2025-02-24 5:26 AM
I am trying to use my STM32F429IGT6 CAN to receive some data from the host computer. The data is basically 4 16-bit unsigned integers (8 bytes in total), the message ID is 0x16 and uses the 11-bit standard ID format. The host computer sends messages to the bus in a 2ms cycle.
On the STM32 part, I enabled CAN1 and used the interrupt function to receive and process the data. However, most of the time, the STM32 does not show any CAN messages coming, and the HAL_CAN_GetRxFifoFillLevel() function always returns 0. This makes me really confused.
Below is the initialization code in my can.c file. My CAN1 is mounted on the APB1 bus with a frequency of 45Mhz, and the CAN transmission rate of the host computer and STM32 is 500kbps.
void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END CAN1_Init 2 */
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
/* USER CODE END CAN1_MspInit 1 */
}
}
and this is my interrupt funciton:
CAN_RxHeaderTypeDef RxHeader;
uint16_t RxData[4];
uint16_t canbuf[4]; /* CAN rx dest */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, (uint8_t *)RxData) == HAL_OK)
{
for (int i = 0; i < RxHeader.DLC / 2; i++)
{
canbuf[i] = RxData[i];
}
}
}
So far, I have tried the following steps:
1. Confirm that the 120 ohm terminal resistors on both sides of the CAN have been added. The CAN cable is a standard twisted pair with a DB9 interface and is well connected.
2. The CAN configuration of the host computer is in send mode, using the standard 11-bit ID mode, the ID value is 18 (0x12), the data segment is 8 bytes, the baud rate is 500kbps (consistent with STM32), and the message transmission rate is 2ms once.
3. I tried to monitor the ESR register (error register) of CAN1 in real time through debug mode, but no abnormalities were found. All flag bits look normal (all 0).
4. I confirmed that I have called the HAL_CAN_Start() and HAL_CAN_ActivateNotification() functions normally.
The one thing I have left to do is to test the CAN message levels sent by the host computer through a logic analyzer (the analyzer is on the way), but I think the possibility of an error in the host computer is low.
Looking forward to responses from people who have had similar problems or professionals.
Solved! Go to Solution.
2025-02-25 8:27 PM
Host computer: https://en.modeling-tech.com/products/4.html
I have now connected the GND of the STM32 board and the GND of the DB9 cable together, and the situation has not improved.
I used CubeMX to configure the CAN, and the ioc file is attached. I did a lot of searching online, and someone did mention that this might be a problem with SJW and Time Seg, although the SJW and Time Seg I configured were able to get the correct baud rate after calculation. Perhaps I should try other SJW or Time Seg values?
2025-02-25 8:57 PM
Your time seg 1 and 2 are pretty close to each other. The sampling point should be in the high 80s
Your values might be closer to ~30
try these values
2025-02-26 10:11 AM
Good news, I tried to recreate a new project, where only CAN1 and USART1 (for sending debug data) were enabled, and it seems that the STM32 can normally and stably receive the data returned from the host computer.
In my original project with LVGL integrated, CAN could not be received normally even after trying the new sampling point. There must be something in my code that prevents CAN from running normally.
I am troubleshooting the problem step by step, maybe you have any clues about this phenomenon?
2025-02-26 11:01 AM - edited 2025-02-27 12:48 AM
Hello,
If you are able to receive CAN frames with a very simple project with the same hardware, this is a good sign and it confirms that it's not a hardware issue.
What I suggest is to comment out all the code not related to the CAN in your "LVGL project" and test. If it doesn't work replace the CAN configuration with the code you've written with the simple project. If it does work, it will be a bit tricky to debug. As I don't have your board and your project I cannot run the test. But think about a conflict of GPIOs. It may due to some code in your LVGL project that modified the CAN pins configuration. Check also if the CAN RXFIFO NVIC is enabled. Check also the interrupt priorities. For example increase the preemption of the CAN RXFIFO NVIC.
2025-02-26 2:22 PM
After a night of debugging, I finally located the problem in the initialization function of my LTDC screen. When I disabled everything except CAN and UART (including LVGL), whenever lcd_init() was called, CAN would definitely fail after a while of receiving. If I commented out lcd_init() and did not initialize the LTDC screen, everything worked fine.
The driver file for the LTDC screen was obtained from the screen manufacturer, which included some color filling functions and the DMA2D driver. I tried to change the priority of the DMA2D interrupt and reduce the main frequency of the LTDC screen, but nothing seemed to work. The original version of this driver was written, compiled and run under Keil. Since I was familiar with IAR EW, I converted it to an IAR EW version and added it to my project file. But obviously, something went wrong during the conversion process, and I didn't know what it was.Unfortunately, my development experience is not enough for me to answer this strange phenomenon. Maybe you have some ideas about this phenomenon?
I spent a little time porting my project file back to the version adapted for Keil, and now it works fine, and LVGL and CAN can run perfectly well. Although the previous problem has not been fundamentally solved, at least I can continue working now.
In any case, I want to thank you for your help - you, Mr. Karl Yamashita, Mr. LCE and other partners. In order to save resources, I will not reply to them one by one. I hope they can all see this message. It is your wisdom that helps this community grow better and also helps STM32 become one of the best MCUs. Thank you again for your help!
2025-02-27 5:29 AM - edited 2025-02-27 5:30 AM
Hello @most1ma
Thank your for your valuable feedback :).
@most1ma wrote:
In any case, I want to thank you for your help - you, Mr. Karl Yamashita, Mr. LCE and other partners. In order to save resources, I will not reply to them one by one.
In next time you can tag the contributors using '@ ' so they can get the notification and read your message.
And thank you for choosing STM32 MCU.