STM32之CAN外设

news2024/10/12 5:47:21

相信大家在学习STM32系列的单片机时,在翻阅芯片的数据手册时,都会看到这么一个寄存器外设——CAN外设寄存器。那么,大家知道这个外设的工作原理以及该如何使用吗?这节的内容将会详细介绍STM32上的CAN外设,文章结尾附有相关代码帮助大家更好地掌握。

1.CAN外设(CAN控制器)介绍

STM32的芯片中具有bxCAN控制器(Basic Extended CAN),它支持CAN协议2.0A 和2.0B Active标准。(CAN2.0A只能处理标准数据帧且扩展帧的内容会织别错误。而CAN2.0 B Active可以处理标准数据帧和扩展数据帧。CAN2.0 B Passive只能处理标准数据帧而扩展帧的内容会被忽略)。

该CAN控制器支持最高的通讯速率为1Mb/s;可以自动地接收和发送CAN报文,支持使用标准ID和扩展ID的报文;外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有2个3级深度的接收FIFO,可使用过滤功能只接收或不接收某些ID号的报文;可配置成自动重发;不支持使用DMA进行数据收发。

2.CAN控制器的3种工作模式

CAN控制器有3种工作模式:初始化模式,正常模式,睡眠模式。

上电复位后CAN控制器默认会进入睡眠模式,作用是降低功耗。当需要将进行初始的时候(配置寄存器),会进入初始化模式。当需要通讯的时候,就进入正常模式。

3.CAN控制器的3种测试模式

有3种测试模式:静默模式、环回模式、环回静默模式。当控制器进入初始化模式的时候才可以配置测试模式 。

静默模式可以用于检测总线的数据流量。环回模式可以用于自检(影响总线)。环回静默也是用于自检,不会影响到总线。

4.功能框图 

 ​​​​​​​主动内核

含各种控制/状态/配置寄存器,可以配置模式、波特率等。在STM32CubeMx中可以非常方便的配置。

​​​​​​​发送邮箱

用来缓存待发送的报文,最多可以缓存3个报文。发送调度决定报文的发送顺序。

​​​​​​​接收FIFO

共有2个接收FIFO,每个FIFO都可以存放3个完整的报文。它们完全由硬件来管理。从而节省了CPU的处理负荷,简化了软件并保证了数据的一致性。应用程序只能通过读取FIFO输出邮箱,来读取FIFO中最先收到的报文。

​​​​​​​接收滤波器(过滤器)

做用:对接到的报文进行过滤。最后放入FIFO 0或FIFO 1。

当总线上报文数据量很大时,总线上的设备会频繁获取报文,占用CPU。过滤器的存在,选择性接收有效报文,减轻系统负担。

有2种过滤模式:

  1. 标识符列表模式,它把要接收报文的ID列成一个表,要求报文ID与列表中的某一个标识符完全相同才可以接收,可以理解为白名单管理。
  2. 掩码模式(屏蔽位模式),它把可接收报文ID的某几位作为列表,这几位被称为掩码,可以把它理解成关键字搜索,只要掩码(关键字)相同,就符合要求,报文就会被保存到接收FIFO。

如果使能了筛选器,且报文的ID与所有筛选器的配置都不匹配,CAN外设会丢弃该报文,不存入接收FIFO。每个CAN提供了14个位宽可变的、可配置的过滤器组(13~0)。每个过滤器组x由2个32位寄存器,CAN_FxR1和 CAN_FxR2组成。

5.CAN通讯实验2:双击测试 :一发一收

5.1需求描述

使用2块STM32开发板实现CAN消息的发送和接收。一个发送数据,另外一个接收数据。

​​​​​​​5.2硬件设计

需要把2块开发的CAN_High连起来,CAN_Low连起来。连接如图所示。

​​​​​​​5.3软件设计(寄存器)

复制CAN通信案例1的寄存器版本工程2,一个用于发送,一个用于接收

​​​​​​​can.c注释掉下面2行代码,其他不用做任何变化。

/* 4.5 配置位时序寄存器 */
    /* 4.5.1 静默模式 用于调试 */
    // CAN1->BTR |= CAN_BTR_SILM;   
    /* 4.5.2 回环模式 用于调试 */
//   CAN1->BTR |= CAN_BTR_LBKM;

 ​​​​​​​main.c  发送

用于发送的工程只保留发送的代码即可。

#include "stm32f10x.h" // Device header
#include "usart.h"
#include "Delay.h"
#include "can.h"
#include "string.h"

int main(void)
{
    usart1_init();
    printf("尚硅谷 CAN 通讯实验: 发送节点 寄存器版\r\n");
    CAN_Init();
    printf("CAN 初始化配置完成...\r\n");

    uint16_t stdId = 123;
    uint8_t *tData = "abcdef";

    while (1)
    {
        CAN_SendMsg(stdId, tData, strlen((char *)tData));
        printf("发送完毕...\r\n");
        Delay_s(3);
    }
}

 ​​​​​​​main.c  接收

用于接收的工程只保留接收的代码即可。

#include "stm32f10x.h" // Device header
#include "usart.h"
#include "Delay.h"
#include "can.h"
#include "string.h"

int main(void)
{
    usart1_init();
    printf("尚硅谷 CAN 通讯实验: 接收节点 寄存器版\r\n");
    CAN_Init();
    printf("CAN 初始化配置完成...\r\n");

        RxDataStruct rxDataStruct[8];
    uint8_t rxMsgCount;
    while (1)
    {
        /* 1. 接收数据 */
        CAN_ReceiveMsg(rxDataStruct, &rxMsgCount);
        /* 2. 输出消息 */
        uint8_t i;
        for (i = 0; i < rxMsgCount; i++)
        {
            RxDataStruct msg = rxDataStruct[i];
            printf("stdId = %d, length = %d, msgData = %s\r\n", msg.stdId, msg.length, msg.data);
        }
    }
}

 5.4软件设计(HAL库)

CubeMx设置

拷贝CAN通信实验1的HAL库版本工程2次。一个用于发送,一个用于接收。重新打开每个工程,把Test Mode改成 Normal即可,其他不用改变。然后重新生成代码。

 ​​​​​​​main.c 发送

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_CAN_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */
    /* 1. 配置过滤器 */
    CAN_Filter_Config();
    /* 2. 启动CAN总线 */
    HAL_CAN_Start(&hcan);
    printf("尚硅谷 CAN 发送实验...\r\n");

    while (1)
    {
        uint16_t stdId = 0x011;
        uint8_t *tData = "abcdefg";
        CAN_SendMsg(stdId, tData, strlen((char *)tData));
        printf("发送完毕...\r\n");
        HAL_Delay(300);
    }
}

 ​​​​​​​main.c 接收

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_CAN_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */
    /* 1. 配置过滤器 */
    CAN_Filter_Config();
    /* 2. 启动CAN总线 */
    HAL_CAN_Start(&hcan);
    printf("尚硅谷 CAN 接收 实验...\r\n");
    /* 4. 接收数据 */
    RxDataStruct rxDataStruct[8];
    uint8_t rxMsgCount;
    while (1)
    {
        CAN_ReceiveMsg(rxDataStruct, &rxMsgCount);
        /* 5. 输出消息 */
        uint8_t i;
        for (i = 0; i < rxMsgCount; i++)
        {
            RxDataStruct msg = rxDataStruct[i];
            printf("stdId = %d, length = %d, msgData = %s\r\n", msg.stdId, msg.length, msg.data);
        }
    }
}

好了,以上就完成了两个32单片机之间的一发一收的整个流程了 

 

 

 

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

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

相关文章

气象数据三维可视化的实现原理及代码

气象数据三维可视化是一种使用三维图形技术来呈现和分析气象数据的方法。通过三维可视化&#xff0c;用户可以更直观地观察气象数据的空间分布、变化趋势以及天气现象的复杂结构。这种技术广泛应用于气象预报、科学研究以及环境监测等领域。 本文将介绍气象数据三维可视化的基…

未来战争中的指控体系不仅是分布式的

指控体系&#xff0c;作为军事指挥与控制的重要组成部分&#xff0c;经历了从传统的集权指挥向现代分布式指挥的转变。历史上&#xff0c;战争指挥体系主要依赖于集中式指挥官的决策&#xff0c;信息流动缓慢&#xff0c;决策过程受到地理位置、通信手段等多种因素的制约。随着…

数据库实例

例3.5建立一个“学生”表student create table student(sno char(9) primary key,sname char(20) unique,ssex char(2),sage smallint,sdept char(20)); 例3.6建立一个“课程”表course create table course(cno char(4) primary key,cname char(40) not null,cpno char(4),…

保姆级教程 | VMD输出局部结构及利用TkConsole实现旋转

背景 由于课题需要,现需要展示lammps模拟轨迹中的局部结构(主要是想可视化这里的结果:保姆级教程 | 输出分子动力学轨迹文件输出特定原子范围内的化学环境),因为ovito效果有点笨笨的,所以我这里选用VMD软件为例进行操作,效果图(超级好看夸夸): (说明:主要的分子构…

计算机毕业设计 | SSM 旅游网站后台管理系统(附源码)

1&#xff0c;概述 1.1 背景分析 随着人们生活水平的提高和对休闲旅游的日益重视&#xff0c;旅游业已成为全球最大的经济产业之一。越来越多的人选择通过在线方式进行旅行预订&#xff0c;这种趋势为旅游网站提供了巨大的商机。用户体验是决定旅游网站成功与否的关键因素。良…

vue代码中关于字符串对比的实现

常见的数据比较都只限制于数字比较的比较&#xff0c;但是现在遇到一个框架他会自动将所有传输过来的值转化为字符串形式&#xff0c;导致在比较的时候无法进入到表单校验的代码中去 1.使用Number函数 2.使用 号运算符,都可以实现

python networkx 计算路径A*

import matplotlib.pyplot as plt # 导入 Matplotlib 工具包 import networkx as nx # 导入 NetworkX 工具包 from typing import List# 初始化空的无向图 graph nx.Graph() # 向图中添加多条赋权边: (node1,node2,weight) graph.add_weighted_edges_from([(1, 2, 50),(1, 3…

智能扭矩系统在制造领域应用_SunTorque

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在当今高度自动化和智能化的制造领域&#xff0c;各种先进技术不断涌现&#xff0c;为提高生产效率、保证产品质量和降低成本提供了有力支持。智能扭矩系统作为其中…

【电子电力】基于DSP28335+DSP28035的三相三电平大功率并网逆变器程序代码

摘要 本文介绍了基于DSP28335和DSP28035的三相三电平大功率并网逆变器设计和实现。通过DSP控制器对三电平逆变器的精确控制&#xff0c;实现了逆变器与电网的并网控制&#xff0c;保证了系统的高效稳定运行。该设计主要应用于光伏发电和风力发电系统中的并网发电部分。本文通过…

在AI大模型时代遨游,你不得不知道的一些事

用户到底为什么而买单/产品和研发要抛弃的历史包袱 在大模型时代之前&#xff0c;其实企业和企业之间的软件产品壁垒来自两个地方&#xff1a; 交互&#xff0c;让用户用起来感觉舒服。打磨&#xff0c;我花了五年修复了用户遇到的一万个bug,所以我的产品比你好。 但是无论如何…

如何使用flutter doctor命令检测环境是否配置成功

Flutter Windows Android环境搭建 真机调试学习地址&#xff1a; 17 Flutter介绍-Flutter Windows Android环境搭建 真机调试 如何使用flutter doctor命令检测环境是否配置成功&#xff0c;详细步骤如下&#xff1a; 第一次执行可能会提示下面错误&#xff1a; 1、错误一&am…

建站:腾讯云+宝塔linux+xftp

1.首先&#xff0c;控制台&#xff0c;服务器 2.服务器-网络与域名-ip地址&#xff0c;能看到公网地址 3.宝塔Linux面板-网站-添加站点 4.填写域名会自动生成 ftp 帐号密码 域名可以加上端口&#xff0c;端口号可以写大点 5.xftp新建会话 主机地址&#xff1a;腾讯云拿到的公…

直流有刷电机驱动芯片:【TOSHIBA:TB6612】

Toshiba TB6612是是东芝半导体的一款驱动电机的IC。一个TB6612FNG可以驱动两个电机&#xff0c;每一个驱动都有两个逻辑输入引脚&#xff0c;一个输出引脚和一个PWM引脚。可以通过给两个逻辑输入引脚不同的电平来控制电机的运行状态&#xff0c;通过PWM输入引脚实现电机调速。 …

怎么看待数字化转型是大势所趋?

怎么看到数字化转型是大势所趋&#xff1f;下面我结合最新数据给大家讲明白这个事。 近日&#xff0c;我通过大量的数据相关性分析&#xff0c;有了一些关键发现。 【数字化转型】之所以势在必行&#xff0c;主要是因为数字化转型为各个国家数字经济发展提供了重要的参考依据。…

R2:RNN-心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、实验目的&#xff1a; 本地读取并加载数据。了解循环神经网络&#xff08;RNN&#xff09;的构建过程测试集accuracy到达87% 拔高&#xff1a;测试集accur…

腾讯云Android 相关

集成遇到异常怎么办&#xff1f; 您可以使用 armeabi 和 armeabi-v7a 架构。 如上图所示&#xff0c;请在app的 build.gradle 中指定 abiFilters 为“armeabi”。 功能模块升级后&#xff0c;短视频 SDK 的功能不能使用&#xff1f; 1. 如果使用的是 androidstudio&#xff0…

2024Selenium自动化常见问题!

"NoSuchElementException"异常&#xff1a; 确保使用了正确的选择器来定位元素。可以使用id、class、XPath或CSS选择器等。 可以尝试使用find_elements方法来查找元素列表&#xff0c;并检查列表的长度来判断元素是否存在。 使用显式等待&#xff08;WebDriverWait…

考研编程:10.11 回文数 水仙花 生成一定范围内的随机数 求二叉树宽度

回文数 #include <stdio.h>int main(){int a,b,c0,sum;scanf("%d",&a);ba;while(b!0){c b%10 c*10;b b/10;}if(ca){printf("yes");}return 0; } 水仙花 #include <stdio.h> #include <math.h> int main(){int a,b,c0,sum;scan…

内嵌服务器Netty Http Server

内嵌式服务器不需要我们单独部署&#xff0c;列如SpringBoot默认内嵌服务器Tomcat,它运行在服务内部。使用Netty 编写一个 Http 服务器的程序&#xff0c;类似SpringMvc处理http请求那样。举例&#xff1a;xxl-job项目的核心包没有SpringMvc的Controller层&#xff0c;客户端却…

css多层嵌套折叠

<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>美观的纯 CSS 折叠列表</title><style>b…