cancel
Showing results for 
Search instead for 
Did you mean: 

Problem receiving CAN messages using HAL for STM32F767ZI

tor7767
Associate II

Edit: HAL_CAN_Start() and configuring the CAN filter correctly fixed it.

Hi, I am trying to read CAN messages sent by a device, but are not able to.

Hardware setup should be correct, my setup works when testing with a program using mBed OS, messages are correctly received.

Some notes:

  • The messages are specified to be CAN2.0B, standard frame format, baud 250kbps, Sampling point 70%, SJW 2 Tq.
  • CAN1 is used configured to PD0 and PD1.
  • UART and GPIO works as expected.
  • I used http://www.bittiming.can-wiki.info/ for bit timing, BTR register is set to 0x0149000b which I have verified in the debugger.
  • HAL_CAN_GetRxFifoFillLevel() returns 0 and HAL_CAN_GetRxMessage returns no message.
  • The clocks is configured to the default that CubeMX set when initializing default settings for peripherals, APB1 clock is set to 48 MHz, which is used as basis for the CAN bit timings.
  • I have not configured any filter.

Code(irrelevant code removed, msp at the end):

#include "main.h"
#include <stdio.h>
 
CAN_HandleTypeDef hcan1;
UART_HandleTypeDef huart3;
 
CAN_TxHeaderTypeDef   TxHeader;
CAN_RxHeaderTypeDef   RxHeader;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
char msg[50];
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_CAN1_Init(void);
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_CAN1_Init();
 
  uint8_t TestData[7];
 
  while (1)
  {
 
	  sprintf(msg,"Waiting for message\r\n");
	  HAL_UART_Transmit(&huart3,(uint8_t*)msg,sizeof(msg),HAL_MAX_DELAY);
 
	  if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0)
	  {
		  HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, TestData);
		  HAL_UART_Transmit(&huart3, "Can Message recieved\n\r", 22, 10);
	  }
 
	  HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, TestData);
 
	  sprintf(msg,"Message: %x\r\n", TestData[0]);
	  HAL_UART_Transmit(&huart3,(uint8_t*)msg,sizeof(msg),HAL_MAX_DELAY);
 
	  HAL_Delay(500);
  }
 
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  HAL_PWR_EnableBkUpAccess();
 
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 96;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    Error_Handler();
  }
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_CLK48;
  PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
  PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_CAN1_Init(void)
{
 
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 12;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
static void MX_GPIO_Init(void)
{
 lots of code
}
 
void Error_Handler(void)
{
}
 
/* hal_msp.c */
 
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hcan->Instance==CAN1)
  {
 
    __HAL_RCC_CAN1_CLK_ENABLE();
 
    __HAL_RCC_GPIOD_CLK_ENABLE();
 
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
  }
 
}

1 ACCEPTED SOLUTION

Accepted Solutions
Michael Hilzendegen
Associate II

Did you call HAL_CAN_Start() somewhere in your code?

Also uint8_t TestData[7] should be uint8_t TestData[8].

If you are using CubeMX you could have a look into:

STM32Cube/Repository/STM32Cube_FW_F7_V.15.0/Projects/STM32F723E-Discovery/Examples/CAN/CAN_Loopback/Src/main.c

for comparison.

View solution in original post

5 REPLIES 5
Michael Hilzendegen
Associate II

Hello tor7767,

How did you setup the BTR register?

Maybe MX_CAN1_Init() resets your configuration,

since it clearly doesnt meet your setup of 250kbps, Sampling point 70%, SJW 2 Tq

tor7767
Associate II

My mistake, I posted wrong MX_CAN1_init. The correct one(which does not work) is

static void MX_CAN1_Init(void)
{
 
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 12;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
 
}

Michael Hilzendegen
Associate II

Did you call HAL_CAN_Start() somewhere in your code?

Also uint8_t TestData[7] should be uint8_t TestData[8].

If you are using CubeMX you could have a look into:

STM32Cube/Repository/STM32Cube_FW_F7_V.15.0/Projects/STM32F723E-Discovery/Examples/CAN/CAN_Loopback/Src/main.c

for comparison.

tor7767
Associate II

I added HAL_CAN_Start() and now I can find seemingly correct data in the corresponding receive registers(Rl0R/RDL0R/RDH0R) when running in debug.

The data is still not read with HAL_CAN_GetRxMessage and HAL_CAN_GetRxFifoFillLevel. I will try to add a proper CAN filter.

hey @Tor Egil Øvernes​ , does it work now? Could you please share the working code...