我发现 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(&hUsbDeviceFS,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(&hUsbDeviceFS,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->Ex
tid;
}
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);
}
关于HAL库的通信组件, 在特定的条件下接受不了数据的情况的解决方案:
在主循环中 加入HAL_XXX_Receive_IT(......);
XXX是 外设。
如果是OS的话,在某一任务,中加入这句话就OK了。
比如操作串口的任务中,加入。 当然这个任务不能长时间阻塞
这是为啥啊? 我在学HAL库,用的生不如死。。。。
经常有莫名其妙的问题,接收不到数据、进不去中断。。。
库呢是个好库,就是资料太少,这不算是BUG,是很完善的一种机制。 我们所遇到的应该都是溢出错误,那么HAL就会给设备一个busy状态。 需要我们去处理下BUSY的这个状态,回调函数中处理
一周热门 更多>