C/XC8 语法:invert 和AND 运算可以在同一个语句中使用吗?

C/XC8 Syntax: Can invert and AND operation be used in the same statement?

我正在为 PIC 微控制器在 xc8 编译器中编写 C 代码。此代码将使用 CCP 模块控制风扇(电机)on/off 和速度。

为了转动 on/off CCP 模块和风扇,我像这样切换 CCP1CON 位

ccp1conValue = CCP1CON;
ccp1conValue = ~ccp1conValue & 0x0F;
ccp1conValue = CCP1CON;

我担心的是这种语法在 XC8 中是否正确且可接受?我可以在同一语句中使用 invert 和 AND 运算还是需要分别进行?或者有更好的方法来完成吗?

这是有效的 C 语法,任何稍微兼容的编译器都应该优雅地处理它。虽然人们经常在一行 C 代码中推动合理的做法,但我个人会判断您所做的是完全可以接受的。

组合多个操作时要注意的一件事是运算符优先级。

您的声明:

~ccp1conValue & 0x0F

相当于:

(~ccp1conValue) & 0x0F

这可能是您想要做的,但最好记住。

此外,最后一行:

ccp1conValue = CCP1CON;

大概应该是:

CCP1CON = ccp1conValue;

相反。

根据您是否需要保留该值,您可以将这三行替换为:

CCP1CON = ~CCP1CON & 0x0F;

Can I use invert and AND operation in the same statement or I need to do them separately?

您完全可以在同一个表达式中使用按位取反和按位与,如图所示。

但是,由于其他原因,这似乎很可疑:

I am toggling the CCP1CON bits like so

ccp1conValue = CCP1CON;
ccp1conValue = ~ccp1conValue & 0x0F;
ccp1conValue = CCP1CON;
  1. 正如@ThomasJager 已经观察到的那样,您似乎已经反转了最后一个赋值语句的操作数。如所写,对 CCP1CON 没有影响,并且位操作的结果不会保留在任何地方。一个聪明的编译器甚至可以为你诊断这个。如果 ccp1conValueCCP1CON 都不是 volatile 那么我希望编译器完全优化前两个语句。

  2. 假设 (1) 被 flip-flopping 操作数更正,那一系列语句将不仅仅是切换 CCP1CON 中的某些位。它会切换 lowest-order 四位, 并清除所有其他 .

Or is there a better way to do it altogether?

一方面,不清楚您认为临时变量对您有什么好处。即使 CCP1CONvolatile,上面的代码(修正最后一条语句后)也等同于

CCP1CON = ~CCP1CON & 0x0F;

我觉得更清楚了。

此外,如果您的objective只是修改四个least-significant位,或者如果higher-order 位无关紧要,那么我个人会通过按位异或运算符而不是按位取反运算符来执行翻转:

CCP1CON = CCP1CON ^ 0x0F;

这更清楚,至少对我来说是这样,如果您需要避免更改 more-significant 位,那么它会这样做,而您的版本则不会。但是,我强调,这是用与原始代码的更正版本不同的值更新 CCP1CON

如果 more-significant 位实际上无关紧要 那么您也可以只考虑平坦的、未屏蔽的反转:

CCP1CON = ~CCP1CON;

分配的值不同于其他两个备选方案,并且这没有 XOR 版本的优势,可以清楚地表明您真正关心的是哪些位,但如果它做了 (a) 正确的事情,那么它的优点是尽可能简单。