STM32-HAL library 09-CAN communication (loopback mode)

1. Materials used:

STM32F103C6T6 Minimum System Board
STM32CUBEMX (HAL library software)
MDK5
Serial debugging assistant

2. What you learned:

Preliminarily learn how to use the CAN communication function of STM32. In this chapter, we mainly achieve the effect of on-board CAN communication, that is, 32 sends CAN information and then prints it out through the serial port in the CAN receiving interrupt.

3. CUBEMX configuration:

The first step: the old three-piece set-RCC, SYS, clock tree configuration



Step 2: Serial port configuration

Step 3: CAN configuration

key step:

  • Baud rate setting: 1M bit/s, the specific configuration is as shown below
  • TEST MODE-Loopback
  • Turn on receive interrupt RX0

4. MDK5 configuration:

1. can.h header file configuration

/* Define to prevent recursive inclusion ---------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__

#ifdef __cplusplus
extern "C" {<!-- -->
#endif

/* Includes ----------------------------------------------- ------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern CAN_HandleTypeDef hcan;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_CAN_Init(void);

/* USER CODE BEGIN Prototypes */
void CANFilter_Config(void);
void CAN1_Send_Test(void);
void CAN_Start_Init(void);
void CAN1_Send(uint8_t* cdata);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __CAN_H__ */


2. can.c source file configuration

/* Includes ----------------------------------------------- -----------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */
#include "stdio.h"
#include "usart.h"
#include "main.h"
static CAN_TxHeaderTypeDef TxMessage; //Message header of the message sent by CAN
static CAN_RxHeaderTypeDef RxMessage; //Message header of the message received by CAN
/* USER CODE END 0 */

CAN_HandleTypeDef hcan;

/* CAN init function */
void MX_CAN_Init(void)
{<!-- -->
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 4;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_5TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_3TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init( & amp;hcan) != HAL_OK)
  {<!-- -->
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

  /* USER CODE END CAN_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{<!-- -->

  GPIO_InitTypeDef GPIO_InitStruct = {<!-- -->0};
  if(canHandle->Instance==CAN1)
  {<!-- -->
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN GPIO Configuration
    PA11 ------> CAN_RX
    PA12 ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */

  /* USER CODE END CAN1_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{<!-- -->

  if(canHandle->Instance==CAN1)
  {<!-- -->
  /* USER CODE BEGIN CAN1_MspDeInit 0 */

  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();

    /**CAN GPIO Configuration
    PA11 ------> CAN_RX
    PA12 ------> CAN_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */

  /* USER CODE END CAN1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
/************************
Accept message filters
*******************/
 void CANFilter_Config(void)
{<!-- -->
    CAN_FilterTypeDef sFilterConfig;
    
    sFilterConfig.FilterBank = 0; //CAN filter number, range 0-27
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //CAN filter mode, mask mode or list mode
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //CAN filter scale, 16-bit or 32-bit
    sFilterConfig.FilterIdHigh = 0x000 << 5; //Under 32 bits, store the high 16 bits of the ID to be filtered
    sFilterConfig.FilterIdLow = 0x0000; //Under 32 bits, store the lower 16 bits of the ID to be filtered
    sFilterConfig.FilterMaskIdHigh = 0x0000; //In mask mode, the mask is stored
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterFIFOAssignment = 0; //After the message passes the filter match, which FIFO is stored in it
    sFilterConfig.FilterActivation = ENABLE; //Activate filter
    sFilterConfig.SlaveStartFilterBank = 0;
    
    if (HAL_CAN_ConfigFilter( & amp;hcan, & amp;sFilterConfig) != HAL_OK)
{<!-- -->
        Error_Handler();
       }
else{<!-- --> printf("HAL_CAN_ConfigFilter( & amp;hcan, & amp;sFilterConfig) is HAL_OK\r\\
"); }
}
/************************
Interrupt acceptance
*******************/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{<!-- -->

    uint8_t data[8];
    HAL_StatusTypeDef status;
    status = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, & amp;RxMessage, data);
    if (HAL_OK == status)
{<!-- -->
printf("--->Data Receive!\r\\
");
printf("RxMessage.StdId is %#x\r\\
", RxMessage.StdId);
printf("data[0] is 0x x\r\\
", data[0]);
printf("data[1] is 0x x\r\\
", data[1]);
printf("data[2] is 0x x\r\\
", data[2]);
printf("data[3] is 0x x\r\\
", data[3]);
printf("data[4] is 0x x\r\\
", data[4]);
printf("data[5] is 0x x\r\\
", data[5]);
printf("data[6] is 0x x\r\\
", data[6]);
printf("data[7] is 0x x\r\\
", data[7]);
printf("<---\r\\
");
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
}

/************************
send function
*******************/
void CAN1_Send_Test(void)
{<!-- -->
    uint32_t TxMailbox;
    uint8_t data[4] = {<!-- -->0x01, 0x02, 0x03, 0x04};
    TxMessage.IDE = CAN_ID_STD; //Set ID type
TxMessage.StdId = 0x111; //Set ID number
    TxMessage.RTR = CAN_RTR_DATA; //Set the transmission data frame
TxMessage.DLC = 4; //Set data length
if (HAL_CAN_AddTxMessage( & amp;hcan, & amp;TxMessage, data, & amp;TxMailbox) != HAL_OK)
{<!-- -->
        Error_Handler();
     }
// else{ printf("HAL_CAN_AddTxMessage( & amp;hcan, & amp;TxMessage, data, & amp;TxMailbox) is HAL_OK\r\\
"); }
}

void CAN1_Send(uint8_t* cdata)
{<!-- -->
    uint32_t TxMailbox;
    TxMessage.IDE = CAN_ID_STD; //Set ID type
TxMessage.StdId = 0x111; //Set ID number
    TxMessage.RTR = CAN_RTR_DATA; //Set the transmission data frame
TxMessage.DLC = 8; //Set data length
if (HAL_CAN_AddTxMessage( & amp;hcan, & amp;TxMessage, cdata, & amp;TxMailbox) != HAL_OK)
{<!-- -->
        Error_Handler();
    }
}
/************************
CAN start function
*******************/
void CAN_Start_Init(void)
{<!-- -->
  if (HAL_CAN_Start( & amp;hcan) != HAL_OK)
    {<!-- -->
        Error_Handler();
     }
  else{<!-- --> printf("HAL_CAN_Start( & amp;hcan) is HAL_OK\r\\
"); }
    
    /* 3. Enable CAN RX Interrupt */
    if (HAL_CAN_ActivateNotification( & amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {<!-- -->
        Error_Handler();
    }
  else{<!-- --> printf("HAL_CAN_ActivateNotification( & amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING) is HAL_OK\r\\
"); }
}
/* USER CODE END 1 */

3. Main.c file configuration

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();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  CANFilter_Config();
  CAN_Start_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {<!-- -->
CAN1_Send_Test();
HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4. Serial port printing results:

5. Sharing of code corresponding to this article:

https://download.csdn.net/download/qq_45854134/88522530