STM32之CAN外设

相信大家在学习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单片机之间的一发一收的整个流程了 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

树的中心——dfs

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e510, M N*2; int h[N], e[M], ne[M], idx; int n; int ans 2e9; bool st[N]; void add(int a, int b) // 添加一条边a->b {e[idx] b, ne[idx] h[a], h[a] idx ; } int dfs(int u) {int…

系统移植一

使用设备是fs4412开发板 一、系统移植 系统移植是将一个操作系统或软件从一个硬件平台或处理器架构转移到另一个平台的过程。系统移植的主要目标是使软件在新的硬件环境下能够正常运行。在系统移植过程中&#xff0c;主要的改动集中在硬件相关的底层部分以及操作系统的核心模…

低代码工单管理app评测,功能与效率解析

预计到2030年&#xff0c;低代码平台市场将达1870亿美元。ZohoCreator助力企业构建定制化软件应用&#xff0c;以建筑行业工作订单管理app为例&#xff0c;简化流程&#xff0c;提升管理效率&#xff0c;降低成本。其用户友好界面、自动化管理、跨平台使用及全面报告功能受企业…

【高频SQL基础50题】31-35

又到SQL。 目录 1.查询结果的质量和占比 2.求关注者的数量 3.指定日期的产品价格 4.好友申请 II &#xff1a;谁有最多的好友 5.按日期分组销售产品 1.查询结果的质量和占比 聚合题。 # Write your MySQL query statement below SELECT t1.query_name,ROUND((SUM(t1.r…

【Linux探索学习】第四弹——Linux权限管理详解:理解用户、组和权限之间的关系

前言&#xff1a; 在前面我们已经学习了Linux的基础指令&#xff0c;相信大家对Linux已经有了一定的认识&#xff0c;今天我们来学习Linux权限的相关知识点&#xff0c;Linux权限是Linux初学者必须要掌握的内容 目录 一、Linux下用户类型 二、权限基本概念 三、权限的表示 四…

WebGoat JAVA反序列化漏洞源码分析

目录 InsecureDeserializationTask.java 代码分析 反序列化漏洞知识补充 VulnerableTaskHolder类分析 poc 编写 WebGoat 靶场地址&#xff1a;GitHub - WebGoat/WebGoat: WebGoat is a deliberately insecure application 这里就不介绍怎么搭建了&#xff0c;可以参考其他…

数据结构修炼——树?二叉树?堆?从入门到代码实现,第一弹!!!

目录 一、树的概念与结构1.1 树的概念1.2 树的相关概念1.3 树的表示及实际应用 二、二叉树概念及结构2.1 二叉树的概念2.2 特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 2.3 二叉树的存储结构 三、二叉树的顺序结构与实现3.1 堆的概念及结构3.2 堆的实现3.2.1 堆的创建与销毁3.…

安卓13禁止用户打开开发者选项 android13禁止用户打开开发者选项

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 设置 =》关于平板电脑 =》版本号,一般的话,在这里连续点击就可以打开我们的开发者选项了。但是有些系统要进行保密,因此要禁止用户进入。 2.问题分析 这里我们是通过点…

Android Framework AMS(02)AMS启动及相关初始化5-8

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要涉及systemserver启动AMS及初始化AMS相关操作。同时由于该部分内容过多&#xff0c;因此拆成2个章节&#xff0c;本章节是第二章节&…

【技术】Jaskson的序列化与反序列化

文章目录 概念解释1.Jasksona.JSONJSON 的基本特点JSON 的基本结构JSON 示例 b.ObjectMapper类 2.序列化与反序列化a.序列化对象序列化集合序列化ListSetMap b.反序列化反序列化单个对象反序列化集合对象 概念解释 1.Jaskson Jackson 是一个用于处理 JSON 数据的 Java 库,所以…

vue-插槽作用域实用场景

vue-插槽作用域实用场景 1.插槽1.1 自定义列表渲染1.2 数据表格组件1.3 树形组件1.4 表单验证组件1.5 无限滚动组件 1.插槽 插槽感觉知道有这个东西&#xff0c;但是挺少用过的&#xff0c;每次看到基本都会再去看一遍用法和概念。但是在项目里&#xff0c;自己还是没有用到过…

基于SpringBoot+Vue的疫情物资管理系统(带1w+文档)

基于SpringBootVue的疫情物资管理系统(带1w文档) 基于SpringBootVue的疫情物资管理系统(带1w文档) 本课题研究和开发疫情物资管理系统管理系统&#xff0c;让安装在计算机上的该系统变成管理人员的小帮手&#xff0c;提高疫情物资管理系统信息处理速度&#xff0c;规范疫情物资…

C++入门基础知识107—【关于C++continue 语句】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C continue 语句的相关内容&#xff01;…

关于Java部署项目,文件上传路径问题 、Windows是\ linux是/

Windows是\ linux是/ &#xff0c;踩坑。报错如下&#xff1a;

SpringBootWeb快速入门!详解如何创建一个简单的SpringBoot项目?

在现代Web开发中&#xff0c;SpringBoot以其简化的配置和快速的开发效率而受到广大开发者的青睐。本篇文章将带领你从零开始&#xff0c;搭建一个基于SpringBoot的简单Web应用~ 一、前提准备 想要创建一个SpringBoot项目&#xff0c;需要做如下准备&#xff1a; idea集成开发…

信息安全工程师(28)机房安全分析与防护

前言 机房安全分析与防护是一个复杂而细致的过程&#xff0c;涉及到物理安全、环境控制、电力供应、数据安全、设备管理、人员管理以及紧急预案等多个方面。 一、机房安全分析 1. 物理安全威胁 非法入侵&#xff1a;未经授权的人员可能通过门窗、通风口等进入机房&#xff0c;…

《大规模语言模型从理论到实践》第一轮学习笔记

第一章 绪论 本章主要介绍大规模语言模型基本概念、发展历程和构建流程。 大规模语言模型&#xff08;Large Language Models&#xff0c;LLM&#xff09;&#xff0c;也称大语言模型 或大型语言模型。 1.1 大规模语言模型基本概念 1.语言模型&#xff08;Language Model&a…

LeetCode 3310. 移除可疑的方法

LeetCode 3310. 移除可疑的方法 你正在维护一个项目&#xff0c;该项目有 n 个方法&#xff0c;编号从 0 到 n - 1。 给你两个整数 n 和 k&#xff0c;以及一个二维整数数组 invocations&#xff0c;其中 invocations[i] [ai, bi] 表示方法 ai 调用了方法 bi。 已知如果方法 k…

Leetcode 37. 解数独

1.题目基本信息 1.1.题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 33 宫内只能出现一次。&#xff08;请参考…

文件IO及目录操作

一、文件IO 1.1 close函数&#xff08;关闭文件&#xff09; #include <unistd.h>---所需头文件 int close(int fd); 功能&#xff1a;关闭文件 参数&#xff1a;fd&#xff1a;文件描述符 返回值&#xff1a;成功返回0&#xff0c;失败返回-1&#xff0c;置位错误码 …