2024-05-01 11:11 PM
I am using NUCLEO STM32F103RB to learn CAN communication. In CubeMX, PB8 and PB9 were set to CAN_RX and CAN_TX, the baud rate is 500kbps, standard frame, and in Loopback mode. The USB_LP_CAN1_RX0_IQRHandler and CAN1_RX1_IRQHandler were enabled. The CAN filter was set in the MX_CAN_Init():
CAN_FilterTypeDef canfilterconfig;
canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
canfilterconfig.FilterBank = 10;
canfilterconfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canfilterconfig.FilterIdHigh = 0;
canfilterconfig.FilterIdLow = 0x0000;
canfilterconfig.FilterMaskIdHigh = 0;
canfilterconfig.FilterMaskIdLow = 0x0000;
canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
canfilterconfig.SlaveStartFilterBank = 0;
HAL_CAN_ConfigFilter(&hcan, &canfilterconfig);
In the main.c, the data transmission is done as below:
/* start CAN communication */
HAL_CAN_Start(&hcan);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
TxHeader.DLC = 1; // data length is 1
TxHeader.ExtId = 0;
TxHeader.IDE = CAN_ID_STD; //standard frame
TxHeader.RTR = CAN_RTR_DATA; //data frame
TxHeader.StdId = 0x103; // ID = 0x103
TxHeader.TransmitGlobalTime = DISABLE;
TxData[0] = 0x01;
TxData[1] = 0x02;
TxData[2] = 0x03;
TxData[3] = 0x04;
if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, &TxData[0], &TxMailbox) != HAL_OK)
{
Error_Handler();
}
The Callback function is defined in the main.c as below:
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData);
count ++;
}
I thought, since the the Tx data will be loopback to Rx in the Loopback mode, each time after the HAL_CAN_AddTxMessage is called, the HAL_CAN_RxFifo0MsgPendingCallback will be triggered.
However, in my case, the first HAL_CAN_AddTxMessage() will not trigger the callback function. Only when HAL_CAN_AddTxMessage() called twice, the callback function will be triggered, and the received data was those from the first HAL_CAN_AddTxMessage() data. And, the last HAL_CAN_AddTxMessage() will not trigger the callback function either, even after it is the endless while(1) loop.
Not sure what's the cause for this problem. Any suggestion, advice will be appreciated.
2024-05-02 04:38 PM
Your approach is all wrong. You're trying to send 4 can messages back to back without checking if there are Tx mailboxes empty. You should instead buffer your CAN messages if you have multiple messages to send at once. Send each message only if there is an empty mailbox. Look into HAL_CAN_IsTxMessagePending