Skip to main content
Visitor II
September 15, 2025
Solved

CAN Loopback Test using STM32 NUCLEO-L452RE

  • September 15, 2025
  • 2 replies
  • 385 views

It seems like the program is getting stuck in the Error_Handler loop and not coming out. Could there be a problem with my code?

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.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 ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
uint8_t button_pressed_flag = 0;
uint8_t message_received_flag = 0;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* 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_USART2_UART_Init();
 MX_CAN1_Init();
 /* USER CODE BEGIN 2 */
 // 1. CAN 수신 필터 설정 (Loopback에서도 필수는 동일)
 CAN_FilterTypeDef canfilterconfig;
 canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
 canfilterconfig.FilterBank = 0;
 canfilterconfig.FilterFIFOAssignment = CAN_RX_FIFO0;
 canfilterconfig.FilterIdHigh = 0x0000;
 canfilterconfig.FilterIdLow = 0x0000;
 canfilterconfig.FilterMaskIdHigh = 0x0000;
 canfilterconfig.FilterMaskIdLow = 0x0000;
 canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
 canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;

 if (HAL_CAN_ConfigFilter(&hcan1, &canfilterconfig) != HAL_OK)
 {
 Error_Handler();
 }

 // 2. CAN 통신 시작
 if (HAL_CAN_Start(&hcan1) != HAL_OK)
 {
 Error_Handler();
 }

 // 3. CAN 수신 메시지 알림(인터럽트) 활성화
 if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
 {
 Error_Handler();
 }

 // 4. 전송할 메시지 헤더 기본 설정
 TxHeader.IDE = CAN_ID_STD;
 TxHeader.StdId = 0x123; // 메시지 ID
 TxHeader.RTR = CAN_RTR_DATA;
 TxHeader.DLC = 1; // 데이터 길이 (1바이트)
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	 // 1. 버튼이 눌렸으면 메시지 전송
	 if (button_pressed_flag == 1)
	 {
	 button_pressed_flag = 0; // 플래그 초기화

	 TxData[0]++; // 보낼 때마다 데이터 1씩 증가

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

	 // 2. 메시지가 수신되었으면 LED 토글
	 if (message_received_flag == 1)
	 {
	 message_received_flag = 0; // 플래그 초기화
	 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); // 녹색 LED 깜빡이기
	 }
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */


 }
 /* USER CODE END 3 */
}

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

 /** Configure the main internal regulator output voltage
 */
 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
 {
 Error_Handler();
 }

 /** 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 = 64;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 1;
 RCC_OscInitStruct.PLL.PLLN = 10;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
 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_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

/* USER CODE BEGIN 4 */
/**
 * @brief CAN 메시지 수신 완료 시 호출되는 콜백 함수
 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
 if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
 {
 // 수신된 ID가 내가 보낸 ID와 일치하는지 확인
 if (RxHeader.StdId == 0x123)
 {
 message_received_flag = 1; // 수신 플래그 설정
 }
 }
}
/**
 * @brief 외부 인터럽트(버튼) 발생 시 호출되는 콜백 함수
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if (GPIO_Pin == B1_Pin)
 {
 button_pressed_flag = 1; // 버튼 플래그 설정
 }
}
/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
	 // 오류 발생 시 녹색 LED가 매우 빠르게 깜빡이도록 설정
	 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	 HAL_Delay(100);
 }
 /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * file: pointer to the source file name
 * line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
    This topic has been closed for replies.
    Best answer by Karl Yamashita

    Some code are missing that typically are produced by CubeMX or STM32CubeIDE

     

    /* Private variables ---------------------------------------------------------*/
    CAN_HandleTypeDef hcan1; // You're missing this
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);// You're missing this
    static void MX_CAN1_Init(void);// You're missing this
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */

     

    Not sure how you're getting the project to build, if hcan1 is not defined?

    Are you copying code from somewhere or did you use CubeMX/STM32CubeIDE to generate the code?

    2 replies

    Technical Moderator
    September 15, 2025

    Hello @OH and welcome to the St community,

    You didn't share the CAN configuration? The GPIOs configuration of Tx/Rx? and you didn't tell on which Error_Handler() it was stuck? which line?

    You can also refer to this article: Guide to CAN (bxCAN/CAN2.0) configuration in Loop back mode on STM32 MCUs

    Graduate II
    September 15, 2025

    Some code are missing that typically are produced by CubeMX or STM32CubeIDE

     

    /* Private variables ---------------------------------------------------------*/
    CAN_HandleTypeDef hcan1; // You're missing this
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);// You're missing this
    static void MX_CAN1_Init(void);// You're missing this
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */

     

    Not sure how you're getting the project to build, if hcan1 is not defined?

    Are you copying code from somewhere or did you use CubeMX/STM32CubeIDE to generate the code?