当前位置: 首页 > news >正文

STM32 CAN通讯实验程序

目录

STM32 CAN通讯实验

CAN硬件原理图

CAN外设原理图

TJA1050T硬件描述

实验线路图

回环实验

CAN头文件配置

 CAN_GPIO_Config初始化

CAN初始化结构体

CAN筛选器结构体

 接收中断优先级配置

接收中断函数

main文件

实验现象

补充


STM32 CAN通讯实验

CAN硬件原理图

CAN外设原理图

野火STM32F103ZET6霸道板载原理图

我们的开发板没有使用GPIO外设的复用功能PA11和PA12,而使用了重定义(重映射)功能PB8和PB9

TJA1050T硬件描述

实验线路图

图中为两个霸道开发板,如果使用指南针开发板需要外接CAN收发器和电阻。

        是否使用RX和TX引脚是根据实际情况来确认是否使用的。如果我们使用回环模式时,在STM32芯片内部的CAN控制器的发送端和接收端就已经通过硬件逻辑连接起来了,比如回环静默模式,根本不用使用STM32的发送和接收引脚。甚至使用回环测试的时候,CAN收发器就算不供电都可以工作。

回环实验

我们配置外设的GPIO功能时,可以参考手册的外设GPIO功能配置

CAN头文件配置

#ifndef __BSP_CAN_H
#define __BSP_CAN_H#include "stm32f10x.h"#define PASS_ID   ((uint32_t)0x1314)#define CAN_TX_GPIO_PROT          GPIOB
#define CAN_TX_GPIO_PIN           GPIO_Pin_9#define  CAN_RX_GPIO_PORT     GPIOB
#define  CAN_RX_GPIO_PIN      GPIO_Pin_8#define CAN_GPIO_CLK                    RCC_APB2Periph_GPIOB/*信息输出*/
#define CAN_DEBUG_ON         1#define CAN_INFO(fmt,arg...)           printf("<<-CAN-INFO->> "fmt"\n",##arg)
#define CAN_ERROR(fmt,arg...)          printf("<<-CAN-ERROR->> "fmt"\n",##arg)
#define CAN_DEBUG(fmt,arg...)          do{\if(CAN_DEBUG_ON)\printf("<<-CAN-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);void CAN_Config(void)    ;     #endif /* __BSP_CAN_H */

 CAN_GPIO_Config初始化

void CAN_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* 使能CAN时钟 */RCC_APB1PeriphClockCmd (RCC_APB1Periph_CAN1 , ENABLE );/* 使能CAN引脚相关的时钟 */RCC_APB2PeriphClockCmd ( CAN_GPIO_CLK|RCC_APB2Periph_AFIO, ENABLE );//使用PA8 9引脚的第二功能GPIO_PinRemapConfig (GPIO_Remap1_CAN1 ,ENABLE);/* 配置CAN的 引脚,普通IO即可 */GPIO_InitStructure.GPIO_Pin = CAN_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(CAN_TX_GPIO_PROT, &GPIO_InitStructure);/* 配置CAN的 引脚,普通IO即可 */GPIO_InitStructure.GPIO_Pin = CAN_RX_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);}

PB8和PB9使用重映射功能

我们要使用GPIO_PinRemapConfig函数来使能PA8 9引脚的第二功能,此外一定要记得开启相应的AFIO时钟,否则第二功能是无法使用的。

CAN初始化结构体

void CAN_Mode_Config(void)    
{CAN_InitTypeDef CAN_InitTypeStruct;CAN_InitTypeStruct.CAN_ABOM = ENABLE;CAN_InitTypeStruct.CAN_AWUM = ENABLE;CAN_InitTypeStruct.CAN_Mode = CAN_Mode_LoopBack;//CAN_Mode_Normal;//调试时建议使用回环模式,调试完再改成NORMALCAN_InitTypeStruct.CAN_NART = ENABLE; //错误重传CAN_InitTypeStruct.CAN_RFLM = ENABLE;CAN_InitTypeStruct.CAN_TTCM = DISABLE;CAN_InitTypeStruct.CAN_TXFP = DISABLE; //按ID优先级发送//配置成1MbpsCAN_InitTypeStruct.CAN_BS1 = CAN_BS1_5tq;CAN_InitTypeStruct.CAN_BS2 = CAN_BS2_3tq;CAN_InitTypeStruct.CAN_SJW = CAN_SJW_2tq;CAN_InitTypeStruct.CAN_Prescaler = 4;CAN_Init(CAN1,&CAN_InitTypeStruct);}

其中位时序及波特率按照下表配置

CAN筛选器结构体

void CAN_Filter_Config(void)
{CAN_FilterInitTypeDef CAN_FilterInitTypeStruct;CAN_FilterInitTypeStruct.CAN_FilterActivation = ENABLE;CAN_FilterInitTypeStruct.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0  ;CAN_FilterInitTypeStruct.CAN_FilterNumber = 0;CAN_FilterInitTypeStruct.CAN_FilterScale = CAN_FilterScale_32bit;CAN_FilterInitTypeStruct.CAN_FilterMode = CAN_FilterMode_IdMask  ;CAN_FilterInitTypeStruct.CAN_FilterIdHigh = ((PASS_ID<<3 |CAN_Id_Extended |CAN_RTR_Data)&0xFFFF0000)>>16;CAN_FilterInitTypeStruct.CAN_FilterIdLow = ((PASS_ID<<3 |CAN_Id_Extended |CAN_RTR_Data)&0xFFFF);CAN_FilterInitTypeStruct.CAN_FilterMaskIdHigh = 0xFFFF;CAN_FilterInitTypeStruct.CAN_FilterMaskIdLow =0xFFFF;    CAN_FilterInit(&CAN_FilterInitTypeStruct);CAN_ITConfig (CAN1,CAN_IT_FMP0,ENABLE);}    

其中假如我们要过滤的ID为0x1314

使用stm32f10x_can.h文件末尾定义的相关宏

由于使用的是32位筛选器且标识符掩码,所以其中CAN_FilterIdHigh和CAN_FilterIdLow为我们过滤ID格式的高16位和低16位,首先将ID号左移三位,然后或上IDE、RTR位

CAN_FilterInitTypeStruct.CAN_FilterIdHigh = ((PASS_ID<<3 |CAN_Id_Extended |CAN_RTR_Data)&0xFFFF0000)>>16;
CAN_FilterInitTypeStruct.CAN_FilterIdLow = ((PASS_ID<<3 |CAN_Id_Extended |CAN_RTR_Data)&0xFFFF);

而CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow为要过滤的ID掩码,全为1,表示完全过滤

CAN_FilterInitTypeStruct.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitTypeStruct.CAN_FilterMaskIdLow =0xFFFF;    

 接收中断优先级配置

void CAN_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 配置NVIC为优先级组1 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;/* 配置抢占优先级 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 配置子优先级 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中断通道 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

在标准库头文件中找到CAN接收数据中断源,我们使用的是接收邮箱0,所以选择USB_LP_CAN1_RX0_IRQn

使能中断放在CAN筛选器结构体配置中

接收中断函数

extern CanRxMsg  CAN_Rece_Data;
extern uint8_t flag;void USB_LP_CAN1_RX0_IRQHandler(void)    
{CAN_Receive(CAN1,CAN_FIFO0, &CAN_Rece_Data); flag = 1;}

要注意的是在CAN里,我们设置完CAN_Receive(CAN1,CAN_FIFO0, &CAN_Rece_Data);之后不需要手动清除接收标志,该函数会自动清除。

flag用于在main函数中判断是否接收到数据,从而做相应的应用处理

我们也可以再加个判断进一步确认接收数据的准确性

main文件

#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./can/bsp_can.h"
#include "./key/bsp_key.h"  CanRxMsg  CAN_Rece_Data;
CanTxMsg  CAN_Tran_Data;uint8_t flag = 0;void Delay(__IO uint32_t nCount); /** 函数名:main* 描述  :主函数* 输入  :无* 输出  :无*/
int main(void)
{     LED_GPIO_Config();LED_BLUE;/* 配置串口为:115200 8-N-1 */USART_Config();printf("\r\n 这是一个CAN通讯实验 \r\n");CAN_Config()    ;   Key_GPIO_Config();printf("\r\n 按KEY1按键发送数据\r\n");while(1){if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON  ){uint8_t box;CAN_Tran_Data.StdId = 0;CAN_Tran_Data.ExtId = PASS_ID;CAN_Tran_Data.RTR = CAN_RTR_Data;//使用数据帧CAN_Tran_Data.IDE = CAN_Id_Extended ; //使用扩展帧CAN_Tran_Data.DLC = 1;CAN_Tran_Data.Data[0] = 10;box = CAN_Transmit(CAN1,&CAN_Tran_Data);while(CAN_TransmitStatus(CAN1,box) == CAN_TxStatus_Failed);printf("\r\n 数据包发送完成\r\n");            }         if(flag == 1){printf("\r\n接收到的数据:%d\r\n",CAN_Rece_Data.Data[0]);flag = 0;}else{}}
}void Delay(__IO uint32_t nCount)
{for(; nCount != 0; nCount--);
}

实验现象

补充

由于只有一个板子,无法演示双机实验,双机实验只需要将我们的回环实验中的回环模式换成正常模式,然后将程序分别下载到两个开发板即可。

学完基础的CAN通讯协议之后,如果想要今后从事CAN通讯相关工作,比如工业、汽车领域,我们还需要进一步学习一下CAN OPEN。

相关文章:

STM32 CAN通讯实验程序

目录 STM32 CAN通讯实验 CAN硬件原理图 CAN外设原理图 TJA1050T硬件描述 实验线路图 回环实验 CAN头文件配置 CAN_GPIO_Config初始化 CAN初始化结构体 CAN筛选器结构体 接收中断优先级配置 接收中断函数 main文件 实验现象 补充 STM32 CAN通讯实验 CAN硬件原理图…...

Python代码片段之Django静态文件URL的配置

首先要说明这段python代码并不完整&#xff0c;而且我也没有做过测试&#xff0c;只是我在工作时参考了其中的一些个方法。这是我在找python相关源码资料里看到的一段代码&#xff0c;是Django静态文件URL配置代码片段2&#xff0c;代码中有些方法还是挺技巧的&#xff0c;做其…...

基于飞桨paddle的极简方案构建手写数字识别模型测试代码

基于飞桨paddle的极简方案构建手写数字识别模型测试代码 原始测试图片为255X252的图片 因为是极简方案采用的是线性回归模型&#xff0c;所以预测结果数字不一致 本次预测的数字是 [[3]] 测试结果&#xff1a; PS E:\project\python> & D:/Python39/python.exe e:/pro…...

soft ip与hard ip

ip分soft和hard两种&#xff0c;soft就是纯代码&#xff0c;买过来要自己综合自己pr。hard ip如mem和analog与工艺有关。 mem的lib和lef是memory compiler产生的&#xff0c;基于bitcell&#xff0c;是foundry给的。 我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起…...

MyBatisPlus从入门到精通-2

接着上一讲的Mp的分页功能 下面我们讲解条件查询功能和其他功能 解决一下日志输出和banner问题 每次卞就会输出这些日志 很不美观&#xff0c;现在我们关闭一下 这样建个xml&#xff0c;文件名为logback.xml 文件内容改成这样 配置了logback但是里面什么都没写就不会说有日…...

AI面试官:Asp.Net 中使用Log4Net (一)

AI面试官&#xff1a;Asp.Net 中使用Log4Net (一) 当面试涉及到使用log4net日志记录框架的相关问题时&#xff0c;通常会聚焦在如何在.NET或.NET Core应用程序中集成和使用log4net。以下是一些关于log4net的面试题目&#xff0c;以及相应的解答、案例和代码&#xff1a; 文章目…...

Selenium自动化元素定位方式与浏览器测试脚本

Selenium八大元素定位方法 Selenium可以驱动浏览器完成各种操作&#xff0c;比如模拟点击等。要想操作一个元素&#xff0c;首先应该识别这个元素。人有各种的特征&#xff08;属性&#xff09;&#xff0c;我们可以通过其特征找到人&#xff0c;如通过身份证号、姓名、家庭住…...

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…...

【项目】轻量级HTTP服务器

文章目录 一、项目介绍二、前置知识2.1 URI、URL、URN2.2 CGI2.2.1 CGI的概念2.2.2 CGI模式的实现2.2.3 CGI的意义 三、项目设计3.1 日志的编写3.2 套接字编写3.3 HTTP服务器实现3.4 HTTP请求与响应结构3.5 EndPoint类的实现3.5.1 EndPoint的基本逻辑3.5.2 读取请求3.5.3 构建响…...

sketch如何在线打开?有没有什么软件可以辅助

Sketch 在线打开的方法有哪些&#xff1f;这个问题和我之前回答过的「Sketch 可以在线编辑吗&#xff1f;」是一样的答案&#xff0c;没有。很遗憾&#xff0c;Sketch 没有在线打开的方法&#xff0c;Sketch 也做不到可以在线编辑。那么&#xff0c;那些广告里出现的设计软件工…...

CSS Flex 笔记

1. Flexbox 术语 Flex 容器可以是<div> 等&#xff0c;对其设置属性&#xff1a;display: flex, justify-content 是沿主轴方向调整元素&#xff0c;align-items 是沿交叉轴对齐元素。 2. Cheatsheet 2.1 设置 Flex 容器&#xff0c;加粗的属性为默认值 2.1.1 align-it…...

Markdown常用标签及其用途-有示例

Markdown常用标签及其用途 Markdown是一种轻量级标记语言&#xff0c;具有简洁易读的特点。下面是一些常用的Markdown标签以及它们的用途&#xff0c;并附带一些示例&#xff1a; 标题 用于创建不同级别的标题&#xff0c;可通过添加一到六个#符号来表示不同级别的标题。 #…...

25.1 Knife4j-Swagger的增强插件

1.Knife4j概述 Knife4j是一款基于Swagger UI的增强插件&#xff0c;它可以为Spring Boot项目生成美观且易于使用的API文档界面。它是Swagger UI的增强版&#xff0c;提供了更多的功能和定制选项&#xff0c;使API文档更加易读和易于理解。 2.Knife4j使用 Knife4j 集Swagger2…...

用flask run代替flask run --debug

安装python-dotenv依赖。 在项目根目录下新建.flaskenv文件&#xff0c;并作如下配置&#xff1a; FLASK_ENVdevelopment FLASK_DEBUG1...

python_day14_综合案例

文件内容 导包配置 import jsonfrom pyspark import SparkContext, SparkConf import osos.environ["PYSPARK_PYTHON"] "D:/dev/python/python3.10.4/python.exe" os.environ["HADOOP_HOME"] "D:/dev/hadoop-3.0.0" conf SparkC…...

【算法题】2779. 数组的最大美丽值

题目&#xff1a; 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一步操作中&#xff0c;你可以执行下述指令&#xff1a; 在范围 [0, nums.length - 1] 中选择一个 此前没有选过 的下标 i 。 将 nums[i] 替换为范围 [nums[i] - k, nums[i] k] 内的任一整…...

文件上传之PHP

别怕,我会一直陪着你 一.知识二.实例1.phtml, <?简单过滤2.前端验证, phtml3 \.htaccess 一.知识 绕过后缀的有文件格式有php,php3,php4,php5,phtml.pht 二.实例 1.phtml, <?简单过滤 (1)一句话木马 故意使用了post和get用来迷惑人 https://127.0.0.1/shy.php?POS…...

人脸检测实战-insightface

目录 简介 一、InsightFace介绍 二、安装 三、快速体验 四、代码实战 1、人脸检测 2、人脸识别 五、代码及示例图片链接 简介 目前github有非常多的人脸识别开源项目&#xff0c;下面列出几个常用的开源项目&#xff1a; 1、deepface 2、CompreFace 3、face_recogn…...

Linux工具【1】(编辑器vim、编译器gcc与g++)

vim详解 引言vimVim的三种模式及模式切换普通模式下操作底行模式下操作 gcc与ggcc的使用&#xff08;g类似&#xff09;预编译编译汇编链接静态库与动态库 总结 引言 vim&#xff08;vi improved&#xff09;编辑器是从 vi 发展出来的一个文本编辑器。 代码补全、编译及错误跳…...

基于Java+SpringBoot+vue前后端分离古典舞在线交流平台设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...