stm32 cubemx can通讯(3)bsp_can

这篇具有很好参考价值的文章主要介绍了stm32 cubemx can通讯(3)bsp_can。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

stm32 cubemx can通讯(1)回环模式
stm32 cubemx can通讯(2)过滤器设置说明代码分析
根据前两篇文章已经能够实现can标准帧的收发,但是调用的函数没有标准化和可扩展性。
所以本文讲解bsp,在bsp中已经有了发送函数和接受回调函数的任务映射处理回调函数。
暂时(2023.8.10)还未加入过滤器配置,所以过滤器还是需要在can_init中进行配置。
(2023.9.29)修改文章,加入了cubemx的配置,以及对can的连接。

文件


一、cubemx配置

1.F407ZET6

stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript
stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript

2.F103C8T6

stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript
stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript

二、物理连接【stm32can连接】

系统板上一般不会有can收发器,
所以要自己外置一个,我用的是TJA1050
这个模块的vcc只能接3.3.不要接5v
stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript

一定要注意连接如图
stm32 cubemx can通讯(3)bsp_can,stm32,stm32,前端,javascript
这个和串口的不同,千万不要连反了。

三、bsp

bsp_can.h

#ifndef __BSP_CAN_H
#define __BSP_CAN_H
#include "main.h"

#include "can.h"

uint8_t  CANSend(CAN_HandleTypeDef *hcan,
                               uint32_t Source_ID,
                               uint32_t IDE,
                               uint32_t RTR,
                               uint8_t* Datum,
                               uint8_t DataLength);
															 
typedef struct {
    uint32_t id;
    uint32_t idType;  // CAN_ID_STD or CAN_ID_EXT
    void (*callback)(uint8_t* data);
} CAN_CallbackMapType;

#endif

bsp_can.c

#include "bsp_can.h"


/**
 * 发送CAN数据
 * @param hcan: 使用的CAN句柄
 * @param Source_ID: 消息ID
 * @param IDE: 标识符类型 (CAN_ID_STD 或 CAN_ID_EXT)
 * @param RTR: 消息类型 (CAN_RTR_DATA 或 CAN_RTR_REMOTE)
 * @param Datum: 要发送的数据
 * @param DataLength: 数据长度
 * @return: HAL的状态 (		1 成功 		0 失败			)
 */
#define CAN_MAX_DATA_LENGTH 8
uint8_t  CANSend(CAN_HandleTypeDef *hcan,
                               uint32_t Source_ID,
                               uint32_t IDE,
                               uint32_t RTR,
                               uint8_t* Datum,
                               uint8_t DataLength)
{
    // 参数验证
    if (!hcan || !Datum || 
        (IDE != CAN_ID_STD && IDE != CAN_ID_EXT) || 
        DataLength > CAN_MAX_DATA_LENGTH) 
    {
        return 0;
    }

    CAN_TxHeaderTypeDef TXHeader;  
    uint32_t pTxMailbox = 0;

    if (IDE == CAN_ID_STD) 
    {
        TXHeader.StdId = Source_ID;
    } 
    else 
    {
        TXHeader.ExtId = Source_ID;               
    }

    TXHeader.IDE = IDE;
    TXHeader.DLC = DataLength;
    TXHeader.RTR = RTR;
    TXHeader.TransmitGlobalTime = DISABLE;
		
   HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(hcan, &TXHeader, Datum, &pTxMailbox);
    
    if (status == HAL_OK) 
    {
        return 1;  // 返回1表示成功
    } 
    else 
    {
        return 0;  // 返回0表示失败
    }		
}

/* USER CODE BEGIN mapping_function */
int  cc =0;
// 示例的回调函数
void handle_ID_0x01(uint8_t *data) {
    // 对于ID 0x01的处理代码
	cc=1;
}

void handle_ID_0x02(uint8_t *data) {
    // 对于ID 0x02的处理代码
	cc=2;
}
void handle_ID_0x12345678(uint8_t *data) {
    // 对于ID 0x02的处理代码
	cc=4;
}
// 初始化映射表
CAN_CallbackMapType callbackMap[] = {
    {0x01, CAN_ID_STD, handle_ID_0x01},
    {0x02, CAN_ID_STD, handle_ID_0x02},
    // 添加一个扩展ID的例子
    {0x12345678, CAN_ID_EXT, handle_ID_0x12345678}  
};

/* USER CODE mapping_function */
const uint8_t mapSize = sizeof(callbackMap) / sizeof(CAN_CallbackMapType);

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) 
{
    if(hcan->Instance == CAN1) 
		{
        // 获取数据
        CAN_RxHeaderTypeDef RXHeader;
        uint8_t RXmessage[8];  // 确保这里的数组大小正确
        
        if(HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0, &RXHeader, RXmessage) == HAL_OK) 
				{
            for(uint8_t i = 0; i < mapSize; i++) 
						{
                if(RXHeader.IDE == callbackMap[i].idType && 
                   (RXHeader.IDE == CAN_ID_STD && RXHeader.StdId == callbackMap[i].id || 
                    RXHeader.IDE == CAN_ID_EXT && RXHeader.ExtId == callbackMap[i].id) && 
                   callbackMap[i].callback) 
								{
                    callbackMap[i].callback(RXmessage);
                    break;
                }
            }
        }
    }
}

四、发送如何使用

如果不使用过滤器的话
stm32 cubemx can通讯(2)过滤器设置说明代码分析
就需要在初始化的地方加入 HAL_CAN_Start(&hcan);
因为过滤器那个地方有这句话,而如果不加这句话的话就不能正常发送。

发送函数可以直接调用。

uint8_t TXmessage[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
CANSend(&hcan,0x12,CAN_ID_STD,CAN_RTR_DATA,TXmessage,8);

五、接收如何使用

要使用接收必须先配置过滤器。!!!
我的过滤函数写在can.c中,我发现写在其他地方不行。原因不明待解决

		
	CAN_FilterTypeDef sFilterConfig;
	
	sFilterConfig.FilterActivation = ENABLE;
	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 16-bit列表模式用于标准ID
	sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
// 过滤器匹配0x1
	sFilterConfig.FilterBank = 0;
	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;	
	sFilterConfig.FilterIdHigh = 0x1 << 5;
	sFilterConfig.FilterMaskIdHigh = 0xFFFF;
	if(HAL_CAN_ConfigFilter(&hcan2,&sFilterConfig) != HAL_OK)//初始化过滤器
	{
	Error_Handler();
	}
// 过滤器匹配0x1
	sFilterConfig.FilterBank = 1;
	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;	
	sFilterConfig.FilterIdHigh = 0x2<< 5;
	sFilterConfig.FilterMaskIdHigh = 0xFFFF;
	
	if(HAL_CAN_ConfigFilter(&hcan2,&sFilterConfig) != HAL_OK)//初始化过滤器
	{
	Error_Handler();
	}
	
	
//	HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); 
//	sFilterConfig.FilterActivation = ENABLE;//打开过滤器
//	sFilterConfig.FilterBank = 0;//过滤器0 这里可设0-13
//	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
//	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式

//	sFilterConfig.FilterIdHigh = 0x0000; //设置过滤器ID高16位
//	sFilterConfig.FilterIdLow = 0x0000;//设置过滤器ID低16位
//	sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
//	sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
	
	
	
//	if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
//	{
//	Error_Handler();
//	}
	if(HAL_CAN_Start(&hcan2) != HAL_OK)//打开can
	{
	Error_Handler();
	}
	if(HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
	{
	Error_Handler();
	}

接收函数的回调函数不需要进行修改,当有任务需要处理的时候先写任务处理的回调函数也就是示例代码中的void handle_ID_0x01(uint8_t *data)之类的。
然后再进行初始化映射CAN_CallbackMapType callbackMap[]
所以只需要在/* USER CODE BEGIN mapping_function */之间修改函数即可。其他的不需要更改。文章来源地址https://www.toymoban.com/news/detail-645563.html


总结

到了这里,关于stm32 cubemx can通讯(3)bsp_can的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32——CAN通讯

    can通讯传输的是一种 差分信号 ,关于具体的硬件电路略。 1、发送流程 前置工作:如 时钟的开启、引脚的配置; CAN邮箱和模式等配置 参考下面或HAL库选择 选择一个 空置 的邮箱(判断空置:CAN_TSR的TMEx位); 在这个空置邮箱中按数据帧格式设置ID、数据长度以及要发送的数

    2024年03月09日
    浏览(48)
  • CAN总线学习笔记 | STM32CubeMX配置CAN环回测试

    CAN基础知识介绍文中介绍了CAN协议的基础知识,以及STM32F4芯片的CAN控制器相关知识,下面将通过实例,利用STM32CubeMX图形化配置工具,来实现CAN通讯的环回测试 CAN是挂载在APB1总线上,设置PCLK1时钟频率到最大45MHz 激活CAN1,配置位时序参数,其他基本参数以及工作模式(此处

    2024年02月11日
    浏览(35)
  • STM32 CAN通讯实验程序

    目录 STM32 CAN通讯实验 CAN硬件原理图 CAN外设原理图 TJA1050T硬件描述 实验线路图 回环实验 CAN头文件配置  CAN_GPIO_Config初始化 CAN初始化结构体 CAN筛选器结构体  接收中断优先级配置 接收中断函数 main文件 实验现象 补充 CAN外设原理图 野火STM32F103ZET6霸道板载原理图 我们的开发

    2024年02月15日
    浏览(34)
  • 野火STM32电机系列(三)Cubemx配置CAN通信

    CAN接口: PI9 PB9 1.配置CAN 通信参数 由于F4的 CAN外设挂载在APB1上,时钟配置后APB1的时钟速率为42MHz,目标通信速率为1000KHz,由公式: BaudRate = 1/NominalBitTime NominalBitTime = 1tq + tBS1 +tBS2 设置参数如下: CAN时钟分频参数为7,BS1为4,BS2为1,CAN模式为Nomal模式。 生成工程 在can.c中添加

    2024年02月11日
    浏览(45)
  • STM32 CAN使用记录:FDCAN基础通讯

    CAN是非常常用的一种数据总线,被广泛用在各种车辆系统中。这篇文章将对STM32中FDCAN的使用做个示例。 CAN的一些基础介绍与使用可以参考下面文章: 《CAN基础概念》https://blog.csdn.net/Naisu_kun/article/details/132814079 《STM32 CAN使用记录:bxCAN基础通讯》https://blog.csdn.net/Naisu_kun/arti

    2024年02月07日
    浏览(55)
  • 【通讯协议备忘录】stm32的CAN外设

    CAN的报文结构: 静默模式: 环回模式: 环回静默模式: 选好对应GPIO即可,APB1 36 Mhz, 500kbps: 不配置过滤器亦可使用 根据不同位长模式,每个过滤器组,32位模式可以配置一个屏蔽掩码或两个白名单列表,16位模式翻倍 标准帧和扩展帧的ID长度分别为11比特和29比特,通过移位

    2024年02月16日
    浏览(40)
  • 基于STM32F1以及STM32CubeMx实现串口中断通讯(字符串发送与接收)

    首先选好自己的板子并打开软件设置,本实验基于STM32F103ZET6实现,打开软件后如图: 打开外部高速晶振,然后接着配置时钟: 将时钟频率修改为72MHz,接着设置接线方式为SW 接下来需要使用串口中断通讯,打开我们的串口设置并打开中断 这里波特率设置为115200,数据位为

    2024年02月09日
    浏览(44)
  • STM32 CAN通讯滤波器几种模式的设置

    1. 32位过滤器-标识符屏蔽模式(一组筛选ID)  2. 32位过滤器-标识符列表模式(2个筛选ID)  3. 16位过滤器-标识符屏蔽模式(2组筛选ID)  4. 16位过滤器-标识符列表模式(4个筛选ID)  1. 32位过滤器-标识符屏蔽模式(一组筛选ID) 2. 32位过滤器-标识符列表模式(2个筛选ID)  

    2024年02月13日
    浏览(37)
  • STM32单片机CAN通讯连续发送多包数据,发生丢包现象

    使用例程连续发送两三包数据时没有问题,发送多包数据时,发现丢包现象; 例程代码如下: CAN_TxStatus_Failed :状态标志位,不足以判断发送完成,当发送多个数据包时,就会产生问题,修改代码如下: 改成 CAN_TxStatus_Ok 发送成功标志位后,可以连续发送多包数据

    2024年02月16日
    浏览(37)
  • STM32F103C8T6实现CAN通讯与直流编码电机转速闭环控制

    本次实验目的是通过CAN发送目标转速与转向信息,接收方在接到CAN数据流后开始对直流编码电机进行转速闭环控制。我会尽量说清每个函数,注释每一句代码,希望能对大家有所帮助。 CAN通讯基于STM32自带CAN通讯模块,配合库函数使用十分方便。关于CAN通讯可以参考站内大佬

    2023年04月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包