预处理器:在令牌之前缺少二元运算符

我正在尝试在XMEGA微控制器中设置USART模块,并偶然发现我找不到的错误。 为清楚起见,我给你完整的代码。 因此,此头文件中没有任何内容丢失。 ( F_CPU在主文件中定义)

 #ifndef USART_H_ #define USART_H_ #include  #define USART_BAUDRATE 4800 #define USART_BSCALE -3 #if USART_BSCALE < 0 #define USART_BSEL F_CPU / (pow(2,USART_BSCALE) * 16 * USART_BAUDRATE) - 1 #define USART_BAUD_REAL F_CPU / (pow(2,USART_BSCALE) * 16 * (USART_BSEL + 1)) #else #define USART_BSEL (1 / (pow(2,USART_BSCALE))) * (F_CPU / (16 * USART_BAUDRATE) - 1) #define USART_BAUD_REAL F_CPU / (16 * ((pow(2,USART_BSCALE) * USART_BSEL) + 1)) #endif #define USART_BAUD_ERROR USART_BAUD_REAL * 1000 / USART_BAUDRATE #if USART_BAUD_ERROR1010 /* <-- ERROR IS IN THIS LINE! */ #error Baud rate error too high! #endif #endif /* USART_H_ */ 

编译器以错误结束

 令牌之前缺少二元运算符“(” 

在标记的行。 之前有过括号,但我删除了它们,尝试了不同的括号组合,但编译器仍然在那里看到它们。 这有什么不对?

#if预处理器指令在预处理阶段进行评估。 functionpow在运行时评估。 因此,您无法在传递给#if预处理器令牌(宏)中使用它。 您需要在编译时计算所有这些值。

提示:“2次n”与1 << n (按位左移)相同。

此外,还有一些其他严重问题:

  • 您已标记此AVR,因此您可能不应使用浮点数。 它们不仅会让你的程序变得非常慢,而且还可以用于各种bug的可能性,使用它们没有任何好处。

    如果幸运的话,您会收到“缺少浮点库”或类似信息的警告。 如果你运气不好,该程序将链接并吹走你的所有执行速度和内存。

    在考虑使用浮点之前,检查目标系统是否甚至具有FPU可能是明智的。

  • 您需要正确编写宏,并在宏表达式周围加上括号。 就像您正确编写的第二个USART_BSEL一样。 否则,如果在表达式中使用宏,则可能会出现与运算符优先级相关的非常微妙且非常严重的错误。 每一篇不错的C书都在预处理器章节中解决了这个问题。

如果希望预处理器计算表达式,则必须保持不变。 pow()是一个运行时函数,它在编译时不能由预处理器进行评估。

在宏体周围使用括号,否则会遇到问题。

观察数字常量的类型。 根据类型评估操作。 1/ANY_NUMBER给出0 ,因为除法是在signed int中执行的。

 #define USART_BAUDRATE 4800U #define USART_BSCALE (-3) #if USART_BSCALE < 0 #define USART_BSEL (F_CPU*(1UL<<(-USART_BSCALE)) / (16U*USART_BAUDRATE) - 1U) #define USART_BAUD_REAL (F_CPU*(1UL<<(-USART_BSCALE)) / (16U*(USART_BSEL+1U)) ) #else #define USART_BSEL (F_CPU / ((1UL< 

建议:通过舍入技巧,您可以获得更好的分区准确度:

 #define USART_BSEL_DIVISOR ((1UL<