cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CAN Normal mode

DivyaJayan
Associate III

Hi All,

I am currently working on the CAN normal mode in a custom board with MCU STM32F098RCT6 and CAN transceiver TJA1042. Very first I tried the loopback mode and it was successful. Then I am now trying to interface two custom boards using the normal mode. But there is no output. 

Please give some insight about this.

Here is the code: 

#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;

/* USER CODE BEGIN PV */

CAN_TxHeaderTypeDef  TxHeader;
CAN_RxHeaderTypeDef  RxHeader;

uint8_t TxData[2];
uint8_t RxData[2];

uint32_t TxMailbox;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/* USER CODE BEGIN PFP */
HAL_StatusTypeDef  CAN_Polling(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  /* USER CODE BEGIN 2 */

  if(CAN_Polling() != HAL_OK){
         while(1){}
       }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_11);
	  HAL_Delay(500);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief CAN Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN;
  hcan.Init.Prescaler = 16;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

  /* USER CODE END CAN_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET);

  /*Configure GPIO pin : PC11 */
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

HAL_StatusTypeDef  CAN_Polling(void){

	  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 = CAN_FILTER_ENABLE;
	  sFilterconfig.SlaveStartFilterBank = 14;

	  if(HAL_CAN_ConfigFilter(&hcan, &sFilterconfig) != HAL_OK)
	  {
		  Error_Handler();
	  }

	  if(HAL_CAN_Start(&hcan) != HAL_OK)
	  {
		  Error_Handler();
	  }

	  TxHeader.IDE = CAN_ID_STD;
	  TxHeader.RTR = CAN_RTR_DATA;
	  TxHeader.StdId = 0x11;
	  TxHeader.DLC = 2;
	  TxHeader.TransmitGlobalTime = DISABLE;

	  TxData[0] = 0xCA;
	  TxData[1] = 0xFE;

	 if( HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK)
	 {
		 Error_Handler();
	 }

	 while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != HAL_OK){}

	 if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != HAL_OK)
	 {
		 Error_Handler();
	 }
	 if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
	 {
		 Error_Handler();
	 }

	 return HAL_OK;
}

  

1 ACCEPTED SOLUTION

Accepted Solutions

In your code, you send and receive once in polling mode. So I don't know how you test that and what you expect as a behavior.

	 if( HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK)
	 {
		 Error_Handler();
	 }

	 while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != HAL_OK){}

	 if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != HAL_OK)
	 {
		 Error_Handler();
	 }
	 if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
	 {
		 Error_Handler();
	 }

I modified your project (in attachement) to work in RX FIFO interrupt mode. SystemClock at 48MHz / CAN bitrate at 500kb/s (modified the prescaler, BS1 and BS2 with recommended values).

Unfortunately I don't have a board to test that MCU part number. So you need to test it from your side: in the Live Expression check RxData[].

Hope it helps.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

17 REPLIES 17
SofLit
ST Employee

Hello @DivyaJayan ,

First, you are still using Loopback mode:

  hcan.Init.Mode = CAN_MODE_LOOPBACK;

Second, the values you selected for BS1 and BS2 are not recommended and they are too low.

Need to decrease the prescaler and increase BS1 and BS2 as match as possible where BS1=~(45% to 85%) (BS1+BS2)

Third, in Normal mode, HSI is not recommended in CAN communication . Need to use HSE with an external Crystal.

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I have made the changes you suggested. But still also I am  getting the same.

 

Screenshot 2024-09-10 175402.png

 

Could you please share your project including the ioc file? if you don't want to share it in public send it to me in PV. Compress it as .7z file.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Another question, what is connected on the CAN bus apart of (STM32F098RCT6 + TJA1042)? and how did you establish the CAN bus?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Received from private message:

"Nothing connected on CAN bus. There is only STM32F098RCT6  and TJA1042."

CAN is not SPI or UART to use it as simple Transmit or receive in a "floating" bus. You need at least two CAN nodes connected on the bus for ACK mechanism.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
SofLit
ST Employee

Hello again,

In private message you said: "Nothing connected on CAN bus. There is only STM32F098RCT6  and TJA1042."

And in the original post you said:


@DivyaJayan wrote:

Then I am now trying to interface two custom boards using the normal mode. But there is no output.   


But according to this statement you said there are two custom boards: Very confusing.

So now you need to provide a sketch on which you show how your two custom boards are connected together over the transceivers.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
  • I have two custom boards with STM32F098RCT6 & TJA1042 transceiver and I am trying to communicate with each other. I provided 12V supply to both the board and connected CAN_Tx and CAN_Rx pin of the two boards.
  • In each board there is only  STM32F098RCT6 & TJA1042 in the CAN bus.

@DivyaJayan wrote:
  • I have two custom boards with STM32F098RCT6 & TJA1042 transceiver

1- Same HW for the two boards?

2- Need to provide schematics.

3- Again please share the all project by compressing it in .7z format and drag and drop it here. Other compressed file formats are not supported.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Yes, same HW for both two boards.

Here is the schematics:

 

Screenshot 2024-09-11 182437.png

 

 Screenshot 2024-09-11 182449.png