xl1736 发表于 2013-12-21 22:10:43

简单的波特率计算公式,两种写法,两种答案!

芯片ATMEGA168
下面是一个很简单的串口初始化程序。其中a = fosc/16/baud-1;串口能正常使用。换做 (fosc/(16*baud))-1;串口就会挂掉,现在原因找到了:编译器警告 warning: integer overflow in expression本着认真学习的精神,小弟想问对于8位机来说20M的数字会使用于保存临时变量的RAM溢出么?
void Usart_Init(unsigned int baud)
{
        unsigned int a;
        DDRD |=0x02;
        UCSR0C = 0x06;        //异步,无校验,零停止位,八字符
        a = (fosc/(16*baud))-1;//fosc/16/baud-1;
        UBRR0L = a % 256;
        UBRR0H = a / 256;
        UCSR0B = 0x98;
        // sei();
}

alias 发表于 2013-12-21 23:26:21

把 a 定义为 unsigned long int 看看,unsigned int 是 16 位元。

cmheia 发表于 2013-12-21 23:41:58

fosc是不是用宏定义的常量……你的unsigned int有多宽……这些要考虑

xl1736 发表于 2013-12-22 14:34:09

cmheia 发表于 2013-12-21 23:41
fosc是不是用宏定义的常量……你的unsigned int有多宽……这些要考虑

fosc是一个宏定义量,时钟频率。

xl1736 发表于 2013-12-22 14:36:28

alias 发表于 2013-12-21 23:26
把 a 定义为 unsigned long int 看看,unsigned int 是 16 位元。

我感觉也许不是a的问题,最终式子计算出来的东西仅仅100多,用一个unsigned char保存也行。所以我认为问题出现在我们看不见的编译器处理的那个环节,不然改成a = fosc/16/baud-1也不会成功,你说是么?朋友。{:smile:}

takashiki 发表于 2013-12-22 15:06:17

xl1736 发表于 2013-12-22 14:36
我感觉也许不是a的问题,最终式子计算出来的东西仅仅100多,用一个unsigned char保存也行。所以我认为问 ...

呵呵,主要是你的baud*16已经溢出了,所以需要改成16ul或者将baud改成unsigned long类型。

个人建议你将baud改成unsigned long类型,为什么呢?因为你的unsigned int类型在波特率>65535(比如76800、115200)时根本无法正常工作。

xl1736 发表于 2013-12-22 15:15:15

takashiki 发表于 2013-12-22 15:06
呵呵,主要是你的baud*16已经溢出了,所以需要改成16ul或者将baud改成unsigned long类型。

个人建议你将 ...

现在只考虑了再低速模式下,所以baud一直没有超过65535。只是我觉得惊讶的是用来保存16*baud的栈也会溢出。那计算时20M的数字是以什么形式保存的。

takashiki 发表于 2013-12-22 15:20:55

xl1736 发表于 2013-12-22 15:15
现在只考虑了再低速模式下,所以baud一直没有超过65535。只是我觉得惊讶的是用来保存16*baud的栈也会溢出 ...

20M默认使用long类型存储

xl1736 发表于 2013-12-22 15:24:56

takashiki 发表于 2013-12-22 15:20
20M默认使用long类型存储

恩,我知道什么意思了。
由于我波特率参数定义为Uint,所以编译器为这个算式分配的空间也是16位的,这样就照成了溢出。
小弟明白了,谢谢{:smile:}
页: [1]
查看完整版本: 简单的波特率计算公式,两种写法,两种答案!