ATMEGA32A UART串口发送字符失败求助(波特率9600)
ATmega32A串口发送无输出问题排查与修复
问题概述
使用ATmega32A通过串口发送字符,波特率设为9600,串口终端无输出。已确认接线正确,终端参数设置为8位数据、2停止位。
原代码
.cseg .org 0x00 main: ldi r16,0x80 ldi r17,0x25 call USART_Init loop: ldi r20, 0x86 call USART_Transmit ldi r20, 0xFF call USART_Transmit rjmp loop USART_Init: ; Set baud rate out UBRRH, r17 out UBRRL, r16 ; Enable receiver and transmitter ldi r16, (1<<RXEN)|(1<<TXEN) out UCSRB,r16 ; Set frame format: 8data, 2stop bit ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0) out UCSRC,r16 ret USART_Transmit: ; Wait for empty transmit buffer sbis UCSRA,UDRE rjmp USART_Transmit ; Put data (r16) into buffer, sends the data out UDR,r20 ret
核心问题分析
- 波特率寄存器值错误:
ATmega32A的UBRR值计算公式为:UBRR = (F_CPU / (16 * BAUD)) - 1
假设使用默认16MHz晶振,9600波特率对应的UBRR值为十进制103(十六进制0x67)。原代码中设置的UBRRH=0x25、UBRRL=0x80对应十进制9600,完全不符合波特率计算逻辑,导致波特率不匹配,终端无法识别数据。 - 注释错误(不影响功能但易混淆):
USART_Transmit中的注释标注为"Put data (r16) into buffer",但实际使用的是r20,容易造成代码阅读混淆。
修复后的代码
.cseg .org 0x00 main: ; 16MHz晶振下,9600波特率对应的UBRR值为103(0x67),高8位为0 ldi r16, 0x67 ldi r17, 0x00 call USART_Init loop: ldi r20, 0x86 call USART_Transmit ldi r20, 0xFF call USART_Transmit rjmp loop USART_Init: ; 设置波特率 out UBRRH, r17 out UBRRL, r16 ; 使能接收和发送 ldi r16, (1<<RXEN)|(1<<TXEN) out UCSRB,r16 ; 设置帧格式:8位数据,2停止位 ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0) out UCSRC,r16 ret USART_Transmit: ; 等待发送缓冲区为空 sbis UCSRA,UDRE rjmp USART_Transmit ; 将r20中的数据写入发送缓冲区,启动发送 out UDR,r20 ret
额外说明
- 若使用非16MHz晶振,需重新计算UBRR值:
- 8MHz晶振:UBRR值为51(
0x33),对应r16=0x33,r17=0x00 - 1MHz晶振:UBRR值为5(
0x05),对应r16=0x05,r17=0x00
- 8MHz晶振:UBRR值为51(
- 确保熔丝位设置正确,使用外部晶振时不要误设为内部RC振荡器。
内容的提问来源于stack exchange,提问作者Tashfi Nowroz
相关产品推荐
相关产品推荐

