Skip to main content
Associate
August 14, 2024
Question

Issue in CAN commnuication with STM32466RE

  • August 14, 2024
  • 1 reply
  • 968 views

I am currently working on a project involving two STM32F446RE microcontrollers, each connected to a CJMCU-2551 MCP2551 CAN Protocol Controller High-speed Interface Module. The setup is intended to facilitate CAN communication between the two microcontrollers.

Problem:

  • The STM32F446RE configured as the transmitter is successfully sending data.
  • However, the second STM32F446RE, intended to receive the data, is not receiving any communication.
  • Additionally, I have observed that the MCP2551 module connected to the transmitting STM32F446RE is showing equal voltage levels on both the CANH and CANL pins.

Request for Assistance:

  • Could this issue be related to the CAN bus itself, or might it be a problem with the software configuration?
  • What steps can I take to diagnose and resolve this issue?

Any insights or suggestions would be greatly appreciated.

    1 reply

    Senior III
    August 14, 2024

    Best is to connect a known working device such as arduino which receives all transmitted frames. If the receiver do not acknowledge,  the transmitter will stop.

    Associate
    August 14, 2024

    in my case , I have 2 stm32F446RE One is transmitter and another is receiver and reciever don't receive anything inspite of transmitting correctly..can you give me according to this scenario any solution.

     

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * Copyright (c) 2024 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"
    
    /* 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 hcan2;
    
    /* USER CODE BEGIN PV */
    CAN_RxHeaderTypeDef rxHeader; //CAN Bus Transmit Header
    
    CAN_FilterTypeDef canfilterconfig;
    
    uint8_t canRX;
    uint32_t C=0;
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_CAN2_Init(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_CAN2_Init();
     /* USER CODE BEGIN 2 */
     HAL_CAN_ConfigFilter(&hcan2,&canfilterconfig); //Initialize CAN Filter
     HAL_CAN_Start(&hcan2); //Initialize CAN Bus
     HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO1_MSG_PENDING);// Initialize CAN Bus Rx Interrupt
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* 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
     */
     __HAL_RCC_PWR_CLK_ENABLE();
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
    
     /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
     RCC_OscInitStruct.PLL.PLLM = 4;
     RCC_OscInitStruct.PLL.PLLN = 72;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
     RCC_OscInitStruct.PLL.PLLQ = 2;
     RCC_OscInitStruct.PLL.PLLR = 2;
     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_DIV2;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    /**
     * @brief CAN2 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_CAN2_Init(void)
    {
    
     /* USER CODE BEGIN CAN2_Init 0 */
    
     /* USER CODE END CAN2_Init 0 */
    
     /* USER CODE BEGIN CAN2_Init 1 */
    
     /* USER CODE END CAN2_Init 1 */
     hcan2.Instance = CAN2;
     hcan2.Init.Prescaler = 72;
     hcan2.Init.Mode = CAN_MODE_NORMAL;
     hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
     hcan2.Init.TimeSeg1 = CAN_BS1_1TQ;
     hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
     hcan2.Init.TimeTriggeredMode = DISABLE;
     hcan2.Init.AutoBusOff = DISABLE;
     hcan2.Init.AutoWakeUp = DISABLE;
     hcan2.Init.AutoRetransmission = DISABLE;
     hcan2.Init.ReceiveFifoLocked = DISABLE;
     hcan2.Init.TransmitFifoPriority = DISABLE;
     if (HAL_CAN_Init(&hcan2) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN CAN2_Init 2 */
    
    
    	canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
    	canfilterconfig.FilterBank = 18; // which filter bank to use from the assigned ones
    	canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO1;
    	canfilterconfig.FilterIdHigh = 0x446<<5;
    	canfilterconfig.FilterIdLow = 0;
    	canfilterconfig.FilterMaskIdHigh = 0x446<<5;
    	canfilterconfig.FilterMaskIdLow = 0x0000;
    	canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
    	canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
    	canfilterconfig.SlaveStartFilterBank = 20; // how many filters to assign to the CAN1 (master can)
    
     /* USER CODE END CAN2_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_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
    
     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
     /*Configure GPIO pin : PA5 */
     GPIO_InitStruct.Pin = GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    /* USER CODE BEGIN MX_GPIO_Init_2 */
    /* USER CODE END MX_GPIO_Init_2 */
    }
    
    /* USER CODE BEGIN 4 */
    void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan1)
    {
    	if(HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO1, &rxHeader, &canRX)){ //Receive CAN bus message to canRX buffer
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET);// toggle PA3 LED
     C++;
    	}
    }
    /* 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)
     {
     }
     /* 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.
     * @PAram file: pointer to the source file name
     * @PAram 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 is my reciever code .