我正在为PIC微控制器编写xc8编译器的c代码。此代码将使用CCP模块控制风扇(电机)的开/关和速度。
要打开/关闭CCP模块并因此打开风扇,我正在像这样切换CCP1CON位
ccp1conValue = CCP1CON;
ccp1conValue = ~ccp1conValue & 0x0F;
ccp1conValue = CCP1CON;
我担心的是这种语法在 XC8 中是否正确且可以接受?我可以在同一语句中使用反转和 AND 操作还是需要单独执行它们?或者有更好的方法来完全做到这一点?
它是有效的 C 语法,任何稍微兼容的编译器都应该优雅地处理它。虽然人们经常在一行C代码中推动合理的事情,但我个人认为你所做的是完全可以接受的。
每当组合多个操作时,需要注意的一件事是运算符优先级。
您的陈述:
~ccp1conValue & 0x0F
相当于:
(~ccp1conValue) & 0x0F
这可能是您要做的,但最好记住这一点。
另外,最后一行:
ccp1conValue = CCP1CON;
应该是:
CCP1CON = ccp1conValue;
相反。
根据是否需要保留该值,可以将这三行替换为:
CCP1CON = ~CCP1CON & 0x0F;
我可以在同一语句中使用反转和 AND 操作还是需要单独执行?
您绝对可以在同一表达式中使用按位否定和按位 AND,如图所示。
但是,由于其他原因,这似乎很可疑:
我像这样切换CCP1CON位
ccp1conValue = CCP1CON; ccp1conValue = ~ccp1conValue & 0x0F; ccp1conValue = CCP1CON;
-
正如@ThomasJager已经观察到的那样,您似乎已经反转了最后一个赋值语句的操作数。 如前所述,对
CCP1CON
没有影响,并且按位操作的结果不会保留在任何地方。 一个聪明的编译器甚至可能会为你诊断这一点。 如果ccp1conValue
和CCP1CON
都没有volatile
那么我希望编译器完全优化前两个语句。 -
假设 (1) 通过翻转操作数进行更正,那么这一系列语句将不仅仅是在
CCP1CON
中切换一些位。 它将切换最低顺序的四位,并清除所有其他位。
或者有更好的方法来完全做到这一点?
首先,不清楚你认为临时变量对你有什么好处。 即使CCP1CON
是volatile
,上面的代码(在修正最后一个语句之后)等价于
CCP1CON = ~CCP1CON & 0x0F;
我觉得这更清楚了。
此外,如果您的目标是仅修改四个最低有效位,或者如果高阶位无关紧要,那么我将亲自通过按位独占 OR 运算符而不是按位否定运算符执行翻转:
CCP1CON = CCP1CON ^ 0x0F;
至少对我来说,这更清楚,如果您需要避免更改更重要的部分,那么它会这样做,而您的版本不会。 但是,我强调的是,这是使用与原始代码的更正版本不同的值更新CCP1CON
。
如果更重要的位实际上无关紧要,那么您也可以考虑一个平坦的、未屏蔽的反转:
CCP1CON = ~CCP1CON;
分配的值与其他两种选择不同,这没有 XOR 版本的优点,即明确您真正关心哪些位,但如果它做了 (a) 正确的事情,那么它的优点是尽可能简单。