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

news/2024/12/29 2:36:44/

笔者来聊聊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;elsecan1_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;elsecan1_broadcast_flag  = FALSE:}elsebreak;}
}

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

3、参考


http://www.ppmy.cn/news/64026.html

相关文章

国产自研数据库是更新换代首选

伴随着数字经济的高速发展&#xff0c;越来越多的企业都意识到了数据是现代企业最具价值的资产。而与之相对应的是&#xff0c;数据库的重要性也随之水涨船高。 近年来&#xff0c;在席卷全球的云原生大潮中&#xff0c;数据库产业迎来了极为重要的转型升级。特别是在自主创新的…

Melis4.0[D1s]:8.显示测试:图片格式和透明度

文章目录 1.准备素材图片1.1 测试图片像素格式的软件RawViewer.exe1.1.1 使用方法 1.2 自己生成测试图片 2.D1s显示引擎介绍&#xff08;不保证正确&#xff09;2.1 D1s 可以有2个独立的display device输出&#xff08;可以同时接2个显示器&#xff09;2.2 D1s 的 DISP0 有2个通…

项目实战-redis

springboot集成redis 步骤 1、添加Redis依赖项&#xff1a;在项目的pom.xml文件中添加以下依赖项 <!-- spring data redis 依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis<…

关于ADC的笔记1

ADC&#xff0c;全称Anlog-to-Digital Converter&#xff0c;模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件&#xff0c;我们能通过ADC将外界的电压值读入我们的单片机中. 常见的ADC有两种 1.并联比较型&#xff1a; 它的优点是转换速度最快&#x…

操作系统相关问题——应用程序和操作系统怎么配合

应用程序和操作系统都是软件&#xff0c; CPU会将它们一视同仁&#xff0c;甚至CPU不知道自己在执行的程序是操作系统还是一般应用软件。CPU只知道去cs:ip寄存器中指向的内存取出指令并执行&#xff0c;它不知道什么是操作系统。 编程语言其实只是编译器和大家的约定&#xff…

Django框架之视图HttpResponse 对象

本篇文章主要内容为&#xff1a;视图中HttpResponse对象的属性、方法及json、redirect子类包含使用cookie使用、跳转、json返回的示例。 概述 HttpResponse对象是对用户访问的响应&#xff0c;与HttpRequest对象由django创建&#xff0c;HttpResponse对象是由开发人员创建。Ht…

微服务高频面试题

1、Spring Cloud 5大组件有哪些&#xff1f; 早期我们一般认为的Spring Cloud五大组件是 Eureka : 注册中心Ribbon : 负载均衡Feign : 远程调用Hystrix : 服务熔断Zuul/Gateway : 网关 随着SpringCloudAlibba在国内兴起 , 我们项目中使用了一些阿里巴巴的组件 注册中心/配置…

1960-2014年各国二氧化碳排放量(人均公吨数)

1960&#xff0d;2014年各国二氧化碳排放量&#xff08;人均公吨数&#xff09;&#xff08;世界发展指标, 2019年12月更新&#xff09; 1、来源&#xff1a;世界发展指标 2、时间&#xff1a;1960&#xff0d;2014年 3、范围&#xff1a;世界各国 4、指标&#xff1a; 二氧…