<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CAN on Zesean 的博客</title><link>https://zeseanblog.top/tags/can/</link><description>Recent content in CAN on Zesean 的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Tue, 01 Sep 2026 22:58:08 +0800</lastBuildDate><atom:link href="https://zeseanblog.top/tags/can/index.xml" rel="self" type="application/rss+xml"/><item><title>CAN 通信协议学习笔记</title><link>https://zeseanblog.top/p/can/</link><pubDate>Sat, 24 May 2025 10:00:00 +0800</pubDate><guid>https://zeseanblog.top/p/can/</guid><description>&lt;h2 id="can简介"&gt;&lt;a href="#can%e7%ae%80%e4%bb%8b" class="header-anchor"&gt;&lt;/a&gt;CAN简介&#13;&#10;&lt;/h2&gt;&lt;p&gt;CAN总线特征：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;两根通信线(CAN_H、CAN_L)，无需共地&lt;/li&gt;&#10;&lt;li&gt;差分信号，抗干扰&lt;/li&gt;&#10;&lt;li&gt;高速CAN:125k-1mbps，&amp;lt;40m&lt;/li&gt;&#10;&lt;li&gt;低速CAN:10k~125kbps, &amp;lt;1km&lt;/li&gt;&#10;&lt;li&gt;异步通信(无时钟线)，通信速率由设备各自约定&lt;/li&gt;&#10;&lt;li&gt;半双工，可挂载多设备，多设备同时发送数据时通过仲裁判断先后顺序&lt;/li&gt;&#10;&lt;li&gt;11位/29位报文ID，用于区分消息功能，同时决定优先级&lt;/li&gt;&#10;&lt;li&gt;可配置1~8字节的有效载荷&lt;/li&gt;&#10;&lt;li&gt;可实现广播式和请求式两种传输方式&lt;/li&gt;&#10;&lt;li&gt;应答、CRC校验、位填充、位同步、错误处理等特性&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="主流通信协议"&gt;&lt;a href="#%e4%b8%bb%e6%b5%81%e9%80%9a%e4%bf%a1%e5%8d%8f%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;主流通信协议&#13;&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;名称&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;引脚&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;双工&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;时钟&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;电平&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;UART&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;TX、RX&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;全双工&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;异步&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;单端&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;点对点&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;两个设备互相通信&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;I2C&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SCL、SDA&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;半双工&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同步&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;单端&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;多设备&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;一个主控外挂多个模块&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SPI&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SCK、MOSI、MISO、SS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;全双工&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同步&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;单端&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;多设备&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;一个主控外挂多个模块（高速）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CAN&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CAN_H、CAN_L&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;半双工&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;异步&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;差分&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;多设备&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;多个主控互相通信&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;CAN类似UART和IIC的结合&lt;/p&gt;&#10;&lt;h1 id="第一章"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;第一章&#13;&#10;&lt;/h1&gt;&lt;h2 id="can硬件电路"&gt;&lt;a href="#can%e7%a1%ac%e4%bb%b6%e7%94%b5%e8%b7%af" class="header-anchor"&gt;&lt;/a&gt;CAN硬件电路&#13;&#10;&lt;/h2&gt;&lt;p&gt;主控会内置CAN控制器，借助CAN收发器挂载在CAN总线网络&lt;/p&gt;&#10;&lt;p&gt;高速CAN采用闭环网络，CAN的差分信号默认状态下(1，CANH=CANL)，由电阻收紧，而电阻因为阻抗不大，因此电压跃变快，但是功耗高&lt;/p&gt;&#10;&lt;img src="images/image-20251023155654683.png" alt="image-20251023155654683" style="zoom:67%;" /&gt;&#10;&lt;p&gt;低速CAN使用开环网络，两端加开路的电阻，降低反射&lt;/p&gt;&#10;&lt;img src="images/image-20251023155742503.png" alt="image-20251023155742503" style="zoom:67%;" /&gt;&#10;&lt;h2 id="电平标准"&gt;&lt;a href="#%e7%94%b5%e5%b9%b3%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;电平标准&#13;&#10;&lt;/h2&gt;&lt;p&gt;差分信号，即电压差传输数据&lt;/p&gt;&#10;&lt;p&gt;高速CAN：&lt;/p&gt;&#10;&lt;p&gt;隐性电平是不碰两根线，电阻处为收紧状态（默认状态1，隐性）&lt;/p&gt;&#10;&lt;p&gt;显性电平是拉开两根线，电阻处为非收紧状态（显性可以控制总线，0强于1，所以能叫显性）&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;电压差为0V时表示逻辑1（隐性电平）&lt;/li&gt;&#10;&lt;li&gt;电压差为2V时表示逻辑0（显性电平）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;img src="images/image-20251023160648825.png" alt="image-20251023160648825" style="zoom:67%;" /&gt;&#10;&lt;h2 id="can收发器-tja1050高速can"&gt;&lt;a href="#can%e6%94%b6%e5%8f%91%e5%99%a8-tja1050%e9%ab%98%e9%80%9fcan" class="header-anchor"&gt;&lt;/a&gt;CAN收发器-TJA1050(高速CAN)&#13;&#10;&lt;/h2&gt;&lt;img src="images/image-20251023162057153.png" alt="image-20251023162057153" style="zoom: 67%;" /&gt;&#10;&lt;p&gt;CANH和CANL有电压差，RECEIVER输出1，下管导通，RXD为0(有电压差，逻辑0，显性)&lt;/p&gt;&#10;&lt;p&gt;CANH和CANL无电压差，RECEIVER输出0，上管导通，RXD为1(无电压差，逻辑1，隐性)&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023162504583" class="gallery-image" data-flex-basis="283px" data-flex-grow="118" height="161" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023162504583.png" width="190"&gt;&lt;/p&gt;&#10;&lt;p&gt;TXD为0时，2,3的场效应管导通，CANH和CANL有电压差（逻辑0，显性）&lt;/p&gt;&#10;&lt;p&gt;而TXD悬空时，电流源默认让TXD为1&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023163114449" class="gallery-image" data-flex-basis="318px" data-flex-grow="132" height="119" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023163114449.png" width="158"&gt;&lt;/p&gt;&#10;&lt;h2 id="can物理层特性"&gt;&lt;a href="#can%e7%89%a9%e7%90%86%e5%b1%82%e7%89%b9%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;CAN物理层特性&#13;&#10;&lt;/h2&gt;&lt;p&gt;&lt;img alt="image-20251023163332184" class="gallery-image" data-flex-basis="287px" data-flex-grow="119" height="693" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023163332184.png" srcset="https://zeseanblog.top/p/can/images/image-20251023163332184_hu_e57a866cf5261929.png 800w, https://zeseanblog.top/p/can/images/image-20251023163332184.png 831w" width="831"&gt;&lt;/p&gt;&#10;&lt;h1 id="第二章"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;第二章&#13;&#10;&lt;/h1&gt;&lt;h2 id="can总线帧格式"&gt;&lt;a href="#can%e6%80%bb%e7%ba%bf%e5%b8%a7%e6%a0%bc%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;CAN总线帧格式&#13;&#10;&lt;/h2&gt;&lt;p&gt;主要看数据帧&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;帧类型&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;strong&gt;用途&lt;/strong&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;数据帧&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;发送设备主动发送数据（广播式）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;遥控帧&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;接收设备主动请求数据（请求式）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;错误帧&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;某个设备检测出错误时向其他设备通知错误&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;过载帧&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;接收设备通知其尚未做好接收准备&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;帧间隔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;用于将数据帧及遥控帧与前面的帧分离开&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="数据帧"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;数据帧&#13;&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;SOF（Start of Frame）：帧起始，表示后面一段波形为传输的数据位&lt;/li&gt;&#10;&lt;li&gt;ID（Identify）：标识符，区分功能，同时决定优先级&lt;/li&gt;&#10;&lt;li&gt;RTR（Remote Transmission Request ）：远程请求位，区分数据帧和遥控帧&lt;/li&gt;&#10;&lt;li&gt;IDE（Identifier Extension）：扩展标志位，区分标准格式和扩展格式&lt;/li&gt;&#10;&lt;li&gt;SRR（Substitute Remote Request）：替代RTR，协议升级时留下的无意义位&lt;/li&gt;&#10;&lt;li&gt;r0/r1（Reserve）：保留位，为后续协议升级留下空间&lt;/li&gt;&#10;&lt;li&gt;DLC（Data Length Code）：数据长度，指示数据段有几个字节&lt;/li&gt;&#10;&lt;li&gt;Data：数据段的1~8个字节有效数据&lt;/li&gt;&#10;&lt;li&gt;CRC（Cyclic Redundancy Check）：循环冗余校验，校验数据是否正确&lt;/li&gt;&#10;&lt;li&gt;ACK（Acknowledgement）：应答位，判断数据有没有被接收方接收&lt;/li&gt;&#10;&lt;li&gt;CRC/ACK界定符：为应答位前后发送方和接收方释放总线留下时间&lt;/li&gt;&#10;&lt;li&gt;EOF（End of Frame ）：帧结束，表示数据位已经传输完毕&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023163910230" class="gallery-image" data-flex-basis="502px" data-flex-grow="209" height="430" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023163910230.png" srcset="https://zeseanblog.top/p/can/images/image-20251023163910230_hu_87202e28ebbad6da.png 800w, https://zeseanblog.top/p/can/images/image-20251023163910230.png 900w" width="900"&gt;&lt;/p&gt;&#10;&lt;h3 id="标准格式"&gt;&lt;a href="#%e6%a0%87%e5%87%86%e6%a0%bc%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;标准格式&#13;&#10;&lt;/h3&gt;&lt;ol&gt;&#10;&lt;li&gt;开始为空闲状态为隐性&lt;/li&gt;&#10;&lt;li&gt;SOF为帧起始，表明开始一帧数据&lt;/li&gt;&#10;&lt;li&gt;起始帧后发送11位标识符报文，区分功能，同时决定优先级&lt;/li&gt;&#10;&lt;li&gt;RTR为0：数据帧。为1：遥控帧&lt;/li&gt;&#10;&lt;li&gt;IDE为0：标准格式。为1：扩展格式&lt;/li&gt;&#10;&lt;li&gt;r0保留位，暂时无功能&lt;/li&gt;&#10;&lt;li&gt;DLC为数据长度，0001发一个字节，1000发8字节&lt;/li&gt;&#10;&lt;li&gt;Data根据DLC给几个字节能给范围0-64字节&lt;/li&gt;&#10;&lt;li&gt;CRC为校验&lt;/li&gt;&#10;&lt;li&gt;ACK应答位，发送方释放总线，如果接收方收到了，就抢占总线，发送方读取总线状态知道被接受&lt;/li&gt;&#10;&lt;li&gt;CRC/ACK界定符是留出时间交出控制权&lt;/li&gt;&#10;&lt;li&gt;EOF作为结束&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="遥控帧"&gt;&lt;a href="#%e9%81%a5%e6%8e%a7%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;遥控帧&#13;&#10;&lt;/h2&gt;&lt;p&gt;适合使用频率低的数据&lt;/p&gt;&#10;&lt;p&gt;遥控帧无数据段，RTR为隐性电平1，其他部分与数据帧相同&lt;/p&gt;&#10;&lt;p&gt;如果有数据需要，首先接收方发出一个遥控帧，遥控帧包含报文ID，如果发送方有这个报文ID，就将数据发送出来，接收方可以及时获取数据&lt;/p&gt;&#10;&lt;h2 id="错误帧"&gt;&lt;a href="#%e9%94%99%e8%af%af%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;错误帧&#13;&#10;&lt;/h2&gt;&lt;p&gt;总线所有设备监督总线数据，一旦发现错误，这些设备发出错误帧来破坏数据，同时终止当前的发送设备&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023185816885" class="gallery-image" data-flex-basis="581px" data-flex-grow="242" height="429" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023185816885.png" srcset="https://zeseanblog.top/p/can/images/image-20251023185816885_hu_5c5d0970fb8f6aa8.png 800w, https://zeseanblog.top/p/can/images/image-20251023185816885.png 1040w" width="1040"&gt;&lt;/p&gt;&#10;&lt;h2 id="过载帧"&gt;&lt;a href="#%e8%bf%87%e8%bd%bd%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;过载帧&#13;&#10;&lt;/h2&gt;&lt;p&gt;接收方收到大量数据无法处理，发送过载帧，延缓发送方的数据发送，以平衡总线负载，避免数据丢失&lt;/p&gt;&#10;&lt;h2 id="帧间隔"&gt;&lt;a href="#%e5%b8%a7%e9%97%b4%e9%9a%94" class="header-anchor"&gt;&lt;/a&gt;帧间隔&#13;&#10;&lt;/h2&gt;&lt;p&gt;将数据帧和遥控帧与前面的帧分离开&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023190001992" class="gallery-image" data-flex-basis="635px" data-flex-grow="264" height="393" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023190001992.png" srcset="https://zeseanblog.top/p/can/images/image-20251023190001992_hu_64188ad5a2c92944.png 800w, https://zeseanblog.top/p/can/images/image-20251023190001992.png 1040w" width="1040"&gt;&lt;/p&gt;&#10;&lt;h2 id="位填充"&gt;&lt;a href="#%e4%bd%8d%e5%a1%ab%e5%85%85" class="header-anchor"&gt;&lt;/a&gt;位填充&#13;&#10;&lt;/h2&gt;&lt;p&gt;规则：发送方每发送5个相同电平，自动追加相反电平的填充位，接收方检测到填充位，自动移除填充位。&lt;/p&gt;&#10;&lt;p&gt;即将发送：&#9; 100000110&#9; 10000011110&#9; 0111111111110&#10;实际发送： &#9;1000001110&#9; 1000001111100&#9;011111011111010&#10;实际接收： &#9;1000001110&#9; 1000001111100&#9;011111011111010&#10;移除填充后： 100000110&#9; 10000011110&#9; 0111111111110&lt;/p&gt;&#10;&lt;p&gt;作用：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;增加定时信息，有利于接收方同步，防止波形长时间无变化（防止连续很多相同电平，接收方可能数错）&lt;/li&gt;&#10;&lt;li&gt;将正常数据流与“错误帧”和“过载帧”区分（防止连续6个相同电平）&lt;/li&gt;&#10;&lt;li&gt;保持CAN发送数据的活跃状态，防止认为总线空闲（防止连续11个隐性电平1）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="波形实例"&gt;&lt;a href="#%e6%b3%a2%e5%bd%a2%e5%ae%9e%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;波形实例&#13;&#10;&lt;/h2&gt;&lt;h3 id="标准数据帧"&gt;&lt;a href="#%e6%a0%87%e5%87%86%e6%95%b0%e6%8d%ae%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;标准数据帧&#13;&#10;&lt;/h3&gt;&lt;p&gt;11位报文ID：0x555，&lt;/p&gt;&#10;&lt;p&gt;RTR = 0 数据帧，IDE = 0，标准格式&lt;/p&gt;&#10;&lt;p&gt;DLC = 0001(注意其中第一个1为位填充) = 1，一个字节数据&lt;/p&gt;&#10;&lt;p&gt;Data = 10101010 = 0xAA&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023191033968" class="gallery-image" data-flex-basis="1210px" data-flex-grow="504" height="255" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023191033968.png" srcset="https://zeseanblog.top/p/can/images/image-20251023191033968_hu_3426e5dcd4177d2e.png 800w, https://zeseanblog.top/p/can/images/image-20251023191033968.png 1286w" width="1286"&gt;&lt;/p&gt;&#10;&lt;h3 id="扩展数据帧"&gt;&lt;a href="#%e6%89%a9%e5%b1%95%e6%95%b0%e6%8d%ae%e5%b8%a7" class="header-anchor"&gt;&lt;/a&gt;扩展数据帧&#13;&#10;&lt;/h3&gt;&lt;p&gt;扩展数据帧，报文ID为0x0789ABCD，数据长度1字节，数据内容为0x56&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023192707532" class="gallery-image" data-flex-basis="1602px" data-flex-grow="667" height="220" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023192707532.png" srcset="https://zeseanblog.top/p/can/images/image-20251023192707532_hu_d3c3d340c1b2429d.png 800w, https://zeseanblog.top/p/can/images/image-20251023192707532.png 1469w" width="1469"&gt;&lt;/p&gt;&#10;&lt;h1 id="第三章"&gt;&lt;a href="#%e7%ac%ac%e4%b8%89%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;第三章&#13;&#10;&lt;/h1&gt;&lt;h2 id="接收方数据采样"&gt;&lt;a href="#%e6%8e%a5%e6%94%b6%e6%96%b9%e6%95%b0%e6%8d%ae%e9%87%87%e6%a0%b7" class="header-anchor"&gt;&lt;/a&gt;接收方数据采样&#13;&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;CAN总线无时钟线，总线设备通过一个约定的波特率方式确定每个数据位的时长&lt;/li&gt;&#10;&lt;li&gt;发送方以约定的位时长每个固定时间输出一个数据位&lt;/li&gt;&#10;&lt;li&gt;接收方以约定的位时长每个固定时间采样总线电平，输入一个数据位&lt;/li&gt;&#10;&lt;li&gt;理想采样是数据位中心附近&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="会遇到的问题"&gt;&lt;a href="#%e4%bc%9a%e9%81%87%e5%88%b0%e7%9a%84%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;会遇到的问题&#13;&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;接收方采样点没有对齐数据位中心附近&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;解决：第一个跳变沿对齐（硬同步）&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;接收方刚开始采样正确，但是时钟有误差，随着误差积累，采样点逐渐偏离&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;解决：采样点动态调节，弥补时钟误差（再同步）&lt;/p&gt;&#10;&lt;h2 id="位时序"&gt;&lt;a href="#%e4%bd%8d%e6%97%b6%e5%ba%8f" class="header-anchor"&gt;&lt;/a&gt;位时序&#13;&#10;&lt;/h2&gt;&lt;p&gt;因为要调节采样点，所以会对一个数据位时长进行细分&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;同步段（SS）&lt;/li&gt;&#10;&lt;li&gt;传播时间段（PTS）&lt;/li&gt;&#10;&lt;li&gt;相位缓冲段1（PBS1）&lt;/li&gt;&#10;&lt;li&gt;相位缓冲段2（PBS2）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;每个段又由若干个最小时间单位（Tq）构成&lt;/p&gt;&#10;&lt;p&gt;SS = 1Tq、PTS = 1&lt;del&gt;8Tq、PBS1 = 1&lt;/del&gt;8Tq、PBS2 = 2~8Tq&lt;/p&gt;&#10;&lt;img src="images/image-20251023193938293.png" alt="image-20251023193938293" style="zoom: 80%;" /&gt;&#10;&lt;p&gt;如果跳边沿在SS段，说明当前设备与波形达成同步，否则不同步，则需要调节时序使跳变沿正好在同步段&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023194302175" class="gallery-image" data-flex-basis="261px" data-flex-grow="108" height="146" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023194302175.png" width="159"&gt;&lt;/p&gt;&#10;&lt;h2 id="硬同步"&gt;&lt;a href="#%e7%a1%ac%e5%90%8c%e6%ad%a5" class="header-anchor"&gt;&lt;/a&gt;硬同步&#13;&#10;&lt;/h2&gt;&lt;p&gt;使第一次采样对齐&lt;/p&gt;&#10;&lt;p&gt;每个设备有一个位时序计时周期，当某设备发送报文，其他设备接收到SOF下降沿，会将位时序计时周期拨到SS段，与发送方保持同步（实际就是让第一个边沿段调整为SS段，类似于时区，绝对时刻不一样，但都规定为北京时间）&lt;/p&gt;&#10;&lt;p&gt;而此时接受段直接确定数据位采样点（PBS1和PBS2段中间）&lt;/p&gt;&#10;&lt;p&gt;硬同步解决没有对齐数据位中心附近，只要时钟没误差，就不会有问题&lt;/p&gt;&#10;&lt;img src="images/image-20251023200536351.png" alt="image-20251023200536351" style="zoom:67%;" /&gt;&#10;&lt;h2 id="再同步"&gt;&lt;a href="#%e5%86%8d%e5%90%8c%e6%ad%a5" class="header-anchor"&gt;&lt;/a&gt;再同步&#13;&#10;&lt;/h2&gt;&lt;p&gt;解决时钟误差，若数据位边沿逐渐偏离SS段，此时接收方根据再同步补偿宽度值（sjw，是最大的补偿，如果误差1tq，sjw2，则补偿1tq；若误差3tq，则补偿2tq）加长PBS1段，或缩短PBS2段&lt;/p&gt;&#10;&lt;p&gt;再同步发生在，第一个下降沿之后每个数据位跳变边沿&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023201451502" class="gallery-image" data-flex-basis="310px" data-flex-grow="129" height="500" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023201451502.png" width="647"&gt;&lt;/p&gt;&#10;&lt;h2 id="波特率计算"&gt;&lt;a href="#%e6%b3%a2%e7%89%b9%e7%8e%87%e8%ae%a1%e7%ae%97" class="header-anchor"&gt;&lt;/a&gt;波特率计算&#13;&#10;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;波特率 = 1/一个数据位的时长 = 1/（Tss+Tpts+Tpbs1+Tpbs2）&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;SS = 1Tq，PTS = 3Tq，PBS1 = 3Tq，PBS2 = 3Tq，Tq = 0.5us&lt;/p&gt;&#10;&lt;p&gt;则波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps&lt;/p&gt;&#10;&lt;h1 id="第四章"&gt;&lt;a href="#%e7%ac%ac%e5%9b%9b%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;第四章&#13;&#10;&lt;/h1&gt;&lt;h2 id="多设备同时发送遇到的问题"&gt;&lt;a href="#%e5%a4%9a%e8%ae%be%e5%a4%87%e5%90%8c%e6%97%b6%e5%8f%91%e9%80%81%e9%81%87%e5%88%b0%e7%9a%84%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;多设备同时发送遇到的问题&#13;&#10;&lt;/h2&gt;&lt;p&gt;CAN总线只有一差分信号线，同时只能有一个设备操作总线&lt;/p&gt;&#10;&lt;p&gt;若多设备同时又发送需求，该如何分配总线资源？&lt;/p&gt;&#10;&lt;h2 id="资源分配规则1-先占先得"&gt;&lt;a href="#%e8%b5%84%e6%ba%90%e5%88%86%e9%85%8d%e8%a7%84%e5%88%991-%e5%85%88%e5%8d%a0%e5%85%88%e5%be%97" class="header-anchor"&gt;&lt;/a&gt;资源分配规则1-先占先得&#13;&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;若当前有设备操作总线发送数据帧/遥控帧，则其他设备不可发（可发错误帧/过载帧）&lt;/li&gt;&#10;&lt;li&gt;任何设备检测到11连续隐性电平，认为总线空闲，才能发送&lt;/li&gt;&#10;&lt;li&gt;若有设备有发送需求要等待总线空闲&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;而位填充的适用范围&lt;/strong&gt;是从&lt;strong&gt;帧起始（SOF）到CRC序列结束&lt;/strong&gt;，不包括&lt;strong&gt;CRC界定符、ACK域和EOF段&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;此时有ACK界定符一个隐性，EOF7个隐性，只需再等三个隐性即可继续发送。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;但有可能不止一个信号在等待&lt;/strong&gt;，多个设备同时到来（总线仲裁）&lt;/p&gt;&#10;&lt;h2 id="资源分配规则2-非破坏性仲裁"&gt;&lt;a href="#%e8%b5%84%e6%ba%90%e5%88%86%e9%85%8d%e8%a7%84%e5%88%992-%e9%9d%9e%e7%a0%b4%e5%9d%8f%e6%80%a7%e4%bb%b2%e8%a3%81" class="header-anchor"&gt;&lt;/a&gt;资源分配规则2-非破坏性仲裁&#13;&#10;&lt;/h2&gt;&lt;p&gt;多设备发送需求同时到来，对仲裁段（ID+RTR）进行非破坏性仲裁，ID号小（优先级高）的取得控制权，ID号大（优先级低）仲裁失利，继续等待空闲&lt;/p&gt;&#10;&lt;p&gt;实现非破坏性仲裁两个需要的特性：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;线与特性：0 &amp;amp; X &amp;amp; X = 0，1 &amp;amp; 1 &amp;amp; 1 = 1&lt;/li&gt;&#10;&lt;li&gt;回读机制：设备发出一个数据位后，读回总线电平状态，确认电平被发送。发送0读回0，发送1读回不一定是1&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;仲裁：发出数据1，读回（回读机制）数据0（被其他设备线与了）&lt;/p&gt;&#10;&lt;h2 id="非破坏性仲裁过程"&gt;&lt;a href="#%e9%9d%9e%e7%a0%b4%e5%9d%8f%e6%80%a7%e4%bb%b2%e8%a3%81%e8%bf%87%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;非破坏性仲裁过程&#13;&#10;&lt;/h2&gt;&lt;p&gt;数据位从前到后依次比较，出现差异且数据位为1的设备仲裁失利&lt;/p&gt;&#10;&lt;p&gt;单元1在仲裁段中某一个数据位发送1，回读出0，判断有其他设备在发生，但自己优先级低，放弃发送。但是总线电平依旧是单元2的，并没有被破坏&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023204633782" class="gallery-image" data-flex-basis="381px" data-flex-grow="159" height="594" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023204633782.png" srcset="https://zeseanblog.top/p/can/images/image-20251023204633782_hu_d41f194ff4f8d877.png 800w, https://zeseanblog.top/p/can/images/image-20251023204633782.png 945w" width="945"&gt;&lt;/p&gt;&#10;&lt;h2 id="数据帧和遥控帧优先级"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae%e5%b8%a7%e5%92%8c%e9%81%a5%e6%8e%a7%e5%b8%a7%e4%bc%98%e5%85%88%e7%ba%a7" class="header-anchor"&gt;&lt;/a&gt;数据帧和遥控帧优先级&#13;&#10;&lt;/h2&gt;&lt;p&gt;数据帧和遥控帧ID号一样时，数据帧的优先级高于遥控帧（RTR决断，因为RTR = 0 为数据帧）&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023205811312" class="gallery-image" data-flex-basis="493px" data-flex-grow="205" height="460" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023205811312.png" srcset="https://zeseanblog.top/p/can/images/image-20251023205811312_hu_120149f9928a316e.png 800w, https://zeseanblog.top/p/can/images/image-20251023205811312.png 945w" width="945"&gt;&lt;/p&gt;&#10;&lt;h2 id="标准格式和拓展格式的优先级"&gt;&lt;a href="#%e6%a0%87%e5%87%86%e6%a0%bc%e5%bc%8f%e5%92%8c%e6%8b%93%e5%b1%95%e6%a0%bc%e5%bc%8f%e7%9a%84%e4%bc%98%e5%85%88%e7%ba%a7" class="header-anchor"&gt;&lt;/a&gt;标准格式和拓展格式的优先级&#13;&#10;&lt;/h2&gt;&lt;p&gt;标准格式11位ID号和扩展格式29位ID号的高11位一样时，标准格式的优先级高于扩展格式（SRR必须始终为1，以保证此要求）&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251023205932744" class="gallery-image" data-flex-basis="432px" data-flex-grow="180" height="525" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251023205932744.png" srcset="https://zeseanblog.top/p/can/images/image-20251023205932744_hu_816885b17494cda9.png 800w, https://zeseanblog.top/p/can/images/image-20251023205932744.png 945w" width="945"&gt;&lt;/p&gt;&#10;&lt;h1 id="第五章"&gt;&lt;a href="#%e7%ac%ac%e4%ba%94%e7%ab%a0" class="header-anchor"&gt;&lt;/a&gt;第五章&#13;&#10;&lt;/h1&gt;&lt;h2 id="错误类型"&gt;&lt;a href="#%e9%94%99%e8%af%af%e7%b1%bb%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;错误类型&#13;&#10;&lt;/h2&gt;&lt;p&gt;位错误、填充错误、CRC错误、格式错误、应答错误&lt;/p&gt;&#10;&lt;img src="images/image-20251023210342121.png" alt="image-20251023210342121" style="zoom:67%;" /&gt;&#10;&lt;h2 id="错误状态"&gt;&lt;a href="#%e9%94%99%e8%af%af%e7%8a%b6%e6%80%81" class="header-anchor"&gt;&lt;/a&gt;错误状态&#13;&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;主动错误状态参与通信并检测到错误时发送主动错误帧（6个0），可以破坏别的设备的数据&lt;/li&gt;&#10;&lt;li&gt;而频繁发送主动错误，说明这个设备不太可靠，就转到被动错误，收回他破坏其他设备通信的权利&lt;/li&gt;&#10;&lt;li&gt;若还是频繁被动错误，则进入总线关闭&lt;/li&gt;&#10;&lt;li&gt;如何判断：每个设备内部管理一个TEC和REC，根据TEC和REC确定自己状态（信誉分）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;img src="images/image-20251023212056785.png" alt="image-20251023212056785" style="zoom:67%;" /&gt;&#10;&lt;h2 id="错误计数器"&gt;&lt;a href="#%e9%94%99%e8%af%af%e8%ae%a1%e6%95%b0%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;错误计数器&#13;&#10;&lt;/h2&gt;&lt;p&gt;信誉分积分：&lt;/p&gt;&#10;&lt;img src="images/image-20251023212321573.png" alt="image-20251023212321573" style="zoom:80%;" /&gt;&#10;&lt;h1 id="stm32-can外设"&gt;&lt;a href="#stm32-can%e5%a4%96%e8%ae%be" class="header-anchor"&gt;&lt;/a&gt;STM32 CAN外设&#13;&#10;&lt;/h1&gt;&lt;ul&gt;&#10;&lt;li&gt;STM32内置bxCAN支持CAN2.0A和2.0B，可自动发报文，程序只需处理报文数据&lt;/li&gt;&#10;&lt;li&gt;波特率最高1mbps&lt;/li&gt;&#10;&lt;li&gt;3个可配置优先级的发送邮箱&lt;/li&gt;&#10;&lt;li&gt;2个3级深度接收FIFO&lt;/li&gt;&#10;&lt;li&gt;时间触发通信、自动离线恢复、自动唤醒、禁止自动重传、接收FIFO溢出处理方式可配置、发送优先级可配置、双CAN模式&lt;/li&gt;&#10;&lt;li&gt;STM32F103C8T6 CAN资源：CAN1&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="第一节"&gt;&lt;a href="#%e7%ac%ac%e4%b8%80%e8%8a%82" class="header-anchor"&gt;&lt;/a&gt;第一节&#13;&#10;&lt;/h2&gt;&lt;h3 id="can网络拓扑"&gt;&lt;a href="#can%e7%bd%91%e7%bb%9c%e6%8b%93%e6%89%91" class="header-anchor"&gt;&lt;/a&gt;CAN网络拓扑&#13;&#10;&lt;/h3&gt;&lt;p&gt;&lt;img alt="image-20251024152812279" class="gallery-image" data-flex-basis="545px" data-flex-grow="227" height="411" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024152812279.png" srcset="https://zeseanblog.top/p/can/images/image-20251024152812279_hu_4e654ea6ccdb2f2f.png 800w, https://zeseanblog.top/p/can/images/image-20251024152812279.png 934w" width="934"&gt;&lt;/p&gt;&#10;&lt;p&gt;STM32F103C8T6 CAN引脚默认复用&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024153118991" class="gallery-image" data-flex-basis="1295px" data-flex-grow="539" height="173" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024153118991.png" srcset="https://zeseanblog.top/p/can/images/image-20251024153118991_hu_b0dec2e0190a9337.png 800w, https://zeseanblog.top/p/can/images/image-20251024153118991.png 934w" width="934"&gt;&lt;/p&gt;&#10;&lt;p&gt;重定义&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024153129671" class="gallery-image" data-flex-basis="5741px" data-flex-grow="2392" height="52" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024153129671.png" srcset="https://zeseanblog.top/p/can/images/image-20251024153129671_hu_9efacbf4ca291fc4.png 800w, https://zeseanblog.top/p/can/images/image-20251024153129671.png 1244w" width="1244"&gt;&lt;/p&gt;&#10;&lt;h3 id="can收发器电路"&gt;&lt;a href="#can%e6%94%b6%e5%8f%91%e5%99%a8%e7%94%b5%e8%b7%af" class="header-anchor"&gt;&lt;/a&gt;CAN收发器电路&#13;&#10;&lt;/h3&gt;&lt;p&gt;注意TX，RX接法与串口区分&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024153323173" class="gallery-image" data-flex-basis="592px" data-flex-grow="246" height="281" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024153323173.png" width="694"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024153328481" class="gallery-image" data-flex-basis="436px" data-flex-grow="181" height="382" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024153328481.png" width="694"&gt;&lt;/p&gt;&#10;&lt;h2 id="第二节"&gt;&lt;a href="#%e7%ac%ac%e4%ba%8c%e8%8a%82" class="header-anchor"&gt;&lt;/a&gt;第二节&#13;&#10;&lt;/h2&gt;&lt;h3 id="can框图"&gt;&lt;a href="#can%e6%a1%86%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;CAN框图&#13;&#10;&lt;/h3&gt;&lt;img src="images/image-20251024154247741.png" alt="image-20251024154247741" style="zoom:67%;" /&gt;&#10;&lt;p&gt;对于STM32F103C8T6，没有CAN2，只有CAN1。&lt;/p&gt;&#10;&lt;p&gt;通过读写以下寄存器对CAN电路进行配置：&lt;/p&gt;&#10; &lt;img src="images/image-20251024154441586.png" alt="image-20251024154441586" style="zoom: 50%;" /&gt;&#10;&lt;p&gt;3个主发送邮箱，每个可以存入一个CAN报文，若想发送一个报文，可以将报文放入空置邮箱，在设置寄存器请求发送&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024154756599" class="gallery-image" data-flex-basis="160px" data-flex-grow="66" height="224" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024154756599.png" width="150"&gt;&lt;/p&gt;&#10;&lt;p&gt;接收部分包括过滤器和2个FIFO，过滤器设置过滤规则，告诉硬件想要的ID的报文，如果硬件收到相应ID的报文，将报文放入FIFO；如果都没用，就抛弃，减轻软件负担。&lt;/p&gt;&#10;&lt;p&gt;FIFO：先入先出，类似于队列，等待CPU读取&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024155100846" class="gallery-image" data-flex-basis="405px" data-flex-grow="168" height="176" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024155100846.png" width="297"&gt;&lt;/p&gt;&#10;&lt;h3 id="can基本结构"&gt;&lt;a href="#can%e5%9f%ba%e6%9c%ac%e7%bb%93%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;CAN基本结构&#13;&#10;&lt;/h3&gt;&lt;p&gt;&lt;img alt="image-20251024155405878" class="gallery-image" data-flex-basis="432px" data-flex-grow="180" height="544" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024155405878.png" srcset="https://zeseanblog.top/p/can/images/image-20251024155405878_hu_3d28aa830b712f95.png 800w, https://zeseanblog.top/p/can/images/image-20251024155405878.png 980w" width="980"&gt;&lt;/p&gt;&#10;&lt;h3 id="发送过程"&gt;&lt;a href="#%e5%8f%91%e9%80%81%e8%bf%87%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;发送过程&#13;&#10;&lt;/h3&gt;&lt;p&gt;选择空置邮箱-写入报文-配置寄存器请求发送&lt;/p&gt;&#10;&lt;p&gt;RQCP：请求完成&lt;/p&gt;&#10;&lt;p&gt;TXOK：发送成功&lt;/p&gt;&#10;&lt;p&gt;TME = 1：发送邮箱空&lt;/p&gt;&#10;&lt;img src="images/image-20251024160418572.png" alt="image-20251024160418572" style="zoom: 50%;" /&gt;&#10;&lt;p&gt;发送流程：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;默认TME=1处于空置状态时，TXRQ（请求发送控制位）=1（产生发送请求）&lt;/li&gt;&#10;&lt;li&gt;进入挂号状态TME=0，排队等到该邮箱为最高优先级发送报文&lt;/li&gt;&#10;&lt;li&gt;进入预定状态，若优先级被比下去，则退回挂号状态&lt;/li&gt;&#10;&lt;li&gt;处于预定的报文，探测到CAN总线=IDLE空闲，管理员将报文发送到CAN总线&lt;/li&gt;&#10;&lt;li&gt;发送成功回到空置状态，发送失败时若启用NART=0（禁止自动重发）回到空置，若禁止，NART=1则回到预定等待发送（比如总线仲裁失败）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="接收过程"&gt;&lt;a href="#%e6%8e%a5%e6%94%b6%e8%bf%87%e7%a8%8b" class="header-anchor"&gt;&lt;/a&gt;接收过程&#13;&#10;&lt;/h3&gt;&lt;p&gt;接收到一个报文→匹配过滤器后进入FIFO 0或FIFO 1→CPU读取&lt;/p&gt;&#10;&lt;p&gt;FMP：报文数目&lt;/p&gt;&#10;&lt;p&gt;FOVR：FIFO溢出&lt;/p&gt;&#10;&lt;img src="images/image-20251024163116807.png" alt="image-20251024163116807" style="zoom:50%;" /&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;接收到一个报文时，FMP=1,FOVR=0，依次接收后FMP递增&lt;/li&gt;&#10;&lt;li&gt;有效报文存满FULL置1，在收到有效报文进入溢出FOVR=1&lt;/li&gt;&#10;&lt;li&gt;若读取一个报文，RFOM=1，释放一次邮箱&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;注意：溢出状态释放一次是挂号2&lt;/p&gt;&#10;&lt;h3 id="发送和接收配置位"&gt;&lt;a href="#%e5%8f%91%e9%80%81%e5%92%8c%e6%8e%a5%e6%94%b6%e9%85%8d%e7%bd%ae%e4%bd%8d" class="header-anchor"&gt;&lt;/a&gt;发送和接收配置位&#13;&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;NART：NART=1关闭自动重传，CAN报文只发送一次，不管发送结果如何；置0，自动重传，直到发送成功&lt;/li&gt;&#10;&lt;li&gt;TXFP：TXFP=1，优先级按发送请求的顺序；置0，优先级按报文ID，标志符小的先发送（标志符相等，邮箱号小的先发送）&lt;/li&gt;&#10;&lt;li&gt;RFLM：置1，接收FIFO锁定，FIFO溢出，新报文丢弃；置0，FOFO溢出后最后收到报文被覆盖&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="标识符过滤器"&gt;&lt;a href="#%e6%a0%87%e8%af%86%e7%ac%a6%e8%bf%87%e6%bb%a4%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;标识符过滤器&#13;&#10;&lt;/h3&gt;&lt;p&gt;x可以表示0-13，每个过滤器都有一套电路&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;每个过滤器由2个32位寄存器组成，R1[31:0] R2[31:0]&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;位宽设置，FSCx=0，16位，FSCx=1,32位&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;若只有标准ID，则16位足矣，若有标准，有拓展需要用到32位&lt;/li&gt;&#10;&lt;li&gt;16位的话两个32位寄存器能写4个ID号，32位写两个&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;模式设置，&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;FBMx=0，屏蔽模式&lt;/p&gt;&#10;&lt;p&gt;允许一类，使用了类似掩码功能，屏蔽的是不需要的ID号的位，如只需要用前三位，可以ID段前三位写001xxxxxxxx，屏蔽写11100000000,过滤ID前三位为001&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;FBMx=1，列表模式（允许个别）&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;关联到队列，FFAx=0，关联FIFO0，否则关联FIFO1&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;激活FACTx:FACTx=0，禁用，否则启用&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024170732729" class="gallery-image" data-flex-basis="269px" data-flex-grow="112" height="667" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024170732729.png" width="748"&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;列表模式&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;想要的ID号写入R1或R2寄存器中&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;位宽32位&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;STID高11位为标准ID&lt;/li&gt;&#10;&lt;li&gt;前29位是拓展ID&lt;/li&gt;&#10;&lt;li&gt;过滤拓展ID，IDE=1，过滤标准ID，IDE=0&lt;/li&gt;&#10;&lt;li&gt;RTR=1，过滤遥控帧，RTR=0,过滤数据帧&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;位宽16位&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;只使用标准ID，4个16位&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;屏蔽模式&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;ID号过多时使用&lt;/li&gt;&#10;&lt;li&gt;采用位与屏蔽，类似掩码功能&lt;/li&gt;&#10;&lt;li&gt;ID段有效位写实际，对应屏蔽位写1&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="过滤器配置示例"&gt;&lt;a href="#%e8%bf%87%e6%bb%a4%e5%99%a8%e9%85%8d%e7%bd%ae%e7%a4%ba%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;过滤器配置示例&#13;&#10;&lt;/h3&gt;&lt;p&gt;&lt;img alt="image-20251024190102576" class="gallery-image" data-flex-basis="498px" data-flex-grow="207" height="525" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024190102576.png" srcset="https://zeseanblog.top/p/can/images/image-20251024190102576_hu_61d1fe99d93cdfb3.png 800w, https://zeseanblog.top/p/can/images/image-20251024190102576.png 1091w" width="1091"&gt;&lt;/p&gt;&#10;&lt;h2 id="第三节"&gt;&lt;a href="#%e7%ac%ac%e4%b8%89%e8%8a%82" class="header-anchor"&gt;&lt;/a&gt;第三节&#13;&#10;&lt;/h2&gt;&lt;h3 id="测试模式"&gt;&lt;a href="#%e6%b5%8b%e8%af%95%e6%a8%a1%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;测试模式&#13;&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;静默模式：用于分析CAN总线的活动，不会对总线造成影响&lt;/li&gt;&#10;&lt;li&gt;环回模式：用于自测试，同时发送的报文可以在CAN_TX引脚上检测到&lt;/li&gt;&#10;&lt;li&gt;环回静默模式：用于热自测试，自测的同时不会影响CAN总线&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024192633712" class="gallery-image" data-flex-basis="827px" data-flex-grow="344" height="396" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024192633712.png" srcset="https://zeseanblog.top/p/can/images/image-20251024192633712_hu_c2b9f0c6820be399.png 800w, https://zeseanblog.top/p/can/images/image-20251024192633712.png 1366w" width="1366"&gt;&lt;/p&gt;&#10;&lt;h3 id="工作模式"&gt;&lt;a href="#%e5%b7%a5%e4%bd%9c%e6%a8%a1%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;工作模式&#13;&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;初始化模式：用于配置CAN时禁止收发&lt;/li&gt;&#10;&lt;li&gt;正常模式&lt;/li&gt;&#10;&lt;li&gt;睡眠模式：低功耗，CAN外设时钟停止，可以软件唤醒或硬件自动唤醒&lt;/li&gt;&#10;&lt;li&gt;AWUM：置1，自动唤醒，一旦检测到CAN总线活动，硬件就自动清零SLEEP，唤醒CAN外设；置0，手动唤醒，软件清零SLEEP，唤醒CAN外设&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;img src="images/image-20251024193220836.png" alt="image-20251024193220836" style="zoom:67%;" /&gt;&#10;&lt;h3 id="位时间特性"&gt;&lt;a href="#%e4%bd%8d%e6%97%b6%e9%97%b4%e7%89%b9%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;位时间特性&#13;&#10;&lt;/h3&gt;&lt;p&gt;STM32中，PDS和PBS1合在一起&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;SS = 1Tq&#10;BS1 = 1&lt;del&gt;16Tq&#10;BS2 = 1&lt;/del&gt;8Tq&lt;/li&gt;&#10;&lt;li&gt;SJW=1~4Tq&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="image-20251024194312171" class="gallery-image" data-flex-basis="392px" data-flex-grow="163" height="546" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://zeseanblog.top/p/can/images/image-20251024194312171.png" srcset="https://zeseanblog.top/p/can/images/image-20251024194312171_hu_d16765102ffe9b1c.png 800w, https://zeseanblog.top/p/can/images/image-20251024194312171.png 892w" width="892"&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;波特率=APB1时钟频率/分频系数/1位Tq数&lt;/p&gt;&#10;&lt;p&gt;=36Mhz/(BRP[9:0]+1)/(1+(TS1[3:0]+1)+(TS2[2:0]+1))&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="中断"&gt;&lt;a href="#%e4%b8%ad%e6%96%ad" class="header-anchor"&gt;&lt;/a&gt;中断&#13;&#10;&lt;/h3&gt;&lt;p&gt;CAN外设占用4个专用中断向量&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;发送中断：发送邮箱空时产生&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;FIFO 0中断：收到一个报文/FIFO 0满/FIFO 0溢出时产生&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;FIFO 1中断：收到一个报文/FIFO 1满/FIFO 1溢出时产生&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;状态改变错误中断：出错/唤醒/进入睡眠时产生&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;中断发生条件：&lt;/p&gt;&#10;&lt;img src="images/image-20251024195020980.png" alt="image-20251024195020980" style="zoom:67%;" /&gt;&#10;</description></item></channel></rss>