C Uart接收正确的字节,但顺序混乱
使用Atmel studio 7,配备STK600和32UC3C MCU 我正在为这件事发愁。 我每5秒通过UART发送一次大小可变的字符串。该字符串由一个字母组成,作为操作码,随后是两个字符,表示以下数据字符串的长度(如果没有零,则这些字符串的末尾永远不会有零)。在大多数情况下,字符串的大小为3个字符,因为它没有数据(“p00”) 经过调查,我发现应该是“p00”的实际上是“0p0”或“00p”或(仅在重新启动micro“p00”后首次尝试)。我在调试器的内存视图中查找它。然后我启动了hTerm,并确认数据实际上是“p00”。因此,过了一会儿,hTerm向我显示“p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p00p001…” 编辑:实际上“0p0”和“00p”是交替的 波特率是9600。过去我只发一封信。所以一切都很顺利 这是接收器中断的代码: 我尝试了不同的代码变体,它们都以不同的方式做相同的事情。但他们都表现出完全相同的行为 lastWebCMDWritePtr是uint8_t*类型,lastWebCMDRingstartPtr也是。 lastWebCMDRingRXLen是一种uint8_t类型C Uart接收正确的字节,但顺序混乱,c,atmel,atmelstudio,C,Atmel,Atmelstudio,使用Atmel studio 7,配备STK600和32UC3C MCU 我正在为这件事发愁。 我每5秒通过UART发送一次大小可变的字符串。该字符串由一个字母组成,作为操作码,随后是两个字符,表示以下数据字符串的长度(如果没有零,则这些字符串的末尾永远不会有零)。在大多数情况下,字符串的大小为3个字符,因为它没有数据(“p00”) 经过调查,我发现应该是“p00”的实际上是“0p0”或“00p”或(仅在重新启动micro“p00”后首次尝试)。我在调试器的内存视图中查找它。然后我启动了hTer
__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的无数调试器错误有关。要获得完整的图片,您必须显示LastWebCMDRWriteptr的位置和方式,lastWebCMDRingRXLen,lastWebCMDRingstartPtr和lastWebCMDRingBufferSIZE用于其他地方(消费端) 此外,我将首先尝试一种更简单的ISR,不依赖于其他软件模块,以排除硬件resp。寄存器处理问题 方法:
#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);
};
#定义USART\u调试
#定义调试大小30
__属性(中断)
void UartISR\u forWebserver()
{
uint8记录字节;
#ifdef USART_调试
静态易失性uint8_t usart_debug_buf[debug_buf_SIZE];//用于调试的循环缓冲区
静态易失性int-usart\u-debug\u-buf\u索引=0;
#恩迪夫
rec_byte=(uint8_t)(&AVR32_USART0)->rhr&0x1ff;
#ifdef USART_调试
usart_debug_buf_index=usart_debug_buf_index%debug_buf_SIZE;
usart_debug_buf[usart_debug_buf_index]=rec_字节;
usart_debug_buf_索引++
if(!(usart\u debug\u buf\u索引
if(lastWebCMDWritePtr-lastWebCMDRingstartPtr>lastWebCMDRingBufferSIZE)
--if(lastWebCMDWritePtr-lastWebCMDRingstartPtr>lastWebCMDRingBufferSIZE-1)谢谢,但我想这不是我要找的bug…)你试过了吗?您的代码访问的循环缓冲区超出了1的界限,因此从基址开始的队列将“移位”一个值。发送的字符串没有终止标识符,无论是空字符还是'\n'
,等等。收件人不知道一个字符串从何处开始,另一个字符串从何处结束。小调:@LPs good idea可以写成如果(lastWebCMDWritePtr-lastWebCMDRingstartPtr>=lastWebCMDRingBufferSIZE)
。我现在发现了,这是一个硬件故障。在用一个新的MCU切换后,它按预期工作。我希望我早点想到那件事。