ATmega4809通过USART1发送多字符时输出0xFF的问题解决
ATmega4809 USART发送字符串异常(首字符正常其余为0xFF)的解决办法
问题描述
在ATmega4809上使用USART1发送字符时,单个字符发送正常,但发送字符串时,除第一个字符外其余均输出0xFF,预期输出为aHello world!b,实际输出异常。
排查过程
尝试以下操作均未解决问题:
- 更换不同波特率
- 使用Microchip工具链、手动编译的GCC等不同编译器
- 发送每个字符后添加延迟
- 调整字符串定义方式(数组、指针)、发送逻辑(循环、逐个发送)
- 切换至USART2
- 调整时钟频率、编译器优化等级
仅当手动初始化字符数组时,发送结果正常,说明问题与字符串存储相关。
解决方案
问题与USART无关,根源是复用的旧Makefile(原用于ATmega328p和ATmega2560)在转换ELF到HEX文件时,未包含.rodata段。旧款ATmega芯片不需要该段,但ATmega4809必须包含,添加后问题解决。
修改前的Makefile片段
$(OUT).hex: $(OUT).elf rm -f $(OUT).hex $(OUT).eep.hex $(OBJCOPY) -j .text -j .data -O ihex $(OUT).elf $(OUT).hex $(SIZE) $(OUT).hex
修改后的Makefile片段
$(OUT).hex: $(OUT).elf rm -f $(OUT).hex $(OUT).eep.hex $(OBJCOPY) -j .text -j .data -j .rodata -O ihex $(OUT).elf $(OUT).hex $(SIZE) $(OUT).hex
测试代码
用户使用的测试代码如下:
#include <avr/io.h> #define BAUDRATE 115200 #define BAUD_REG (F_CPU * 64UL) / (16UL * BAUDRATE) void usart_init(USART_t * usart) { // Sets up usart usart->BAUD = BAUD_REG; usart->CTRLB = (1 << USART_TXEN_bp) | (1 << USART_RXEN_bp); } void usart_write(USART_t * usart, char c) { // Wait TX ready while (!(usart->STATUS & USART_DREIF_bm)) {;;} // Send character usart->TXDATAL = c; } int main(void) { // Setup 16 MHz clock internal clock CCP = 0xD8; CLKCTRL_MCLKCTRLB = 0; // Setup uart1 // Set alternate pin mux for uart1 to PC4 and PC5 PORTMUX.USARTROUTEA |= PORTMUX_USART1_0_bm; // Set TX pin output VPORTC.DIR |= PIN4_bm; // Setup USART1 usart_init(&USART1); // String to send char st[] = "Hello world!"; // Pointer to iterate of characters char * st_ptr = st; // Send char -> works fine usart_write(&USART1, 'a'); // Send string -> sends garbage while (*st_ptr) { usart_write(&USART1, *st_ptr++); } // Send another char -> works fine usart_write(&USART1, 'b'); while (1) {;;} }
内容的提问来源于stack exchange,提问作者Paulusbrand
相关产品推荐
相关产品推荐

