ATmega328P UART汇编代码问题:无法接收回传数组数据
UART接收回传无数据问题排查(汇编)
常见问题点及排查步骤
1. UART初始化是否正确
- 确认波特率配置:检查
UBRR寄存器值是否匹配目标波特率(比如9600波特率、16MHz时钟下,UBRR值为103) - 确认收发使能:是否设置了
UCSRB寄存器的RXEN和TXEN位(比如ldi r16, (1<<RXEN)|(1<<TXEN)后写入UCSRB) - 帧格式匹配:数据位、停止位、奇偶校验是否和终端一致(比如8位数据、1停止位,需设置
UCSRC的UCSZ1和UCSZ0位)
2. 接收逻辑问题
- 等待接收完成的判断:是否正确检测
UCSRA的RXC位(需循环等待直到该位为1,比如loop: sbis UCSRA, RXC; rjmp loop) - 数据读取时机:是否在
RXC置位后才读取UDR寄存器,未读取的话RXC不会清零,后续接收会异常 - 数组存储逻辑:检查数组地址是否正确,存储时是否使用了正确的指针操作(比如用X/Y/Z寄存器作为指针,每次存储后指针自增)
3. 回传发送逻辑问题
- 等待发送缓冲区空:发送前必须等待
UCSRA的UDRE位为1,否则数据无法写入UDR(比如send_loop: sbis UCSRA, UDRE; rjmp send_loop) - 数组遍历是否完整:是否循环发送了数组的所有元素,检查循环计数器是否正确(比如初始值为数组长度,每次发送后递减直到为0)
- 发送后是否等待发送完成:如果需要确保数据全部发送,可等待
UCSRA的TXC位,不过一般发送缓冲区空即可继续发下一个字节
4. 变量/数组存储验证
- 可在存储数据后,直接读取数组元素并发送(跳过完整存储后再发送的步骤),验证单字节接收发送是否正常
- 若支持仿真,查看内存中数组地址的内容是否与接收的字节一致
- 可添加LED闪烁等硬件反馈,确认接收逻辑是否执行到存储步骤
示例修正代码片段
假设AVR汇编环境,以下是基础的接收数组并回传的示例:
; 初始化UART init_uart: ldi r16, 103 ; 9600波特率@16MHz sts UBRR0H, r16 ldi r16, 0 sts UBRR0L, r16 ldi r16, (1<<RXEN0)|(1<<TXEN0) sts UCSR0B, r16 ldi r16, (1<<UCSZ01)|(1<<UCSZ00) ; 8位数据 sts UCSR0C, r16 ret ; 接收字节到r16 uart_receive: lds r17, UCSR0A sbrs r17, RXC0 rjmp uart_receive lds r16, UDR0 ret ; 发送r16中的字节 uart_send: lds r17, UCSR0A sbrs r17, UDRE0 rjmp uart_send sts UDR0, r16 ret ; 主逻辑:接收5字节数组并回传 main: call init_uart ldi XL, low(buffer) ldi XH, high(buffer) ldi r17, 5 ; 数组长度 receive_loop: call uart_receive st X+, r16 dec r17 brne receive_loop ; 回传数组 ldi XL, low(buffer) ldi XH, high(buffer) ldi r17, 5 send_loop: ld r16, X+ call uart_send dec r17 brne send_loop rjmp main .dseg buffer: .byte 5 ; 定义5字节数组
注意:不同MCU的UART寄存器名称可能不同(比如AVR的UCSR0A vs UCSRA),需根据实际芯片调整。
内容的提问来源于stack exchange,提问作者Hiro
相关产品推荐
相关产品推荐

