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;
}

  

18 REPLIES 18

Here is the project file:

kumaichi
Associate III

Not sure how useful this will be for you, but ControllersTech did an excellent video on CAN normal mode.

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.

The circuit on CAN_STBY is putting the TJA1042BT probably in standby. The STB pin is a digital input, so setting it to 1.6V is definitively not a good idea. Please remove R5 to enable the Driver.

Martin


@MHoll.2 wrote:

The circuit on CAN_STBY is putting the TJA1042BT probably in standby. The STB pin is a digital input, so setting it to 1.6V is definitively not a good idea. Please remove R5 to enable the Driver.

Martin


Yes it could be related to this.

SofLit_0-1726066755358.png

 

 

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.

Hi,

I tried the interrupt code you have provided. But there is no change. Nothing is receiving as RxData.

  • And removed the R5 and checked again, again there is no change.
  • Screenshot 2024-09-12 103403.png

Hi, 

thankyou for replying.

 

I am already using Controllers Tech video as a reference.

Check your hardware. You need to check all the HW part of the CAN network. The power, the connections, the termination resistors.

You need to probe CAN_Tx and CAN_Rx pins and see what happens.

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.

Hi,

Thank You all for reply.

The issue was related to the standby pin on the transceiver. I started receiving data once the STBY pin was set to low.