CUBEMX HAL库的问题。
我发现 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=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=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->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=o->p;
}
for(coun=0;coun<8;coun++)
{
sendCANInfo.ID_Data=hcan->pRxMsg->Data;
}
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<<8|da;
// Item c;
// memcpy(c.ID_Data,(void *)&da,12);
// EnQueue(&sendCanQueue,c);
uint32_t id;
uint32_t id_dr_se;
uint8_t canDataRemotely,canStdandardExtend;
id_dr_se=da<<24|da<<16|da<<8|da;
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=da;
}
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);
}
加断点后,在线仿真会不会进入这几个判断? 安 发表于 2016-1-5 11:20
加断点后,在线仿真会不会进入这几个判断?
关于HAL库的通信组件, 在特定的条件下接受不了数据的情况的解决方案:
在主循环中 加入HAL_XXX_Receive_IT(......);
XXX是 外设。
如果是OS的话,在某一任务,中加入这句话就OK了。
比如操作串口的任务中,加入。 当然这个任务不能长时间阻塞 david2016 发表于 2016-1-5 15:08
关于HAL库的通信组件, 在特定的条件下接受不了数据的情况的解决方案:
在主循环中 加入HAL_XXX_Receive_ ...
这是为啥啊?我在学HAL库,用的生不如死。。。。
经常有莫名其妙的问题,接收不到数据、进不去中断。。。 我在串口使用时也发生过不能接收数据的问题,通过仿真发现当前设备处于忙状态,上次数据的溢出等问题可能导致当前设备的忙状态。需要进行初始化后,进入正常。 tangxhhh 发表于 2016-1-5 23:30
这是为啥啊?我在学HAL库,用的生不如死。。。。
经常有莫名其妙的问题,接收不到数据、进不去中断。 ...
库呢是个好库,就是资料太少,这不算是BUG,是很完善的一种机制。 我们所遇到的应该都是溢出错误,那么HAL就会给设备一个busy状态。 需要我们去处理下BUSY的这个状态,回调函数中处理 问题来了,我用最新的F1 V1.40的库,现在的情况是,能进中断,但是只要收到数据就死机了,这会是什么问题? 我的也是,能进接收回调,但接收不到数据。 david2016 发表于 2016-1-7 10:22
库呢是个好库,就是资料太少,这不算是BUG,是很完善的一种机制。 我们所遇到的应该都是溢出错误,那么HA ...
之前用SPI接收中断,串口接收中断,都遇到了这个问题。当时想用中断接收一帧数据中的每一个字节,结果接收完第一个字节后就溢出错误了。
后来按论坛其他网友给的方法,改成空闲中断了。
感觉串口中断这个函数,不适合我们以前的那种接收思路。
页:
[1]