使用STM32的CAN通讯,利用回环模式,按键控制发送CAN数据,中断接收CAN数据并通过串口助手打印出来。
由于每次新建工程都需要配置信息,比较麻烦,好在STM32CubeIDE提供了导入.ioc文件的功能,可以帮我们节省时间。
1.从Serial的项目里导入ioc文件,并命名为CAN。
在Connectivity里找到CAN,并打勾Activated使能CAN外设。

2.根据原理图可知,CAN总线连接的引脚为PB8和PB9,而默认的CAN总线引脚为PA11和PA12,所以需要手动修改CAN总线的引脚为PB8和PB9。



3.设置CAN外设的参数,这里我们设置波特率为1000kbps,模式设置为Loopback。

由于这里只用来测试通讯,所以选择Loopback回环模式(数据自发自收);如果需要连接第三方CAN设备,请选择为Normal常规模式(数据收/发独立)。

4.中断设置里将CAN RX0中断打开,如果不打开中断就无法接收到数据。

1.在BSP中新建蜂鸣器的驱动库bsp_can.h和bsp_can.c文件。在bsp_can.h中增加以下内容:
- /*
- * bsp_can.h
- *
- * Created on: Mar 7, 2022
- * Author: Administrator
- */
-
- #ifndef BSP_CAN_H_
- #define BSP_CAN_H_
-
- void Can_Init(void);
- void Can_Test_Send(void);
-
- #endif /* BSP_CAN_H_ */
2.在bsp_can.c中添加以下内容:
Can_Init():初始化CAN外设相关内容,设置CAN接收过滤器,开启CAN总线通讯。
- #include "bsp_can.h"
- #include "bsp.h"
-
- // Define related variables 定义相关变量
- CAN_TxHeaderTypeDef TxHeader;
- CAN_RxHeaderTypeDef RxHeader;
- CAN_FilterTypeDef sFilterConfig;
-
-
- // Initialize the CAN 初始化CAN
- void Can_Init(void)
- {
- 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.SlaveStartFilterBank = 27;
- sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;
-
- // Setting the CAN Filter 设置CAN过滤器
- if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
- {
- Error_Handler();
- }
-
- // Start the CAN peripheral 启动CAN
- if (HAL_CAN_Start(&hcan) != HAL_OK)
- {
- Error_Handler();
- }
-
- // Activate CAN RX notification 启动CAN RX通知
- if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
-
- // The test sends data through CAN 测试通过CAN发送数据
- void Can_Test_Send(void)
- {
- uint8_t TxData[8];
- uint32_t TxMailbox = 0;
- TxHeader.StdId = 0x000F;
- TxHeader.ExtId = 0x00;
- TxHeader.RTR = CAN_RTR_DATA;
- TxHeader.IDE = CAN_ID_STD;
- TxHeader.DLC = 8;
- TxHeader.TransmitGlobalTime = DISABLE;
-
- for (int i = 0; i < 8; i++)
- {
- TxData[i] = 1 << i;
- }
- printf("CAN Send:%02X %02X %02X %02X %02X %02X %02X %02X \n",
- TxData[0], TxData[1], TxData[2], TxData[3],
- TxData[4], TxData[5], TxData[6], TxData[7]);
- // Send Data 发送数据
- if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
-
- // CAN receives interrupt callbacks CAN接收中断回调
- void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
- {
- if (hcan->Instance == CAN1)
- {
- uint8_t RxData[8];
- if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
- {
- Error_Handler();
- }
- else
- {
- printf("CAN Receive:%02X %02X %02X %02X %02X %02X %02X %02X \n",
- RxData[0], RxData[1], RxData[2], RxData[3],
- RxData[4], RxData[5], RxData[6], RxData[7]);
- }
- }
- }
3.为了测试发送数据,新建Can_Test_Send()函数把数据通过CAN发送出去,并打印到串口助手上。如果需要修改发送的数据,在发送前修改TxData数组即可。
4.CAN接收中断回调函数,将接收到CAN数据通过串口打印出来。此函数名称不能修改,否则无法调用到此函数。
5.在BSP初始化中,调用Can_Init()函数初始化CAN外设。
- //bsp.c
- #include "bsp.h"
-
- // LED显示当前运行状态,每10毫秒调用一次,LED灯每200毫秒闪烁一次。
- // The LED displays the current operating status, which is invoked every 10 milliseconds, and the LED blinks every 200 milliseconds.
- void Bsp_Led_Show_State_Handle(void)
- {
- static uint8_t led_count = 0;
- led_count++;
- if (led_count > 20)
- {
- led_count = 0;
- LED_TOGGLE();
- }
- }
-
-
- // The peripheral device is initialized 外设设备初始化
- void Bsp_Init(void)
- {
- Can_Init();
- USART1_Init();
- Beep_On_Time(50);
- printf("start\n");
- }
-
-
- // main.c中循环调用此函数,避免多次修改main.c文件。
- // This function is called in a loop in main.c to avoid multiple modifications to the main.c file
- void Bsp_Loop(void)
- {
- // Detect button down events 检测按键按下事件
- if (Key1_State(KEY_MODE_ONE_TIME))
- {
- Beep_On_Time(50);
- Can_Test_Send();
- }
-
- Bsp_Led_Show_State_Handle();
- // The buzzer automatically shuts down when times out 蜂鸣器超时自动关闭
- Beep_Timeout_Close_Handle();
- HAL_Delay(10);
- }
6.在按键按下后,增加发送CAN数据的功能。
烧录程序后,LED灯每隔200毫秒闪一次,将扩展板通过micro-USB数据线与电脑连接后并打开串口助手(具体参数如下图所示),每按一次按键,蜂鸣器都会响50毫秒,可以看到串口助手会显示CAN发送的数据以及CAN接收到的数据。
