嵌入式硬件篇---CAN


文章目录

  • 前言
  • 1. CAN协议基础
    • 1.1 物理层特性
      • 差分信号线
      • 终端电阻
      • 通信速率
      • 总线拓扑
    • 1.2 帧类型
    • 1.3 数据帧格式
  • 2. STM32F103RCT6的CAN硬件配置
    • 2.1 硬件连接
    • 2.2 CubeMX配置
      • 启用CAN1
      • 模式
      • 波特率
      • 引脚分配
      • 过滤器配置(可选)
  • 3. HAL库代码实现
    • 3.1 CAN初始化
    • 3.2 发送CAN数据帧
    • 3.3 接收CAN数据帧(中断模式)
  • 4. 过滤器配置(接收特定ID)
  • 5. 波特率计算
  • 6. 常见问题与调试
    • 6.1 通信失败原因
      • 波特率不匹配
      • 终端电阻缺失
      • ID冲突
      • 硬件连接错误
    • 6.2 逻辑分析仪抓包
  • 7. 完整示例:双机通信
    • 节点A(发送数据)
    • 节点B(接收数据)
  • 总结
    • 硬件配置
    • 数据收发
    • 调试工具
    • 应用场景


前言

CAN(Controller Area Network)是一种高可靠性、多主机的串行通信协议,广泛应用于汽车电子、工业控制等领域。STM32F103RCT6内置了bxCAN控制器(Basic Extended CAN),支持CAN 2.0A/B标准。以下是详细协议解析及代码实现


1. CAN协议基础

1.1 物理层特性

差分信号线

CAN_H(高电平线)
CAN_L(低电平线)

终端电阻

终端电阻:120Ω(两端各一个,抑制反射)。

通信速率

通信速率:最高1 Mbps(常见波特率:125kbps、250kbps、500kbps)。

总线拓扑

总线拓扑:线性总线结构,支持多节点(最多110个节点)。

1.2 帧类型

帧类型 用途
数据帧 传输实际数据(核心帧类型)
远程帧 请求其他节点发送数据
错误帧 报告通信错误
过载帧 通知节点延迟响应

1.3 数据帧格式

[帧起始] [仲裁段] [控制段] [数据段] [CRC段] [ACK段] [帧结束]
仲裁段:
标准帧(11位ID):CAN 2.0A。
扩展帧(29位ID):CAN 2.0B。
数据段:0~8字节有效载荷。

2. STM32F103RCT6的CAN硬件配置

2.1 硬件连接

CAN信号 STM32引脚 说明
CAN_RX PA11 接收引脚
CAN_TX PA12 发送引脚
CAN_H 连接总线 高电平线
CAN_L 连接总线 低电平线
终端电阻 120Ω 接在总线两端

2.2 CubeMX配置

启用CAN1

模式

模式:Normal(正常模式)。

波特率

波特率:500kbps(时钟分频需匹配APB1时钟,默认36MHz)。

引脚分配

引脚分配:

CAN_RX → PA11
CAN_TX → PA12

过滤器配置(可选)

设置接收过滤器(如仅接收特定ID的帧)。

3. HAL库代码实现

3.1 CAN初始化

#include "stm32f1xx_hal.h"CAN_HandleTypeDef hcan;void MX_CAN_Init(void) {hcan.Instance = CAN1;hcan.Init.Prescaler = 9;          // 波特率 = 36MHz / (Prescaler * (1 + BS1 + BS2)) = 500kbpshcan.Init.Mode = CAN_MODE_NORMAL;  // 正常模式(非环回)hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;hcan.Init.TimeSeg1 = CAN_BS1_4TQ;  // BS1 = 4时间单位hcan.Init.TimeSeg2 = CAN_BS2_3TQ;  // BS2 = 3时间单位hcan.Init.TimeTriggeredMode = DISABLE;hcan.Init.AutoBusOff = DISABLE;hcan.Init.AutoWakeUp = DISABLE;hcan.Init.AutoRetransmission = ENABLE; // 自动重传hcan.Init.ReceiveFifoLocked = DISABLE;hcan.Init.TransmitFifoPriority = DISABLE;if (HAL_CAN_Init(&hcan) != HAL_OK) {Error_Handler();}}

3.2 发送CAN数据帧

void CAN_Send(uint32_t id, uint8_t *data, uint8_t len) {CAN_TxHeaderTypeDef tx_header;uint32_t tx_mailbox;tx_header.StdId = id;           // 标准ID(11位)tx_header.ExtId = 0;            // 扩展ID(未使用)tx_header.IDE = CAN_ID_STD;     // 标准帧tx_header.RTR = CAN_RTR_DATA;   // 数据帧tx_header.DLC = len;            // 数据长度(0~8)tx_header.TransmitGlobalTime = DISABLE;if (HAL_CAN_AddTxMessage(&hcan, &tx_header, data, &tx_mailbox) != HAL_OK) {Error_Handler();}
}// 示例:发送8字节数据(ID=0x123)
uint8_t msg[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
CAN_Send(0x123, msg, 8);

3.3 接收CAN数据帧(中断模式)

CAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[8];void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {printf("Received ID: 0x%03X, Data: ", rx_header.StdId);for (uint8_t i = 0; i < rx_header.DLC; i++) {printf("%02X ", rx_data[i]);}printf("\n");}
}// 主函数中启用接收中断
int main(void) {HAL_Init();MX_CAN_Init();HAL_CAN_Start(&hcan);HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);while (1) { /* 其他任务 */ }
}

4. 过滤器配置(接收特定ID)

CAN控制器通过过滤器筛选接收的帧。以下配置仅接收ID=0x123的帧:

CAN_FilterTypeDef filter;filter.FilterBank = 0;                      // 过滤器组0
filter.FilterMode = CAN_FILTERMODE_IDMASK;  // 掩码模式
filter.FilterScale = CAN_FILTERSCALE_32BIT; // 32位过滤
filter.FilterIdHigh = 0x123 << 5;           // ID高16位(左移5位对齐)
filter.FilterIdLow = 0x0000;                // ID低16位
filter.FilterMaskIdHigh = 0xFFFF;           // 掩码高16位(全匹配)
filter.FilterMaskIdLow = 0x0000;            // 掩码低16位
filter.FilterFIFOAssignment = CAN_RX_FIFO0; // 存入FIFO0
filter.FilterActivation = ENABLE;           // 启用过滤器HAL_CAN_ConfigFilter(&hcan, &filter);

5. 波特率计算

CAN波特率由以下公式决定
波特率= Prescaler×(BS1+BS2+1)
APB1时钟:STM32F103默认36MHz。
BS1:TimeSeg1(例中为4)。
BS2:TimeSeg2(例中为3)。
Prescaler:分频系数(例中为9)。

6. 常见问题与调试

6.1 通信失败原因

波特率不匹配

波特率不匹配:确保所有节点波特率一致。

终端电阻缺失

终端电阻缺失:总线两端需接120Ω电阻。

ID冲突

ID冲突:避免多个节点使用相同ID发送

硬件连接错误

硬件连接错误:检查CAN_H/CAN_L是否接反。

6.2 逻辑分析仪抓包

使用CAN分析仪(如PCAN-USB)或示波器观察
差分信号电平(CAN_H - CAN_L应为2V(显性)或0V(隐性))。
帧结构:起始位、ID、数据等是否正常。

7. 完整示例:双机通信

节点A(发送数据)

uint8_t data[8] = {0xAA, 0xBB, 0xCC, 0xDD};
CAN_Send(0x123, data, 4); // 发送ID=0x123的4字节数据

节点B(接收数据)

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {CAN_RxHeaderTypeDef rx_header;uint8_t rx_data[8];HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data);if (rx_header.StdId == 0x123) {HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 收到数据后翻转LED}
}

总结

硬件配置

硬件配置:正确设置波特率、过滤器

数据收发

数据收发:使用HAL_CAN_AddTxMessage中断回调

调试工具

调试工具:逻辑分析仪、CAN分析仪是关键。

应用场景

应用场景:汽车ECU通信、工业传感器网络等。
通过上述代码,STM32F103RCT6可稳定实现CAN通信,适用于高可靠性要求的嵌入式系统。


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

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

相关文章

DeepSeek-R1 Supervised finetuning and reinforcement learning (SFT + RL)

DeepSeek-R1Supervised finetuning and reinforcement learning (SFT RL) 好啊&#xff0c;我们今天的直播会非常透彻的跟大家系统性的分享一下整个agents AI就大模型智能体系统和应用程序。我们在做开发的时候&#xff0c;或者实际做企业级的产品落地的时候&#xff0c;你必…

机器学习 day04

文章目录 前言一、线性回归的基本概念二、损失函数三、最小二乘法 前言 通过今天的学习&#xff0c;我掌握了机器学习中的线性回归的相关基本概念&#xff0c;包括损失函数的概念&#xff0c;最小二乘法的理论与算法实现。 一、线性回归的基本概念 要理解什么是线性回归&…

img.dims() <= 2 in function ‘cv::matchTemplate报错

Mat src mat_ori;//imread(img_original);Mat src_template imread(img_template);cvtColor(src, src, COLOR_BGR2RGB);//不转换&#xff0c;matchTemplate将报错cvtColor(src_template, src_template,COLOR_BGR2RGB);//不转换&#xff0c;matchTemplate将报错 error: (-215…

NY321NY322美光闪存芯片NY323NY336

NY321NY322美光闪存芯片NY323NY336 在存储技术飞速发展的今天&#xff0c;美光科技的闪存芯片凭借其创新架构与高性能表现&#xff0c;已成为工业自动化、智能终端等领域的核心组件。本文将围绕技术解析、产品评测、行业趋势、应用案例及市场动态五大维度&#xff0c;深入探讨…

exit耗时高

背景&#xff1a;程序退出发现被强制退出&#xff0c;而不是正常的退出。正常退出是发送15信号&#xff0c;而异常退出是发送信号9&#xff0c;强制退出。退出机制是先发送信号15&#xff0c;然后6s内没有退出完成&#xff0c;会发送信号9。通过查看退出流程&#xff0c;是将初…

docker compose up -d 是一个用于 通过 Docker Compose 在后台启动多容器应用 的命令

docker compose 表示调用 Docker Compose 工具&#xff0c;用于管理基于 YAML 文件定义的多容器应用。 up 核心指令&#xff0c;作用是根据 docker-compose.yml 文件中的配置&#xff0c;创建并启动所有定义的服务、网络、卷等资源。 如果容器未创建&#xff0c;会先构建镜像&…

从辅助到协作:GitHub Copilot的进化之路

如果说现代程序员的标配工具除了VS Code、Stack Overflow之外&#xff0c;还有谁能入选&#xff0c;那一定是GitHub Copilot。从2021年首次亮相&#xff0c;到如今深度集成进开发者日常流程&#xff0c;这个“AI编程助手”已经不只是写几行自动补全代码的小帮手了&#xff0c;而…

局部放大maya的视图HUD文字大小的方法

一、问题描述&#xff1a; 有网友问&#xff1a;有办法局部放大maya的字体吗比如hud中currenttime打开之后画面右下角有个frame 想放大一下能做到吗&#xff1f; 在 Maya 中&#xff0c;可以通过自定义 HUD&#xff08;Heads-Up Display&#xff09;元素的字体大小来局部放大特…

C++中隐式的类类型转换知识详解和注意事项

一、隐式转换的基本概念 隐式类型转换&#xff08;implicit conversion&#xff09;指编译器在需要时自动在两种类型之间插入转换代码&#xff0c;无需显式调用。对于内置类型&#xff08;如 int 到 double&#xff09;&#xff0c;转换由标准定义&#xff1b;对于用户自定义类…

【C++】18.二叉搜索树

由于map和set的底层是红黑树&#xff0c;同时后面要讲的AVL树(高度平衡二叉搜索树)&#xff0c;为了方便理解&#xff0c;我们先来讲解二叉搜索树&#xff0c;因为红黑树和AVL树都是在二叉搜索树的前提下实现的 在之前的C语言数据结构章节中&#xff0c;我们讲过二叉树&#x…

Leaflet使用SVG创建动态Legend

接前一篇文章&#xff0c;前一篇文章我们使用 SVG 创建了带有动态文字的图标&#xff0c;今天再看看怎样在地图上根据动态图标生成相关的legend&#xff0c;当然这里也还是使用了 SVG 来生成相关颜色的 legend。 看下面的代码&#xff0c;生成了一个 svg 节点&#xff0c;其中…

Linux基础开发工具二(gcc/g++,自动化构建makefile)

3. 编译器gcc/g 3.1 背景知识 1. 预处理&#xff08;进行宏替换/去注释/条件编译/头文件展开等) 2. 编译&#xff08;生成汇编) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 连接&#xff08;生成可执行文件或库文件) 3.2 gcc编译选项 格式 &#xff1a; gcc …

PostGIS实现栅格数据入库-raster2pgsql

raster2pgsql使用与最佳实践 一、工具概述 raster2pgsql是PostGIS提供的命令行工具,用于将GDAL支持的栅格格式(如GeoTIFF、JPEG、PNG等)导入PostgreSQL数据库,支持批量加载、分块切片、创建空间索引及金字塔概览,是栅格数据入库的核心工具。 二、核心功能与典型用法 1…

精益数据分析(64/126):移情阶段的用户触达策略——从社交平台到精准访谈

精益数据分析&#xff08;64/126&#xff09;&#xff1a;移情阶段的用户触达策略——从社交平台到精准访谈 在创业的移情阶段&#xff0c;精准找到目标用户并开展深度访谈是验证需求的关键。今天&#xff0c;我们结合《精益数据分析》中的方法论&#xff0c;探讨如何利用Twit…

ORACLE RAC环境REDO日志量突然增加的分析

服务概述 CRM系统在7/11日出现REDO日志产生量突增&#xff0c;达到平时产生量的20倍以上&#xff0c;对数据同步已经造成了较大的影响。工程师接到故障申报后&#xff0c;及时进行响应&#xff0c;通过对相关日志等信息的深入分析&#xff0c;整理汇总此文档。 二、数据库REDO…

注册表设置windows背景护眼色

方法一&#xff1a; CtrlR&#xff0c;输入regedit打开注册表 HKEY_CURRENT_USER\Control Panel\Colors 右侧窗口Windows键值由255 255 255改为202 234 206。 方法二&#xff1a; 还是注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColo…

回溯法理论基础 LeetCode 77. 组合 LeetCode 216.组合总和III LeetCode 17.电话号码的字母组合

目录 回溯法理论基础 回溯法 回溯法的效率 用回溯法解决的问题 如何理解回溯法 回溯法模板 LeetCode 77. 组合 回溯算法的剪枝操作 LeetCode 216.组合总和III LeetCode 17.电话号码的字母组合 回溯法理论基础 回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一…

自己手写tomcat项目

一&#xff1a;Servlet的原理 在Servlet(接口中)有&#xff1a; 1.init():初始化servlet 2.getServletConfig()&#xff1a;获取当前servlet的配置信息 3.service():服务器&#xff08;在HttpServlet中实现&#xff0c;目的是为了更好的匹配http的请求方式&#xff09; 4.g…

兰亭妙微:用系统化思维重构智能座舱 UI 体验

兰亭妙微设计专注于以产品逻辑驱动的界面体验优化&#xff0c;服务领域覆盖AI交互、智能穿戴、IoT设备、智慧出行等多个技术密集型产业。我们倡导以“系统性设计”为方法论&#xff0c;在用户需求与技术边界之间找到最优解。 此次智能驾驶项目&#xff0c;我们为某车载平台提供…

ubuntu安装google chrome

更新系统 sudo apt update安装依赖 sudo apt install curl software-properties-common apt-transport-https ca-certificates -y导入 GPG key curl -fSsL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | sudo tee /usr/share/keyrings/google-chrom…