STM32F407ZET6与串口调试助手,进行串口通信。
现象1 :串口调试助手设置9600,数据7,偶校验,停止位1;单片机配置为9600,数据8,偶校验,停止位1;调试助手接收数据正常,单片机接收数据乱码。
现象2:串口调试助手设置9600,数据8,偶校验,停止位1;单片机配置为9600,数据9,偶校验,停止位1;数据收发正常。
另外无校验时,数据收发正常。
出现这种情况可能是由于数据位、校验位和停止位设置不一致导致的。校验位的设置不一致可能会导致接收到的数据出现乱码。
在现象1中,串口调试助手设置为数据位7,而单片机配置为数据位8,这样会导致接收到的数据位数不匹配,从而导致乱码。
在现象2中,串口调试助手设置为数据位8,而单片机配置为数据位9,这样也会导致接收到的数据位数不匹配,从而导致乱码。
建议将串口调试助手和单片机的数据位、校验位和停止位设置保持一致,以确保数据的正确传输。
缓冲队列实现代码
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;
}
根据现象1和现象2的描述,可以得出以下结论: 1. 在串口调试助手设置为7位数据位时,单片机的数据位应该设置为7位,否则会导致数据乱码; 2. 在串口调试助手设置为8位数据位时,单片机的数据位应该设置为8位,否则会导致数据乱码; 3. 在串口调试助手设置为9位数据位时,单片机的数据位应该设置为9位,否则会导致数据乱码。
此外,根据参考资料中的缓冲队列实现代码,我们可以看到在写入数据时,判断了msg.MsgLen的最大长度不超过256字节,可能是由于msg.MsgLen的长度设置不合适,也可能会导致数据乱码。因此,我们还需要检查并修改该参数。
根据以上情况,我们可以尝试以下步骤解决该问题:
以下是可能的解决方案示例代码:
// 在单片机代码中修改串口配置
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;
}
}
请注意,以上代码示例仅供参考,实际应用中可能根据具体情况进行修改。
希望以上解决方案能够帮助您解决问题。如果还有其他问题,请随时提问。