文章目录
- 功能实现背景介绍
- HAL库的中断接收函数
- 状态机的运用
功能实现背景介绍
本项目中,需要使用STM32的USART6串口与FPGA板(下位机)通信,需要发送和接收数据,有报文应答机制。
使用的报文规则如表格所示
板间报文的通信协议,校验使用的是和校验
U8 TX_CheckSum(U8 *buf, U8 len)
{
U8 i, ret = 0;
for(i=0; i<len; i++)
{
ret += *(buf++);
}
ret = ~ret;
return ret;
}
U8 RX_CheckSum(U8 *buf, U8 len)
{
U8 i, ret = 0;
for(i=0; i<len; i++)
{
ret += *(buf++);
}
ret = ret;
return ret+1;
}
发送和接收的报文要满足不定长
HAL库的中断接收函数
如果要直接使用HAL库的中断接收函数,也就是HAL_UART_Receive_IT()函数
HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);
在使用时,选择串口,选择接收的缓冲区,选择接收长度。
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
__HAL_LOCK(huart);
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
__HAL_UNLOCK(huart);
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
这个函数本质上其实不是中断接收函数,只是配置函数,配置开启中断的信息,并且接收多少定长的数据结束本数据接收,串口的中断接收还是在中断中进行。
我们本次的长度虽然也是定长,但是有两种长度数据的接收,所以还是从设计接收不定长的数据为最终效果。
状态机的运用
对于不定长数据的接收,使用了状态机,分两次中断来接收数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART6)
{
if(StateMachine_USART6)
{
if(re_flag6 == 1)
{
UART6_RxCounter = 6;
re_flag6 = 0;
}
else
{
len_counter6 = 2+5+UART6_RxBuffer[2]+(UART6_RxBuffer[3]<<8);
if(UART6_RxBuffer[len_counter6 - 1] == 0x55 && UART6_RxBuffer[0] == 0xAA)
{
UART6_RxCounter = len_counter6;
}
else
{
memset(UART6_RxBuffer,0,0x400);
UART6_RxCounter = 0;
}
}
StateMachine_USART6 = 0;
len_counter6 = 0;
HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);
}
else
{
if(UART6_RxBuffer[0] == 0xAA)
{
StateMachine_USART6 = 1;
UART6_RxCounter = 5;
if(UART6_RxBuffer[2] == 0 && UART6_RxBuffer[3] == 0)
{
HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 1);
re_flag6 = 1;
}
else
HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 2 + UART6_RxBuffer[2] + (UART6_RxBuffer[3] << 8));
}
else
{
memset(UART6_RxBuffer,0,0x400);
UART6_RxCounter = 0;
HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);
}
}
}
}
核心思想就是先接收报文的头,根据头来判断后面的长度,把应答报文和音量数据报文区分开,不合格的报文直接舍去同时开启新的接收。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)