2016-12-11 09:30 PM
2016-12-11 11:55 PM
I think your interrupt is overrun. CAN does not have much hardware FIFO. You really need to only fetch the data from the CAN memory. If you want to put it on display, you might want to have a software fifo, or a lower message burst. (eg: a burst of 5 consecutive messages will overrun the 3 deep fifo on an F1.
void CAN1_RX0_IRQHandler(void)
{/* USER CODE BEGIN CAN1_RX0_IRQn 0 */HAL_CAN_IRQHandler(&hcan1);sprintf(data, '%d', hcan1.pRxMsg->Data[0]);Byte_num=hcan1.pRxMsg->Data[0];ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table);HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);/* USER CODE BEGIN CAN1_RX0_IRQn 1 *//* USER CODE END CAN1_RX0_IRQn 1 */}Try reading the FIFO Overrun bits, see what those say.
For comparison, on 125 Kbit, you can fill the buffers in just 1.1 milliseconds. (3 STD RTR frames)
2016-12-12 02:41 PM
Many thanks Jeroen3. I have just removed everything from the can receiving handler and included the following in my main (following an youtube tutorial) and everything is now working like a charm. I have also removed the writing to the LCD to the main while loop and in the
HAL_CAN_RxCpltCallback only reading the received data.
However, not sure what was the problem with my first approach and why it is working now what was the problem??. I always thought that I need tread data from CAN as soon as my program senses an IRQ handler interrupt!.
One more question on a seperate matter. I'd like to start using FreeRTOS semaphores with interrupts and whenever I receive a message give a signal to one of the threads to do something for example read a certain ADC pin and display it on screen then sleep until a new message arrives. My question is, is this the right way to do stuff or any other suggestions?
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{ if ((CanHandle->pRxMsg->StdId == 0x321)&&(CanHandle->pRxMsg->IDE == CAN_ID_STD) && (CanHandle->pRxMsg->DLC == 1)) {// HAL_CAN_IRQHandler(&hcan1);// hcan1->pRxMsg->Data[0];// sprintf(data, '%d', hcan1->pRxMsg->Data[0]);// Byte_num=hcan1->pRxMsg->Data[0];// ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table);Byte_num=CanHandle->pRxMsg->Data[0];
// sprintf(data, '%d', hcan1.pRxMsg->Data[0]);// ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table); //HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); } RxIntEnable(CanHandle);}
void RxIntEnable(CAN_HandleTypeDef *CanHandle) {
if(CanHandle->State == HAL_CAN_STATE_BUSY_TX) CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX; else { CanHandle->State = HAL_CAN_STATE_BUSY_RX;/* Set CAN error code to none */
CanHandle->ErrorCode = HAL_CAN_ERROR_NONE;/* Enable Error warning Interrupt */
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EWG);/* Enable Error passive Interrupt */
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EPV);/* Enable Bus-off Interrupt */
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_BOF);/* Enable Last error code Interrupt */
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_LEC);/* Enable Error Interrupt */
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_ERR); }// Enable FIFO 0 message pending Interrupt
__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_FMP0);}2016-12-12 11:26 PM
Using events to signal a different thread from an interrupt is the way to do it. However, you can't rely on the hardware fifo. You must add some software fifo, otherwise you're still going to truncate data when a burst arrives.
Note that because of this, you can't possibly keep up with a saturated bus! Don't expect this either. It's part of CAN bus design to not have a saturated bus.
2017-06-16 12:59 PM
Hi Raider E,
I am also having the similar problem. I will try the solution proposed here and will try to update in case I will be successful or not. Meanwhile can you please provide me the link of the 'youtube tutorial' you have mentioned in your post.
Thank youNaqqash