ARM学习(21)STM32 外设Can的认识与驱动编写

news2024/11/25 18:26:46

笔者来聊聊can的认识以及can接收数据的驱动编写

1、STM32 Can 外设的认识

Can的特性就不多说了,主要来聊聊can的一些标识符以及收发状态。can有一套收发机制,发送和接收都有硬件缓存,叫邮箱,通过下面的图可以看出,下面这张图很经典,被各大网站和博客上面引用。
在这里插入图片描述
发送时,有三个报文邮箱缓存,接收时有两个fifo缓存,每个fifo有三个邮箱。

从上面图还可以看出,can数据接收到fifo,是经过滤波器过滤才可以到fifo,总共有27个过滤器(互联型,其他只有13个)每个标识符经过一个滤波器后就可以到接收fifo。

1.1、发送过程

3个发送报文缓存邮箱,发送时如果有之前的报文没发送出去,会缓存在邮箱里面,等待发送。

之所以用邮箱,是因为邮箱不仅可以有优先级发送,也可以顺序发送(fifo)

发送时的几个状态:

  • 空状态(TME=1):邮箱空闲状态,此时肯定能请求成功,假如此时3个邮箱都不空闲,可能请求失败
  • 挂起状态(TME=0 RQCP=0 TXOK=0):TXRQ=1,请求发送数据,此时等待邮箱成为最高优先级然后发送数据(can标识符低的优先发送),因为可能存在多个邮箱数据等待发送;此时也有情况发生邮箱已满,此时就只能等待,后面发送数据,那前面状态则不变。
  • 已安排状态(TME=0 RQCP=0 TXOK=0):邮箱成为最高优先级,此时准备发送数据,准备把can数据扔到总线上面(可能此时can总线上面正在繁忙,所以要等待can总线空闲)
  • 发送状态(TME=0 RQCP=0 TXOK=0):此时can数据发送到总线上面;有自动重发选项,可以一直发送(等can总线空闲之后);也有终止请求, 可以终止发送,则会存在多种情况。
  • 发送成功(TME=1 RQCP=1 TXOK=1):数据发送成功
  • 发送失败(TME=1 RQCP=1 TXOK=0):数据发送失败,
    在这里插入图片描述

1.2、标识符过滤

can总线上面一般会有多个设备,那么总线上的数据,多个设备都会收到,那么就需要指明“地址”进行过滤掉其他数据。

can里面一般会用标识符规则来过滤数据,会根据此标识符确定是否接收该数据,一般不说标识符是can的节点,因为标识符可修改,或者该标识符可以过滤筛选一组can数据,

过滤通常有两种方法,标识符列表模式,标识符掩码模式

  • 标识符列表模式:接收的标识符和过滤器指定标识符必须完全匹配,则会被过滤出来,送到fifo邮箱。
  • 标识符掩码模式:接收的标识符和过滤器指定的标识符部分位匹配则就可以被过滤出来,送到fifo邮箱。

换句话说:筛选一组标识符,则选用掩码模式,筛选特定标识符,则选用标识符列表模式。

每个过滤器有两个寄存器可用,均是32位,可以拆分为2个16位的寄存器来使用,则相当于多了1过滤器来使用。

在这里插入图片描述
初步看上面这张表,笔者也看的不是很懂,后面仔细研究过后,其实这是一个过滤器的多种配置,

  • 32位模式下:
    • 掩码模式:标识符寄存器和掩码寄存器为一个过滤器,以标识符寄存器的值为准(笔者亲测),所以其过滤编号也是1个
    • 列表模式:两个寄存器分别代表一个ID,所以是两个过滤器,标识符寄存器在前,掩码在后(过滤器编号)。
  • 16位模式下:
    • 掩码模式:两个寄存器的低16位和高16位各组成一个32位,总共作为两个过滤器,
    • 列表模式:两个寄存器的高低16位都组成一个过滤器,总共作为四个过滤器。

然后接下来这张表就可以看懂了。多个过滤器的一种配置方式,以及编号,该编号可以再收到数据的时候打印出来,可以判断是哪个过滤器接收到的数据。

注意:

  • 只要一个过滤器满足条件就可以过滤到FIFO中,不是同时满足所有的过滤器的要求。
  • 如果同时满足多个筛选器,有优先级规则,
    • 32 位筛选器优先于 16 位筛选器。
    • 对于尺度相等的筛选器, 标识符列表模式优先于标识符掩码模式。
    • 对于尺度和模式均相等的筛选器,则按筛选器编号确定优先级(编号越低,优先级越高)

在这里插入图片描述

typedef struct 
{
	uint32 t stdid;
	uint32 t ExtId;
	uint8 t IDE;
	uint8 t RTR;
	uint8 t DLC;
	uint8 t Data[8];
	uint8 t FMI;
}CanRxMsg;
/* CanRxMsg.FMI  就是指示了哪个过滤器的过滤出来的该数据,

1.3、接收过程

接收时上述已经提过,有两个fifo,每个fifo有3个邮箱,那么总共可以存储6个报文(硬件存储)。

在这里插入图片描述
共有三个状态:有报文,报文满,报文溢出。
FMP:指示了当前有多少报文
FOVR:指示是否溢出,
需要注意的是:

  • 两个fifo是独立的,不会说是FIFO0满了,放到FIFO1,这是由过滤器决定的,满足哪个过滤器,就会放到该fifo,即使是溢出了。
  • 所以接收报文的时候,每次缓存最多就是3个报文,再多就溢出了,如果需要更大缓存, 可以软件上面加缓存,下文介绍。
  • 两个fifo,对应的是两个接收中断。

2、STM32 Can驱动函数的编写

can中断接收数据

CanRxMsg Can1RxMessage;
u8 can1_data_flag;
u8 can1_data_len;
u8 can1_broadcast_flag;
void CAN1_RX0_IROHandler(void)
{
	/*receive a can messaae*/
	CAN_Receive(CAN1,CAN FIFO,&Can1RxMessage);
	can1_data_flag = TRUE;
	can1_data_len = Can1RxMessage.DLC;
	/*check if is broadcast data */
	if(CAN_BROADCAST_CMD== Can1RxMessage.ExtId )
		can1_broadcast_flag = TRUE;
	else
		can1_broadcast_flag = FALSE:
	}
	CAN_EIFORelease(CAN1, CAN_FIFO):
	CAN_IT_Config(CAN1, CAN_IT_FMP0, DISABLE);
}

上面驱动程序只是一个简单的示例来接收can的程序,其有以下缺点:

  • 接收一个8字节,然后处理一次,然后才再可以接收,效率低,没有发挥中断的优势,将中断和处理串起来。
  • 没有发挥硬件fifo的作用(3个)
  • 超过3个fifo的数据来临时,没有缓存能力

软件fifo接收数据。

CanRxMsg Can1RxMessage;
u8 can_fifo_index ;
u8 can_rx_fifo[1024];
u8 can1_data_flag ;
u8 can1_broadcast_flag  ;
void CAN1_RX0_IRQHandler(void)
{
	if(CAN_GetFlagstatus(CAN1,CAN_FLAG_FOV0))
		printf("OVER CAN\r\n");
	u8 fifo_count;/* 3 hardware fifo for can rx */
	for(fifo_count=0; fifo_count<3; fifo_count++)
	{
		if(CAN_GetFlagstatus(CAN1,CAN_FLAG_FMPO))
		{
			/*receive a can data*/
			if(can_fifo_index >= CAN_RX_FIFO_MAX_SIZE) /*1024*/
			{
				printf("over 1k \r\n");
				CAN_ITConfig(CAN1, CAN_IT_FMPO, DISABLE);
				break;
			}
			else
			{
				CAN Receive(CAN1, CAN FIFO, &Can1RxMessage);
				memcpy(&can_rx_fifo[can_fifo_index], (u8 *)8Can1RxMessage.Data[0], Can1RxMessage.DLC);
				can_fifo_index += Can1RxMessage.DLC;
				CAN_FIFORelease(CAN1,CAN_FIFOO);
			}
			can1_data_flag = TRUE;
			/*check if is broadcast data */
			if(CAN_BROADCAST_CMD == Can1RxMessage.ExtId)
				can1_broadcast_flag  = TRUE;
			else
				can1_broadcast_flag  = FALSE:
		}
		else
			break;
	}
}

以上代码也只是demo,相应的错误处理没有增加,在溢出时,只是增加了打印,比如可以增加标志位,然后将其传递出去。

3、参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32学习笔记 -- ESP32-S3 使用外部 PSRAM

ESP32-S3是乐鑫科技推出的一款专为物联网而生的SOC芯片,该芯片同时支持WIFI和BLE蓝牙功能,集成了高性能的Xtensa 32位LX7双核处理器,最高主频可达240MHz。 根据乐鑫官方资料介绍,该芯片内置512KB SRAM片上内存,并且具有45个可编程GPIO管脚和丰富的通信接口。为了更好地扩…

Flask框架之路由与蓝图的使用

路由与蓝图 路由路由概述路由的基本使用查看路由信息url_map对象命令行方式 HTTP请求方法 蓝图概述蓝图的基本使用蓝图的拆分指定蓝图的url前缀蓝图构造URL蓝图静态文件蓝图模板目录 路由 路由概述 在Flask中&#xff0c;路由用于将HTTP请求与特定的Python函数相匹配。通过定义…

K8s-Pod概念、创建及常用命令

文章目录 一、Pod概念1、Pod是什么&#xff1f;2、Pod网络共享实现方式3、Pod存储共享方式4、创建Pod整体流程 二、使用YAML文件定义Pod资源1、Pod资源清单YAML文件书写技巧1. YAML语法格式&#xff1a;2. 配置Linux tab缩进两个空格3. 使用kubectl explain帮助命令 2、创建Pod…

章节2:01-Java序列化和反序列化

章节2&#xff1a;01-Java序列化和反序列化 01-Java序列化和反序列化 基础环境 JDK解压版&#xff1a;包含Java运行时环境 IDEA&#xff1a;开发工具 Maven&#xff1a;jar包依赖管理 Tomcat&#xff1a;HTTP服务器 Burp Suite&#xff1a;发送HTTP请求 Kali&#xff1…

ANSYS APDL谐响应分析——悬臂梁的频响函数计算以及幅值、角度(相位)、分贝计算

问题描述 研究一根悬臂梁&#xff0c;材质为钢材。长度 L 2 L2 L2 米&#xff1b;截面为矩形&#xff0c;矩形的长度为 H 5 c m H 5cm H5cm&#xff0c;宽度为 B 2 c m B 2cm B2cm 。 建模思路&#xff1a; 先建立节点&#xff0c;然后用节点生成单元。使用n命令&…

book-riscv-rev1.pdf 翻译(自用,更新完成)第一章 操作系统接口

Job of operating system: 操作系统使得多个程序分享一台计算机&#xff0c;提供一系列仅靠硬件无法支持的服务。 管理与抽象低级别硬件&#xff08;如&#xff1a;文件处理程序不需要关注使用哪种硬盘&#xff09;使得多个程序分享硬件&#xff08;programs that can run at…

797. 差分(C++和Python3)——2023.5.7打卡

文章目录 QuestionIdeasCode Question 输入一个长度为 n 的整数序列。 接下来输入 m 个操作&#xff0c;每个操作包含三个整数 l,r,c &#xff0c;表示将序列中 [l,r] 之间的每个数加上 c 。 请你输出进行完所有操作后的序列。 输入格式 第一行包含两个整数 n 和 m 。 第二…

高性能流媒体硬解码

目录 高性能流媒体硬解码前言1. What、Why and How1.1 What1.2 Why&#xff1f;1.3 How&#xff1f; 2. 离散傅里叶变换(DFT)2.1 JPEG编码2.2 哈夫曼编码(Huffman Coding) 3. 视频流媒体前置知识3.1 视频文件的构成3.2 视频的编码与封装3.3 H264编码的分层3.4 RTSP之RTP(Real-t…

【clang】安装clang编译器并将linux默认编译器改为clang

目录 省心操作法手动安装 本文是他人智慧的总结个人实践。 省心操作法 缺点&#xff1a; clang版本不能自己选择&#xff1b;我的系统是ubuntu 20&#xff0c;安装后是clang10.0版本 优点&#xff1a;省心&#xff0c;基本不会踩坑 手动安装 参考这篇文章ubuntu20.04 安装cl…

RabbitMQ --- 死信交换机

一、简介 1.1、什么是死信交换机 什么是死信&#xff1f; 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff08;dead letter&#xff09;&#xff1a; 消费者使用basic.reject或 basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false…

超详细-自动化测试从选型到落地,2023年我从10k涨到了18k*14薪...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

系统集成项目管理工程师 下午 真题 及考点(2021年上下半年)

文章目录 2021年下半年试题一&#xff1a;第18章 项目风险管理&#xff0c;风险应对策略&#xff0c;风险的性质&#xff08;客观、偶然、相对、社会、不确定&#xff09;试题二&#xff1a;第9章 项目成本管理&#xff0c;执行绩效&#xff08;即CV和SV&#xff09;&#xff0…

HAL库版FreeRTOS(中)

目录 FreeRTOS 任务切换PendSV 异常PendSV 中断服务函数FreeRTOS 确定下一个要运行的任务函数vTaskSwitchContext()函数taskSELECT_HIGHEST_PRIORITY_TASK() PendSV 异常何时触发FreeRTOS 时间片调度实验功能设计软件设计下载验证 FreeRTOS 内核控制函数FreeRTOS 内核控制函数预…

蓝牙设备的名称与MAC地址及UUID

每个蓝牙设备都具有各自的地址和名称&#xff0c;他们之间通过唯一通过地址和名称进行数据交互。本文详细讲述了蓝牙设备的名称和地址的格式及作用。 名称 蓝牙设备具有各自的名称&#xff0c;通常为字母与数字的组合. MAC地址 与Ethernet相同&#xff0c;MAC地址为48bit的…

VTK安装路径检查

/usr/include/vtk-7.1——————VTK头文件

番剧更新表及番剧详情数据库

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 该项目立足于目前各大平台网站的番剧信息较为分散&#xff0c;用户需要辗转多个平台才能获取较为完整的番剧信息的背景下&#xff0c;实现了各大平台网站番剧信息的整合。将各大平台网站的番剧更新信息及番剧详情信息整合制表…

MATLAB 之 基本概述

文章目录 一、MATLAB 主要功能1. 数值计算功能2. 符号计算功能3. 绘图功能4. 程序设计语言功能5. 工具箱的扩展功能 二、MATLAB 操作界面1. 主窗口2. 命令行窗口3. 当前文件夹窗口4. 工作区窗口5. 搜索路径 三、MATLAB 基本操作1. 交互式命令操作1.1 命令行1.2 续行符1.3 命令行…

开关电源基础01:电源变换器基础(1)-关于缘起

说在开头 我相信各位胖友们通过对《阻容感基础》&#xff0c;《信号完整性基础》以及《半导体器件基础》艰苦卓绝地钻研&#xff0c;已为 “硬功夫” 这门绝世武功&#xff0c;打下了坚实的入门基础&#xff0c;入门之日简直就是指日可待&#xff08;我xxx&#xff0c;都半年了…

【数据结构】单链表详解

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C语言和数据结构 &#x1f33c;博客专栏&#xff1a;数据结构 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&…

阿里云服务器镜像系统怎么选择?超详细教程

阿里云服务器镜像怎么选择&#xff1f;云服务器操作系统镜像分为Linux和Windows两大类&#xff0c;Linux可以选择Alibaba Cloud Linux&#xff0c;Windows可以选择Windows Server 2022数据中心版64位中文版&#xff0c;阿里云百科来详细说下阿里云服务器操作系统有哪些&#xf…