STM8 串口接收 0x00异常

STM8 串口接收 0x00异常,要么跳过,要么重复接收上一个字节
如果第一个字节是0x00 是可以正常收到的 很奇怪
下面是串口助手:

2023:08:16:18:49:29][发送]05 00 00 0A 00 02 E4 8E
[2023:08:16:18:49:29][接收]05 05 0A 0A 02 E4 8E

下面贴上代码:


//IO配置


void IO_Init(void)
{
     
  //所有IO输出低电平
  GPIO_Init(GPIOA, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW);
  GPIO_Init(GPIOB, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW);
  GPIO_Init(GPIOC, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW);
  GPIO_Init(GPIOD, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW);

   GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_FL_IT);

}

//初始化端口
void UART1_485_Init(void)
{
  UART1_Init((u32)bps[baudrate-1], UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
  UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
  UART1_Cmd(ENABLE);
}
//中断接收填充缓冲区

 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
 {
   if(RecIndexLen<20)
   {
     //if(UART1_GetFlagStatus(UART1_FLAG_RXNE)!=RESET) 此处和下面的while同样效果
     {
       ReceiveBuf[RecIndexLen++]=UART1_ReceiveData8();
        while (UART1_GetFlagStatus(UART1_FLAG_RXNE)!=RESET);
     }
   }
   else
   {
     RecIndexLen=0;
   }
}

经过测试发现0x00位于第一字节会发生中断,中间均不发出中断信号,所以造成中间的0x00会丢失

因为485通讯模块在面包板上接地不牢固导致

while换if :
根据你提供的代码,我看到你正在使用STM8单片机和UART1模块进行串口通信。根据你的描述,你遇到了接收到异常的数据的问题,要么跳过一个字节,要么重复接收上一个字节。

在你的代码中,我发现了一个可能导致问题的地方。在UART1_RX_IRQHandler中断处理函数中,你使用了一个while循环等待UART1_FLAG_RXNE标志位被置位。这样做可能会导致嵌套循环,从而导致接收到异常的数据。

为了解决这个问题,你可以尝试将while循环替换为if语句,如下所示:

INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  if (RecIndexLen < 20)
  {
    if (UART1_GetFlagStatus(UART1_FLAG_RXNE) != RESET)
    {
      ReceiveBuf[RecIndexLen++] = UART1_ReceiveData8();
    }
  }
  else
  {
    RecIndexLen = 0;
  }
}

这样,当接收到一个字节时,只会执行一次接收操作,不会陷入循环等待。希望这能解决你遇到的问题。

另外,请确保你正确配置了串口通信的波特率、数据位数、停止位数和校验位数,以确保发送和接收的数据保持一致。如果问题仍然存在,请检查硬件连接和其他相关代码,确保没有其他因素导致异常数据的接收。

如果你还有其他问题,请随时提问!

【以下回答由 GPT 生成】

根据你提供的代码和问题描述,我认为导致串口接收0x00异常的问题可能有以下几个原因:

  1. 中断接收填充缓冲区时,没有正确判断接收数据是否为0x00,导致异常。

下面是我给出的解决方案,你可以尝试按照以下步骤进行修改和调试:

首先,修改中断接收填充缓冲区的代码,增加对接收数据是否为0x00的判断。如果接收到的数据为0x00,则重新等待接收下一个数据。

INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
    uint8_t data = UART1_ReceiveData8();

    if (data == 0x00) {
        // 如果接收到的数据为0x00,重新等待接收下一个数据
        return;
    }

    if (RecIndexLen < 20)
    {
        ReceiveBuf[RecIndexLen++] = data;
    }
    else
    {
        RecIndexLen = 0;
    }
}

其次,你还可以尝试修改串口的初始化设置和配置,以确保串口的正确工作。以下是对串口初始化函数的修改建议:

void UART1_485_Init(void)
{
    UART1_Init((u32)bps[baudrate-1], UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_RX_ENABLE);
    UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
    UART1_Cmd(ENABLE);
}

最后,你需要确保 IO_Init 函数被正确调用以进行端口的初始化配置。

希望这些建议能帮助你解决问题。如果仍然存在问题,请提供更多的代码和相关信息,以便我能够更准确地帮助你定位和解决问题。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^