我发现 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);
}
之前用SPI接收中断,串口接收中断,都遇到了这个问题。当时想用中断接收一帧数据中的每一个字节,结果接收完第一个字节后就溢出错误了。
后来按论坛其他网友给的方法,改成空闲中断了。
感觉串口中断这个函数,不适合我们以前的那种接收思路。
一周热门 更多>