Uart 接收到正确的字节,但顺序混乱
Posted
技术标签:
【中文标题】Uart 接收到正确的字节,但顺序混乱【英文标题】:Uart receives correct Bytes but in chaotic order 【发布时间】:2017-03-23 12:59:18 【问题描述】:使用 Atmel studio 7,搭配 STK600 和 32UC3C MCU
我正在为此烦恼。 我每 5 秒通过 UART 发送一次可变大小的字符串。该字符串由一个作为操作码的字母组成,然后是两个字符,它们告诉后面的数据字符串的长度(没有零,任何这些字符串的末尾都不会有零)。在大多数情况下,字符串大小为 3 个字符,因为它没有数据(“p00”)。
经过调查,我发现应该是“p00”实际上是“0p0”或“00p”或(仅在重新启动微型“p00”后第一次尝试)。我在调试器的内存视图中查找了它。然后我启动 hTerm 并确认数据实际上是“p00”。所以过了一会儿,hTerm 向我显示“p00p00p00p00p00p00p00...”,而我的循环 uart 缓冲区的内存显示为“p000p000p0p000p0p000p0p0...”
编辑:实际上“0p0”和“00p”是交替的。
波特率为 9600。过去我只发送单个字母。所以一切都运行良好。
这是接收器中断的代码: 我尝试了不同的代码变体,它们都以不同的方式做同样的事情。但他们都表现出完全相同的行为。
lastWebCMDWritePtr 是 uint8_t* 类型,lastWebCMDRingstartPtr 也是。 lastWebCMDRingRXLen 是一个 uint8_t 类型。
__attribute__((__interrupt__))
void UartISR_forWebserver()
*(lastWebCMDWritePtr++) = (uint8_t)((&AVR32_USART0)->rhr & 0x1ff);
lastWebCMDRingRXLen++;
if(lastWebCMDWritePtr - lastWebCMDRingstartPtr > lastWebCMDRingBufferSIZE)
lastWebCMDWritePtr = lastWebCMDRingstartPtr;
// Variation 2:
// advanceFifo((uint8_t)((&AVR32_USART0)->rhr & 0x1ff));
// Variation 3:
// if(usart_read_char(&AVR32_USART0, getReadPointer()) == USART_RX_ERROR)
//
// usart_reset_status(&AVR32_USART0);
//
//
;
我欢迎您的任何想法和建议。
向某某致敬
附:我放了 Atmel studio 标签,以防这与 AS 的无数调试器错误有关。
【问题讨论】:
if(lastWebCMDWritePtr - lastWebCMDRingstartPtr > lastWebCMDRingBufferSIZE)
----> if(lastWebCMDWritePtr - lastWebCMDRingstartPtr > lastWebCMDRingBufferSIZE-1)
谢谢,但我猜这不是我要寻找的错误... ;)
嗯,你试过了吗?您的代码访问循环缓冲区超出了 1 的范围,因此从基地址开始的队列将被“移动”一个值。
发送的 strings 没有终止标识符,可以是空字符或'\n'
等。接收者不知道其中一个 string开始,另一个 string 结束。
Minor:@LPs的好主意可以写成if(lastWebCMDWritePtr - lastWebCMDRingstartPtr >= lastWebCMDRingBufferSIZE)
。
【参考方案1】:
要获得完整的图片,您必须显示 lastWebCMDWritePtr、lastWebCMDRingRXLen、lastWebCMDRingstartPtr 和 lastWebCMDRingBufferSIZE 的位置和方式在其他地方使用(在消费端)
另外我会首先尝试一个更简单的 ISR,它不依赖于其他软件模块来排除硬件响应。注册处理问题。
方法:
#define USART_DEBUG
#define DEBUG_BUF_SIZE 30
__attribute__((__interrupt__))
void UartISR_forWebserver()
uint8_t rec_byte;
#ifdef USART_DEBUG
static volatile uint8_t usart_debug_buf[DEBUG_BUF_SIZE]; //circular buffer for debugging
static volatile int usart_debug_buf_index = 0;
#endif
rec_byte = (uint8_t)((&AVR32_USART0)->rhr & 0x1ff);
#ifdef USART_DEBUG
usart_debug_buf_index = usart_debug_buf_index % DEBUG_BUF_SIZE;
usart_debug_buf[usart_debug_buf_index] = rec_byte;
usart_debug_buf_index++
if (!(usart_debug_buf_index < DEBUG_BUF_SIZE))
usart_debug_buf_index = 0; //candidate for a breakpoint to see what happened in the past
#endif
//uart_recfifo_enqueue(rec_byte);
;
【讨论】:
我现在才发现,是硬件故障。用新的 MCU 切换后,它按预期工作。我希望我早点想到这一点。以上是关于Uart 接收到正确的字节,但顺序混乱的主要内容,如果未能解决你的问题,请参考以下文章