C Uart接收正确的字节,但顺序混乱

C Uart接收正确的字节,但顺序混乱,c,atmel,atmelstudio,C,Atmel,Atmelstudio,使用Atmel studio 7,配备STK600和32UC3C MCU 我正在为这件事发愁。 我每5秒通过UART发送一次大小可变的字符串。该字符串由一个字母组成,作为操作码,随后是两个字符,表示以下数据字符串的长度(如果没有零,则这些字符串的末尾永远不会有零)。在大多数情况下,字符串的大小为3个字符,因为它没有数据(“p00”) 经过调查,我发现应该是“p00”的实际上是“0p0”或“00p”或(仅在重新启动micro“p00”后首次尝试)。我在调试器的内存视图中查找它。然后我启动了hTer

使用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类型

__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的位置和方式,lastWebCMDRingRXLenlastWebCMDRingstartPtrlastWebCMDRingBufferSIZE用于其他地方(消费端)

此外,我将首先尝试一种更简单的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切换后,它按预期工作。我希望我早点想到那件事。