C:警告的解决方法:表达式中的整数溢出?

Ham*_*mza 9 c embedded

我正在尝试组织我的UART库并通过添加一些#define来对它进行一些美化,以便我可以在以后自定义它而不必深入研究代码,但我似乎无法使用下面的代码:

#define FOSC        8000000
#define BAUDRATE    9600
#define BRGVAL      (FOSC/2)/(16*BAUDRATE)-1

void uart_init(){
   U1BRG = BRGVAL;
}
Run Code Online (Sandbox Code Playgroud)

在计算之后BRGVAL变为25.0416667,并且因为它不是整数,所以当我将它分配给U1BRG时,我得到以下警告:

UART.c:在函数'uart_init'中:

UART.c:24:警告:表达式中的整数溢出

...而且代码根本无法在目标硬件上运行.(如果我手动输入U1BRG = 25,它就像魅力一样)

有没有办法将该常量强制转换为整数以使编译器满意?

非常感谢,哈姆扎.

Phi*_*ter 24

整数溢出意味着您已超过int值的上限,如果您收到此错误,则可能为32767.它与浮点无关; 您指定的操作实际上是整数数学运算,因此无论如何都会丢弃除法的小数部分.

尝试这样的事情:

#define FOSC        8000000L
#define BAUDRATE    9600L
#define BRGVAL      ((unsigned int)((FOSC/2)/(16*BAUDRATE)-1))

void uart_init(){
   U1BRG = BRGVAL;
}
Run Code Online (Sandbox Code Playgroud)

L后缀将这些常量转换为long类型而不是int类型.该(unsigned int)投转换成U1BRG的类型,并让编译器知道你明白long价值将适合的unsigned int,从而隐藏其可以在你扔任何警告.

通常情况下,沉默编译器警告是不好的做法,但在这种情况下,很明显,虽然您需要long在计算中存储中间值,但最终结果将适合于unsigned int.


tom*_*gic 8

我喜欢Philip的回答,但我认为更好的解决方案是减少公式并将宏更改为:

#define BRGVAL (FOSC/32/BAUDRATE-1)
Run Code Online (Sandbox Code Playgroud)

这样做可以消除转换,因此如果您选择低波特率导致分区值对于16位int而言太大,编译器可以继续发出警告.