STM32 CAN总线通讯

 使用STM32的CAN通讯,利用回环模式,按键控制发送CAN数据,中断接收CAN数据并通过串口助手打印出来。

7.2、配置引脚信息

由于每次新建工程都需要配置信息,比较麻烦,好在STM32CubeIDE提供了导入.ioc文件的功能,可以帮我们节省时间。

1.从Serial的项目里导入ioc文件,并命名为CAN。

在Connectivity里找到CAN,并打勾Activated使能CAN外设。

image-20220326121240215

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

image-20220326122605409

image-20220326122759412

image-20220326122910978

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

image-20220326121651092

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

image-20220326121936036

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

image-20220326122355699

核心代码解释

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接收到的数据。

image-20220326141649900

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值