完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
功能实现背景介绍
本项目中,需要使用STM32的USART6串口与FPGA板(下位机)通信,需要发送和接收数据,有报文应答机制。 使用的报文规则如表格所示 板间报文的通信协议,校验使用的是和校验 U8 TX_CheckSum(U8 *buf, U8 len) //buf为数组,len为数组长度{ U8 i, ret = 0; for(i=0; i HAL库的中断接收函数 如果要直接使用HAL库的中断接收函数,也就是HAL_UART_Receive_IT()函数 HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5); //下位机FPGA1在使用时,选择串口,选择接收的缓冲区,选择接收长度。 /** * @brief Receives an amount of data in non blocking mode. * @note When 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. * @param huart Pointer to a UART_HandleTypeDef structure that contains * the configuration information for the specified UART module. * @param pData Pointer to data buffer (u8 or u16 data elements). * @param Size Amount of data elements (u8 or u16) to be received. * @retval HAL 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)) { return HAL_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); return HAL_OK; } else { return HAL_BUSY; }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950这个函数本质上其实不是中断接收函数,只是配置函数,配置开启中断的信息,并且接收多少定长的数据结束本数据接收,串口的中断接收还是在中断中进行。 我们本次的长度虽然也是定长,但是有两种长度数据的接收,所以还是从设计接收不定长的数据为最终效果。 状态机的运用 对于不定长数据的接收,使用了状态机,分两次中断来接收数据 void HAL_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; //状态机为0 len_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; } 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); } } } } 核心思想就是先接收报文的头,根据头来判断后面的长度,把应答报文和音量数据报文区分开,不合格的报文直接舍去同时开启新的接收。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1537 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1490 浏览 1 评论
910 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
654 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1538 浏览 2 评论
1845浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
597浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
499浏览 3评论
499浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
483浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-5 20:23 , Processed in 0.443930 second(s), Total 43, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号