功能实现背景介绍
本项目中,需要使用STM32的USART6串口与FPGA板(下位机)通信,需要发送和接收数据,有报文应答机制。
使用的报文规则如表格所示
板间报文的通信协议,校验使用的是和校验
U8 TX_CheckSum(U8 *buf, U8 len)//buf为数组,len为数组长度{ U8 i,ret= 0;for(i=0; i< len; i++) {ret+= *(buf++); }ret= ~ret;returnret; } U8 RX_CheckSum(U8 *buf, U8 len)//buf为数组,len为数组长度{ U8 i,ret= 0;for(i=0; i< len; i++) {ret+= *(buf++); }ret=ret;returnret+1; }
发送和接收的报文要满足不定长
HAL库的中断接收函数
如果要直接使用HAL库的中断接收函数,也就是HAL_UART_Receive_IT()函数
HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5); //下位机FPGA
在使用时,选择串口,选择接收的缓冲区,选择接收长度。
/** *@briefReceives an amount of data in non blocking mode. *@noteWhen UART parity is not enabled(PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), * the received data is handled as a set of u16. In this case, Size must indicate the number * of u16 available through pData. *@paramhuart Pointer to a UART_HandleTypeDef structure that contains * the configuration information for the specified UART module. *@parampData Pointer to data buffer (u8 or u16 data elements). *@paramSize Amount of data elements (u8 or u16) to be received. *@retvalHAL status */HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) {/* Check that a Rx process is not already ongoing */if(huart- >RxState == HAL_UART_STATE_READY) {if((pData == NULL) || (Size == 0U)) {returnHAL_ERROR; }/* Process Locked */__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;/* Process Unlocked */__HAL_UNLOCK(huart);/* Enable the UART Parity Error Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_PE);/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);/* Enable the UART Data Register not empty Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);returnHAL_OK; }else{returnHAL_BUSY; } }
这个函数本质上其实不是中断接收函数,只是配置函数,配置开启中断的信息,并且接收多少定长的数据结束本数据接收,串口的中断接收还是在中断中进行。
我们本次的长度虽然也是定长,但是有两种长度数据的接收,所以还是从设计接收不定长的数据为最终效果。
状态机的运用
对于不定长数据的接收,使用了状态机,分两次中断来接收数据
voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart- >Instance == USART6)// 判断是由哪个串口触发的中断{if(StateMachine_USART6)//状态机为1,都接收完毕,准备校验{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;//状态机为0len_counter6 =0;HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5); }else//状态机为0,只接受到了前五个字节,继续接收后面的字节{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; }elseHAL_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); } } } }
核心思想就是先接收报文的头,根据头来判断后面的长度,把应答报文和音量数据报文区分开,不合格的报文直接舍去同时开启新的接收。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
- FPGA
+关注
关注
1620文章
21474浏览量
598081 - STM32
+关注
关注
2254文章
10781浏览量
351730 - 下位机
+关注
关注
0文章
93浏览量
18673 - 串口中断
+关注
关注
0文章
64浏览量
13777 - USART串口
+关注
关注
0文章
32浏览量
6772
发布评论请先登录
相关推荐
STM32之串口DMA接收不定长数据
使用
stm32或者其他单片机的时候,会经常使用到
串口通讯,那么如何有效地
接收数据呢?假如这段数据是
不定长的有如何高效
接收呢?同学A:数据来了
发表于12-24 19:03
•
30次下载

评论