STM3F407串口奇偶校验数据乱码

STM32F407ZET6与串口调试助手,进行串口通信。
现象1 :串口调试助手设置9600,数据7,偶校验,停止位1;单片机配置为9600,数据8,偶校验,停止位1;调试助手接收数据正常,单片机接收数据乱码。
现象2:串口调试助手设置9600,数据8,偶校验,停止位1;单片机配置为9600,数据9,偶校验,停止位1;数据收发正常。
另外无校验时,数据收发正常。

出现这种情况可能是由于数据位、校验位和停止位设置不一致导致的。校验位的设置不一致可能会导致接收到的数据出现乱码。

在现象1中,串口调试助手设置为数据位7,而单片机配置为数据位8,这样会导致接收到的数据位数不匹配,从而导致乱码。

在现象2中,串口调试助手设置为数据位8,而单片机配置为数据位9,这样也会导致接收到的数据位数不匹配,从而导致乱码。

建议将串口调试助手和单片机的数据位、校验位和停止位设置保持一致,以确保数据的正确传输。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/1032071
  • 除此之外, 这篇博客: 构建驱动模块6--STM32 缓冲队列中的      缓冲区常常用于临时保存数据,特别是在通讯过程中,先把数据接收下后,后期等待任务空闲在进行处理,这样避免接收数据中处理数据而造成数据丢失。缓冲队列里经常使用为环形缓冲队列,环形队列是一个头尾相接的队列,一般定义当入队操作为缓冲写操作,而出队则定义为缓冲读。当一个数据或者一组消息来到时,进行入队操作;当需要解析消息时才有出队操作。针对该思想编写一个最简单缓冲队列模块。其代码如下: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 缓冲队列实现代码

    typedef struct
    {
    	
    	MsgCell *msgCell;
    	ht_uint32_t wPos;
    	ht_uint32_t rPos;
    	ht_uint32_t Count;
    }cmMsg_t;
    /**********************************************************************************************************
     *
     *  函数名:cmMsgCreate
     *  功 能: 
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    void* cmMsgCreate(ht_uint32_t wantSize)
    {
    	cmMsg_t *prt=NULL;
      prt=(cmMsg_t *)cmMalloc(sizeof(cmMsg_t)) ;
      prt->msgCell=(MsgCell *)cmMalloc(sizeof(MsgCell)*wantSize) ;
    	prt->rPos=0;
    	prt->wPos=0;
    	prt->Count=wantSize;
    	return (void*)prt;
    	
    }
    /**********************************************************************************************************
     *
     *  函数名:cmMsgWrite
     *  功 能: 
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
     ht_int32_t cmMsgWrite(void * handle,MsgCell msg)
    {
      ht_uint32_t iPos,i;
    	cmMsg_t *prt=(cmMsg_t*)handle;
    	 iPos=(prt->wPos+1)%prt->Count;
    if(( iPos!=prt->rPos)&&(msg.MsgLen<=256))//最大长度不超过256字节
    {
      prt->msgCell[prt->wPos].MsgLen=msg.MsgLen;
      prt->msgCell[prt->wPos].prtMsg=(ht_uint8_t *)cmMalloc(msg.MsgLen) ;
      for(i=0;i<prt->msgCell[prt->wPos].MsgLen;i++)
    	{
    		prt->msgCell[prt->wPos].prtMsg[i]=msg.prtMsg[i];
    	}
       prt->wPos=iPos;
     return 1;
    }
    else
    { 
     return 0;
    }	
    }
    
    /**********************************************************************************************************
     *
     *  函数名:cmMsgRead
     *  功 能: 
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    
    ht_int32_t cmMsgRead(void * handle,MsgCell *msg )
    {
       ht_uint32_t  i;
    	cmMsg_t *prt=(cmMsg_t*)handle;
     
    	if( prt->wPos!=prt->rPos)
    { 
    	  msg->MsgLen=prt->msgCell[prt->rPos].MsgLen;
    	  for(i=0;i<prt->msgCell[prt->rPos].MsgLen;i++)
    	{
    		msg->prtMsg[i]=prt->msgCell[prt->rPos].prtMsg[i];
    		cmFree(prt->msgCell[prt->rPos].prtMsg);
    	}
         prt->rPos=(prt->rPos+1)%prt->Count;
    	return 1;
    }
    return 0;
    	
    }
  • 以下回答由chatgpt基于相关博客总结生成:

    思路和建议

    根据现象1和现象2的描述,可以得出以下结论: 1. 在串口调试助手设置为7位数据位时,单片机的数据位应该设置为7位,否则会导致数据乱码; 2. 在串口调试助手设置为8位数据位时,单片机的数据位应该设置为8位,否则会导致数据乱码; 3. 在串口调试助手设置为9位数据位时,单片机的数据位应该设置为9位,否则会导致数据乱码。

    此外,根据参考资料中的缓冲队列实现代码,我们可以看到在写入数据时,判断了msg.MsgLen的最大长度不超过256字节,可能是由于msg.MsgLen的长度设置不合适,也可能会导致数据乱码。因此,我们还需要检查并修改该参数。

    根据以上情况,我们可以尝试以下步骤解决该问题:

    1. 首先检查和修改单片机串口的配置,确保和串口调试助手的配置相匹配,包括波特率、数据位、校验位和停止位。
    2. 修改缓冲队列实现代码中的msg.MsgLen的最大长度限制,调整为实际应用中可能的数据长度。
    3. 测试以上修改是否能够解决问题。

    以下是可能的解决方案示例代码:

    // 在单片机代码中修改串口配置
    void UART_Configuration(void)
    {
      USART_InitTypeDef USART_InitStructure;
    
      USART_InitStructure.USART_BaudRate = 9600;
      USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 修改为实际应用中对应的数据位
      USART_InitStructure.USART_StopBits = USART_StopBits_1;
      USART_InitStructure.USART_Parity = USART_Parity_Even; // 修改为实际应用中对应的校验位
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    
      USART_Init(USART1, &USART_InitStructure);
      USART_Cmd(USART1, ENABLE);
    }
    
    // 修改缓冲队列实现代码中的msg.MsgLen的最大长度限制
    #define MAX_MSG_LEN 256 // 修改为实际应用中可能的数据长度
    
    typedef struct
    {
      MsgCell *msgCell;
      ht_uint32_t wPos;
      ht_uint32_t rPos;
      ht_uint32_t Count;
    } cmMsg_t;
    
    ht_int32_t cmMsgWrite(void * handle, MsgCell msg)
    {
      ht_uint32_t iPos, i;
      cmMsg_t *prt = (cmMsg_t*)handle;
      iPos = (prt->wPos + 1) % prt->Count;
      if ((iPos != prt->rPos) && (msg.MsgLen <= MAX_MSG_LEN))
      {
        prt->msgCell[prt->wPos].MsgLen = msg.MsgLen;
        prt->msgCell[prt->wPos].prtMsg = (ht_uint8_t *)cmMalloc(msg.MsgLen);
        for (i = 0; i < prt->msgCell[prt->wPos].MsgLen; i++)
        {
          prt->msgCell[prt->wPos].prtMsg[i] = msg.prtMsg[i];
        }
        prt->wPos = iPos;
        return 1;
      }
      else
      {
        return 0;
      }
    }
    

    请注意,以上代码示例仅供参考,实际应用中可能根据具体情况进行修改。

    希望以上解决方案能够帮助您解决问题。如果还有其他问题,请随时提问。