完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我发现 HAL库,使用 那些通讯的组件,经常会发生 数据接收不到的情况,CAN,UART 都这样。
为此 我在主循环中假如了错误检测。一有错误 ,就重新初始化组件: while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /*if(oldIDList!=newIDList) { HAL_CAN_MspDeInit(&hcan1); MX_CAN1_Init(); }*/ if(can_error_flag==1)//can error { HAL_CAN_DeInit(&hcan1); HAL_Delay(1); MX_CAN1_Init(); message[0]=0xFF; USBD_CUSTOM_HID_SendReport(&hU***DeviceFS,message,0x40); //HAL_Delay(50); //while(1); } if(HAL_CAN_GetError(&hcan1)!=HAL_CAN_ERROR_NONE) { HAL_CAN_DeInit(&hcan1); HAL_Delay(1); MX_CAN1_Init(); message[0]=0xCC; USBD_CUSTOM_HID_SendReport(&hU***DeviceFS,message,0x40); } ................ } 是为了调试, CAN组件接收不到数据之后,我用bus Hound 查看了数据, 还是没打印0xff 或者 0xcc 但是程序还没死掉,PC 发给 单片机的数据,单片机通过CAN还是能转发出来的。 void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) { unsigned char B,D; uint32_t id4; unsigned char coun=0; canDebug=1; // CAN_Receive(CAN2,CAN_FIFO0,&RxMessage); /* ¶ÁÈ¡Êý¾Ý */ if(hcan->pRxMsg->IDE==CAN_ID_EXT)//ÊÇ·ñÀ©Õ¹Ö¡ { B=1; id4=hcan->pRxMsg->Extid; } else { B=0; id4=hcan->pRxMsg->StdId; } if(hcan->pRxMsg->RTR==CAN_RTR_DATA) { D=0; } else D=1; id4=(id4<<3)|(B<<2)|(D<<1)|0; union Data *o=(union Data *)&id4; for(coun=0;coun<4;coun++) { sendCANInfo.ID_Data[3-coun]=o->p[coun]; } for(coun=0;coun<8;coun++) { sendCANInfo.ID_Data[4+coun]=hcan->pRxMsg->Data[coun]; } HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);//modefiy to hcan EnQueue(&pq,sendCANInfo); }接收的回调函数 void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { can_error_flag=1; } 错误的回调 单片机接收到PC发的数据之后,会调用一下函数,通过CAN转发出去 void sendCanData(unsigned char *da) { // //uint8_t len=da[2]<<8|da[1]; // Item c; // memcpy(c.ID_Data,(void *)&da[4],12); // EnQueue(&sendCanQueue,c); uint32_t id; uint32_t id_dr_se; uint8_t canDataRemotely,canStdandardExtend; id_dr_se=da[4+3]<<24|da[4+2]<<16|da[4+1]<<8|da[4]; id=id_dr_se>>3; uint32_t last3=(id_dr_se&0x07)>>1; switch(last3) { case 0x00: canDataRemotely=CAN_RTR_DATA; canStdandardExtend=CAN_ID_STD; break; case 0x01: canDataRemotely=CAN_RTR_REMOTE; canStdandardExtend=CAN_ID_STD; break; case 0x02: canDataRemotely=CAN_RTR_DATA; canStdandardExtend=CAN_ID_EXT; break; case 0x03: canDataRemotely=CAN_RTR_REMOTE; canStdandardExtend=CAN_ID_EXT; break; } //hcan1.pTxMsg->Data for(int l=0;l<8;l++) { hcan1.pTxMsg->Data[l]=da[4+4+l]; } hcan1.pTxMsg->DLC=8; if(canStdandardExtend==CAN_ID_STD) { hcan1.pTxMsg->StdId=id; } else { hcan1.pTxMsg->ExtId=id; } hcan1.pTxMsg->RTR=canDataRemotely; hcan1.pTxMsg->IDE=canStdandardExtend; HAL_CAN_Transmit(&hcan1,1); } |
|
相关推荐
8个回答
|
|
加断点后,在线仿真会不会进入这几个判断?
|
|
|
|
关于HAL库的通信组件, 在特定的条件下接受不了数据的情况的解决方案: 在主循环中 加入HAL_XXX_Receive_IT(......); XXX是 外设。 如果是OS的话,在某一任务,中加入这句话就OK了。 比如操作串口的任务中,加入。 当然这个任务不能长时间阻塞 |
|
|
|
cmlzwkd 发表于 2019-2-14 09:25 这是为啥啊? 我在学HAL库,用的生不如死。。。。 经常有莫名其妙的问题,接收不到数据、进不去中断。。。 |
|
|
|
我在串口使用时也发生过不能接收数据的问题,通过仿真发现当前设备处于忙状态,上次数据的溢出等问题可能导致当前设备的忙状态。需要进行初始化后,进入正常。
|
|
|
|
库呢是个好库,就是资料太少,这不算是BUG,是很完善的一种机制。 我们所遇到的应该都是溢出错误,那么HAL就会给设备一个busy状态。 需要我们去处理下BUSY的这个状态,回调函数中处理 |
|
|
|
问题来了,我用最新的F1 V1.40的库,现在的情况是,能进中断,但是只要收到数据就死机了,这会是什么问题?
|
|
|
|
我的也是,能进接收回调,但接收不到数据。
|
|
|
|
cmlzwkd 发表于 2019-2-14 10:04 之前用SPI接收中断,串口接收中断,都遇到了这个问题。当时想用中断接收一帧数据中的每一个字节,结果接收完第一个字节后就溢出错误了。 后来按论坛其他网友给的方法,改成空闲中断了。 感觉串口中断这个函数,不适合我们以前的那种接收思路。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
991 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
970 浏览 2 评论
2080 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1177 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1599 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 08:13 , Processed in 0.649206 second(s), Total 56, Slave 49 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号