ATMEGA8535的UART信号为何比ATMEGA328 Arduino慢200倍?
问题描述
尝试让ATMEGA8535的UART功能正常工作,在自定义PCB上失败后,将芯片放在裸面包板上,仅连接GND和5V,TX引脚接示波器监测输出。代码如下:
#define F_CPU 1000000UL //CPU frequency #include <xc.h> #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define BAUD 19200 // baud #define BRC ((F_CPU/16/BAUD) - 1) int main(void) { /* Set baud rate */ UBRRH = (BRC >> 8); UBRRL = BRC; /* Enable receiver and transmitter */ UCSRB = (1<<RXEN)|(1<<TXEN); /* Set frame format: 8data*/ UCSRC = (1<<UCSZ1)|(1<<UCSZ0); while(1){ UDR = 'b'; _delay_ms(2000); } }
示波器显示信号格式正确,但传输速度远慢于预期:整个信号传输耗时远超200ms,而相同波特率设置的ATMEGA328 Arduino传输耗时不到1ms。更换5片ATMEGA8535后问题依旧,查数据手册未发现相关时钟误差因素。
问题根源与解决方法
问题根源:ATMEGA8535的
CKDIV8熔丝位默认处于使能状态,内部1MHz RC振荡器的时钟会被分频8倍,实际运行频率为125kHz,远低于代码中定义的F_CPU=1000000UL。这导致UART波特率计算值与实际运行频率不匹配,实际波特率仅为预期的1/8,传输时间因此延长8倍。解决方法:
- 修改熔丝位:使用编程器禁用
CKDIV8熔丝位,让芯片以1MHz内部RC时钟全速运行,此时代码中的F_CPU定义与实际频率一致,UART波特率会恢复正常。 - 调整代码参数:如果不想修改熔丝位,将代码中的
F_CPU改为125000UL,重新计算波特率寄存器值:#define BRC ((125000/16/BAUD) - 1),这样波特率计算会匹配实际时钟频率。 - 改用外部晶振:为了获得更稳定的时钟,可外接合适的晶振(如16MHz),同时修改熔丝位选择外部时钟源,并将代码中的
F_CPU改为对应晶振频率(如16000000UL),重新计算BRC值。
- 修改熔丝位:使用编程器禁用
内容的提问来源于stack exchange,提问作者M_Kotamech
相关产品推荐
相关产品推荐

