3.RTOS队列、邮箱接收比如:void DEBUG_COM_IRQHandler(void){ static uint8_t Data;
if(USART_GetITStatus(DEBUG_COM, USART_IT_RXNE) != RESET) { Data = USART_ReceiveData(DEBUG_COM); CLI_RcvDateFromISR(Data); //下面把这个函数分离出来了 }}
void CLI_RcvDateFromISR(uint8_t RcvData){ static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if(xCLIRcvQueue != NULL) { xQueueSendFromISR(xCLIRcvQueue, &RcvData, &xHigherPriorityTaskWoken); }}中断来一字节数据,就通过消息队列发送一个字节数据,如果没有及时出来这个数据,也是存储在队列中。
通信协议解析像上面第2种,简单通信协议,项目相对较小的情况下,可以直接在中断函数里面处理。
但是,如果项目相对较大、复杂一点,协议也先对复杂一点,上面第2种在函数内部出来方式就不可取。
1.裸机环境裸机的情况下,建议用第一种:中断数组缓存数据(FIFO),应用解析通信协议。
2.RTOS环境RTOS情况下,建议用第三种方式:消息队列、邮箱等方式接收数据,然后发送(通知)应用解析协议。
当然,以上说的都只是常见的方式,具体还需要结合你项目实际情况。
同时,其它类似I2C、CAN等通信,如有协议解析,也是类似。
比如之前给大家分享的MavLink,我就用CAN实现过:void CAN_RX_IRQHandler(void){ static CanRxMsg RxMessage; static MAVRCV_QUEUE_TypeDef MAVRcvQueue_Union;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //拷贝长度、 数据 MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Len = RxMessage.DLC; memcpy(&MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Buf[0], &RxMessage.Data[0], RxMessage.DLC);
MAVLink_RcvDateFromISR(&MAVRcvQueue_Union.MAVLinkRcv_Queue[0]);}
最后,以上内容,仅提供思路,代码不一定适合项目。
|