如何解决PIC 嵌入式 C printf 损坏的输出 - 很奇怪
我有一个 69 元素数组 MBRespon[i]
的十六进制数据,我从 PIC18F46K40 上的两个 USART 发送出去。第一个 USART 循环遍历数据并正常传输所有内容,完成后,代码通过第二个循环,在第二个 UART 中使用以下命令打印格式化数据:
printf(" Byte %02i : 0x%02x \r\n",i,MBRespon[i]);
起初看起来数据打印得很好,但是在第 57 个字节附近仔细检查后,它发送了错误的内容。起初我认为这可能是 EUSART2_TX_BUFFER_SIZE 问题,确实改变缓冲区大小确实有影响;当与 32 不同时,more 会损坏。
#define EUSART2_TX_BUFFER_SIZE 32 // 32 Works (Sort of)
#define EUSART2_RX_BUFFER_SIZE 32 // 32 Works (Sort of)
如果我将数组中的元素数量减少到 58 个或更少,那就没问题了,再多就会损坏。
我的代码:
void PrintModRespon(){
int i=0;
printf("Modbus Response Count %i:\r\n",MBResCnt);
while(!EUSART2_is_tx_ready()); // Hold the program until TX is ready
for(i=0; i< MBResCnt ; i++ ){
while(!EUSART2_is_tx_ready()); // Hold the program until TX is ready
printf(" Byte %02i : 0x%02x \r\n",MBRespon[i]);
while(!EUSART2_is_tx_done()); // Hold until done.
}
while(!EUSART2_is_tx_ready()); // Hold the program until TX is ready
printf("\r\n\n");
while(!EUSART2_is_tx_done());
}
我添加了 while(!EUSART2_is_tx_ready());
和 while(!EUSART2_is_tx_done());
,因为我认为这可能是 UART 没有准备好/忙碌,但它们没有任何区别。
UART1 输出(好的):
06 03 40 00 01 00 02 00 03 ....etc.... 00 1a 00 1b 00 1c 00 1d 00 1e 00 1f 00 20 5c 30
UART2 输出(坏的):
Modbus Response Count 69:
Byte 00 : 0x06
Byte 01 : 0x03
Byte 02 : 0x40
Byte 03 : 0x00
Byte 04 : 0x01
Byte 05 : 0x00
Byte 06 : 0x02
Byte 07 : 0x00
Byte 08 : 0x03
...等等...
Byte 53 : 0x00
Byte 54 : 0x1a
Byte 55 : 0x00
Byte 56 : 0x1b
Byte 57 : 0x14 // <-- This is NOT in the array!
Byte 58 : 0x1c
Byte 59 : 0x00
Byte 60 : 0x1d
Byte 61 : 0x00
Byte 62 : 0x1e
Byte 63 : 0x00
Byte 64 : 0x1f
Byte 65 : 0x00
Byte 66 : 0x20
Byte 67 : 0x5c
Byte 68 : 0x30
printf(" Byte %02i : 0x%02x \r\n",0x00 +i);
I.E 不使用数据数组,它输出 69x 增量值很好!这表明这不是 UART 缓冲区/时序问题?
Modbus Response Count 69:
Byte 00 : 0x00
Byte 01 : 0x01
Byte 02 : 0x02
...etc.
Byte 51 : 0x33
Byte 52 : 0x34
Byte 53 : 0x35
Byte 54 : 0x36
Byte 55 : 0x37
Byte 56 : 0x38
Byte 57 : 0x39
Byte 58 : 0x3a
Byte 59 : 0x3b
Byte 60 : 0x3c
Byte 61 : 0x3d
Byte 62 : 0x3e
Byte 63 : 0x3f
Byte 64 : 0x40
Byte 65 : 0x41
Byte 66 : 0x42
Byte 67 : 0x43
Byte 68 : 0x44
非常感谢任何建议。我已经坚持了好几天了!
解决方法
这很可能是填充问题,因为结构的第一个元素有奇数个字节。
在定义结构时,如果元素不符合处理器的默认对齐方式,编译器将在元素之间创建一字节的填充。 16 位处理器将希望大多数事物在字边界(即甚至地址)上对齐,包括字节数组(例如字符数组)。只占一个字节的元素除外。
在 16 位 Microchip MPU 上,如果您尝试访问奇地址上的字或双字数据,则会导致内存故障。编译器正在努力防止这种情况发生。
如果您的结构仅包含字节大小的元素(char、uint8_t 等)或相同的数组,您可以通过在结构声明中添加限定符 __attribute__((packed))
来强制字节对齐。这可能很危险,因为您最终可能会得到具有奇数地址的元素。只要奇数寻址元素仅作为字节访问(例如字符数组),这是可以的,但请谨慎操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。