news 2026/3/24 13:27:02

解码CAN总线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
解码CAN总线

CAN总线概述

CAN总线(Controller Area Network,控制器局域网络)是多主控、串行通信的总线标准,由德国博世(Bosch)公司于1980年代为汽车电子系统研发,初衷是解决汽车内部各控制单元(发动机、刹车、空调等)间布线复杂、通信低效的问题,核心优势是高可靠性、强实时性、低成本

目前除汽车电子外,已广泛应用于工业自动化、楼宇控制、医疗设备、轨道交通、船舶电子等领域,核心实现多节点通过单一总线完成实时数据共享。

CAN总线协议规范

CAN协议分为物理层数据链路层,物理层定义底层硬件传输规则,数据链路层定义数据帧格式、仲裁、错误处理等逻辑规则,是CAN通信的核心。

物理层

物理层是CAN总线的硬件基础,定义了传输介质、信号电平、拓扑结构、通信速率等关键参数,确保数据在物理总线上的可靠传输。

传输介质

CAN总线首选带屏蔽层的双绞线,也可使用光纤、同轴电缆,三者核心区别如下(双绞线的CAN_H、CAN_L传输差分信号,是抗干扰的核心设计):

传输介质特点适用场景备注
双绞线(推荐)带屏蔽层,双线路传输差分信号,抗干扰能力强汽车电子、工业控制等常规CAN网络总线两端需接120Ω终端电阻,匹配特性阻抗
光纤抗电磁干扰极强,传输距离远,信号衰减小强电磁干扰环境(工厂电机、高压设备区)需专用光纤收发器,成本较高
同轴电缆单芯屏蔽结构,特性阻抗50Ω/75Ω,抗干扰中等特定工业场景、早期CAN应用传输速率/距离介于双绞线与光纤之间

信号电平

CAN总线通过CAN_H(高电平线)和CAN_L(低电平线)的差分电压判断逻辑电平,仅分为显性电平(逻辑0)和隐性电平(逻辑1)显性电平可强制覆盖隐性电平(优先级更高),高速CAN的电平标准为:

逻辑状态CAN_H电压CAN_L电压差分电压总线状态
显性电平(0)3.5V1.5V2V有节点主动发送数据
隐性电平(1)2.5V2.5V0V总线空闲/低优先级节点发送

拓扑结构

CAN总线采用总线型拓扑,所有节点并联在主干总线上,分支线长度≤0.3米(避免信号反射),理论支持110个节点,实际建议≤30个(保证可靠性),高速CAN和低速CAN的拓扑设计不同:

  • 高速CAN(ISO 11898)闭环结构,总线两端接120Ω终端电阻,吸收信号反射,防止波形失真,适用于对速率要求高的场景(如发动机控制);
  • 低速CAN(ISO 11519-2)开环结构,总线两端接2.2kΩ终端电阻,搭建简便、成本低,适用于对速率要求低的场景(如车身灯光、电动窗)。

通信速率

CAN总线的通信速率由ISO标准界定,ISO 11898(高速)为125kbps~1Mbps,实际推荐最高500kbps(保证可靠性);ISO 11519-2(低速)为125kbps以下,速率与总线最大长度成反比(速率越高,传输距离越短)。

汽车领域按速率将CAN分为四类应用,适配不同系统需求:

ISO标准核心区别

ISO 11898(高速)和ISO 11519-2(低速)在数据链路层定义一致,物理层差异显著,核心参数区别如下:

专用驱动IC

高速CAN和低速CAN因物理层规格不同,需搭配专用驱动IC(收发器),核心配套型号如下:

标准对应驱动IC
ISO 11898(高速)HA13721RPJE、PCA82C250、Si9200、CF15
ISO 11519-2(低速)PCA82C252、TJA1053、SN65LBC032

数据链路层

数据链路层是CAN总线的逻辑核心,定义了帧结构、仲裁机制、时序分析、同步方式、错误处理等规则,核心是将数据打包为进行传输,确保多节点通信的有序、可靠。

帧的类型

CAN总线通过5种基本帧类型实现节点间通信协调,其中数据帧、遥控帧11位ID标准帧29位ID扩展帧两种格式,5种帧的核心作用和特点如下:

帧类型核心作用关键特点
数据帧发送节点向接收节点传输实际数据CAN核心帧,含数据段,分标准/扩展格式
遥控帧接收节点向目标节点请求数据无数据段,ID需与目标数据帧一致,RTR位为1
错误帧节点检测到传输错误时,通知其他节点无ID/数据段,分主动/被动,强制中断异常传输
过载帧接收节点因忙碌(缓冲区满)通知发送节点延迟传输流量控制机制,非错误处理,仅在帧间隔发送
帧间隔分隔连续的数据帧/遥控帧为接收节点预留处理时间,避免帧冲突

数据帧

用于传输实际数据的核心帧,标准格式(11位ID)的字段结构为7个部分,扩展格式仅仲裁段增加18位扩展ID,其余字段一致,标准格式字段详情:

字段名称位数功能描述
帧起始(SOF)1单个显性位(0),标志帧传输开始,实现节点同步
仲裁段1211位ID(越小优先级越高(MSB))+1位RTR位(固定0,区分遥控帧)
控制段61位IDE位(0=标准帧)+1位保留位+4位DLC位(0~8,指示数据字节数)
数据段0~64传输的有效数据,长度由DLC决定,最大8字节
CRC段1615位CRC校验码+1位隐性界定符,检测传输错误
ACK段2包含1位ACK槽(发送节点发送隐性位1,接收节点正确接收后发送显性位0应答)和1位ACK界定符(隐性位1)
帧结束(EOF)77个连续隐性位(1),标志帧传输结束

帧起始

  • 结构:固定为1 个位的显性电平(逻辑 0),是数据帧传输的起始标志;
  • 核心作用:实现总线上所有节点的通信同步,让所有节点统一识别帧传输的开始时刻;
  • 总线逻辑:CAN 总线执行 逻辑线 “与”规则,显性电平具有绝对优先级—— 只要有一个节点输出显性电平,总线整体即为显性电平;仅当所有节点都输出隐性电平时,总线才为隐性电平(逻辑 1)。

仲裁段

  • 核心作用:定义数据帧的优先级,解决 CAN 多主通信模式下多节点同时发送的总线冲突,采用非破坏性仲裁机制(仲裁失利节点仅停止发送,不破坏已传输数据,无数据丢失);
  • 格式差异
    • 标准格式:共 12 位,包含11 位 ID+1 位 RTR 位(远程发送请求位,数据帧固定为 0,显性电平);
    • 扩展格式:共 32 位,包含 11 位基本 ID+1 位 SRR 位 + 1 位 IDE 位 + 18 位扩展 ID+1 位 RTR 位,整体为 29 位 ID+3 位控制位;
  • 仲裁规则
    • 位逐位比较,显性位(0)优先于隐性位(1),ID 值越小,显性位占比越高,优先级越高;
    • 扩展格式仲裁时,先比较 11 位基本 ID,基本 ID 相同时再比较 18 位扩展 ID,确保优先级唯一;
    • 标准格式 11 位 ID 有硬性规定:高 7 位禁止全为隐性电平(1)(即禁止 ID=1111111XXXX),避免 ID 识别混淆,保障数据传输的有效性;
  • 特殊仲裁:同 ID 的数据帧与遥控帧竞争时,数据帧 RTR=0(显性)优先于遥控帧 RTR=1(隐性)。

控制段

  • 结构:固定为6 个位,标准格式与扩展格式的构成略有差异,核心包含IDE 位(标识符扩展位)保留位(r0/r1)DLC 位(数据长度码)
  • 各子位规则
    • IDE 位:标准格式固定为 0(显性),扩展格式固定为 1(隐性),用于区分帧格式;
    • 保留位:标准格式为 r0,扩展格式为 r0+r1,发送方必须以显性电平发送,接收方可接收显性、隐性或任意组合电平,为协议后续扩展预留;
    • DLC 位:占4 个位,是数据长度码,用于指示数据段的有效字节数,仅支持0~8 字节;接收方对 DLC=9~15 的情况不视为错误,仅按实际数据字节数解析;
  • 核心作用:传递帧格式标识、数据段长度信息,为协议扩展预留空间,是数据帧与后续数据段的 “衔接字段”。

数据段

  • 结构:长度为0~8 字节(0~64 位),由 DLC 位的数值决定,0 字节表示无有效数据传输;
  • 核心作用:承载 CAN 总线传输的实际有效数据,如传感器采集的数值、设备的控制指令、状态信息等;
  • 传输规则:数据传输遵循MSB(最高位)优先原则,即从数据的最高位开始依次发送。
  • 特点:是数据帧的核心载荷段,也是 CAN 总线通信的最终数据载体,字节长度灵活适配不同场景的传输需求。

CRC 段

  • 结构:固定为16 个位,包含15 位 CRC 顺序(CRC 校验码)+1 位 CRC 界定符(固定为隐性电平 1);
  • 核心作用检测帧传输过程中的错误,如信号干扰、位翻转等,是 CAN 总线的核心检错机制;
  • 校验规则
    • 采用15 位 CRC 多项式进行计算,生成多项式为:x15+x14+x10+x8+x7+x4+x3+1;
    • CRC 校验码的计算范围包含:帧起始、仲裁段、控制段、数据段的所有位流;
    • 发送方按上述规则计算 CRC 值并随帧发送,接收方以相同算法重新计算,若二者不一致,接收方判定传输错误并立即发送错误帧。
  • CRC 界定符:固定为隐性电平,用于分隔 CRC 校验码与后续的 ACK 段,避免字段混淆。

ACK 段

  • 结构:固定为2 个位,包含1 位 ACK 槽+1 位 ACK 界定符(固定为隐性电平 1);
  • 核心作用确认数据帧是否被正确接收,是 CAN 总线的核心应答机制,保障数据传输的可靠性;
  • 应答规则
    • 发送方在 ACK 段的两个位均发送隐性电平(1)
    • 总线上所有接收到正确帧(无 CRC 错误、格式错误等)的节点,在ACK 槽发送显性电平(0),通过显性电平覆盖发送方的隐性电平,完成 “应答”;
    • 若发送方在 ACK 槽检测到的是隐性电平,说明无节点正确接收该帧,判定传输失败,触发自动重发机制
  • ACK 界定符:固定为隐性电平,用于分隔 ACK 槽与后续的帧结束段,标志应答过程结束。

帧结束

  • 结构:固定为7 个连续的隐性电平(1),是数据帧传输的结束标志;
  • 核心作用
    • 明确界定单帧数据的传输边界,避免相邻帧的数据混淆、错误拼接,降低通信错误概率;
    • 为接收节点预留短暂的处理时间,让接收节点完成当前帧的解析、存储后,再准备接收下一帧;
  • 特点:7 个连续隐性电平是数据帧的固定结束标识,总线上所有节点检测到该字段后,判定当前帧传输完成,总线进入帧间隔阶段。

遥控帧

用于请求数据,无数据段,标准格式字段与数据帧基本一致,核心差异为RTR位固定1,DLC位需与目标数据帧一致(指示期望接收的字节数),传输流程:

  • 接收节点发送遥控帧(指定ID和DLC);
  • 经总线仲裁后,目标发送节点收到请求;
  • 发送节点发送同ID、同DLC的数据帧;
  • 接收节点解析数据帧,完成数据获取。
字段名称位数功能描述
帧起始(SOF)1单个显性位(0),标志帧传输开始,与数据帧相同
仲裁段12包含:
1) 11位ID(与目标数据帧的ID一致,用于指定请求的数据对象)
2) 1位RTR位(远程发送请求位,遥控帧固定为1,与数据帧的RTR=0形成区分)
控制段6包含:
1) 1位IDE位(标识符扩展位,标准格式固定为0)
2) 1位r0位(保留位,固定为0)
3) 4位DLC位(数据长度码,需与请求的数据帧DLC一致,指示期望接收的数据字节数)
CRC段1615位CRC校验码 + 1位CRC界定符(隐性位1),与数据帧结构相同
ACK段21位ACK槽(接收节点应答显性位0) + 1位ACK界定符(隐性位1),与数据帧相同
帧结束(EOF)77个连续隐性位(1),标志帧传输结束,与数据帧相同

错误帧

节点检测到传输错误时发送,由错误标志错误界定符组成(总长度14位)。

主动错误帧字段结构表

字段名称位数功能描述
主动错误标志66个连续的显性位(0),强制打断当前传输,通知其他节点“检测到错误”
错误界定符88个连续的隐性位(1),用于结束错误帧,使总线恢复到空闲状态

被动错误帧字段结构表

字段名称位数功能描述
被动错误标志66个连续的隐性位(1),无法主动打断总线传输,仅在总线空闲时发送
错误界定符8同主动错误帧(8个隐性位1),用于结束错误帧

CAN总线定义5种核心错误类型,节点检测到任意错误即发送错误帧:位错误、填充错误、CRC错误、格式错误、ACK错误。

过载帧

用于流量控制,由过载标志(6个显性位)过载界定符(8个隐性位)组成(总长度14位),仅在帧间隔期间发送,通知发送节点延迟传输,避免数据丢失。

字段名称位数功能描述
过载标志66个连续的显性位(0),用于通知总线节点“接收节点暂时忙碌”
过载界定符88个连续的隐性位(1),用于结束过载帧,使总线恢复同步

帧间隔

分隔数据帧/遥控帧的时间间隔,由间歇段(2个隐性位)总线空闲段(≥1个隐性位)组成,核心作用是为接收节点预留数据处理时间,错误帧、过载帧前不插入帧间隔

字段名称位数功能描述
间歇场2位固定为2个隐性位(1),所有节点在此期间禁止发送新帧,确保接收节点完成当前帧处理
总线空闲场≥1位连续的隐性位(1),长度不固定。若总线空闲场持续1位以上,发送节点可开始发送新帧;若插入过载帧,此场会被延长

仲裁机制

CAN总线是多主控总线(所有节点均可主动发数据),需通过仲裁机制解决多节点同时发送的冲突,核心为非破坏性仲裁(仲裁失败的节点仅停止发送,不破坏已传输数据,总线无数据丢失),核心规则:

  • 总线空闲时,最先发送的节点获得发送权;
  • 多节点同时发送时,从仲裁段第一位开始逐位比较,显性位(0)优先于隐性位(1),连续输出显性位最多的节点继续发送;

  • ID值越小,优先级越高(MSB);
  • 同ID的数据帧与遥控帧仲裁时,数据帧RTR=0(显性)优先于遥控帧RTR=1(隐性);

  • 同ID的标准帧与扩展帧仲裁时,标准帧优先级更高。

时序分析

CAN总线为异步通信(无时钟信号线),通过位时序补偿节点间的时钟偏差和信号传播延迟,确保所有节点同步采样总线电平。

  • 时间量子(TQ):位时序的最小单位,由CAN控制器系统时钟分频得到;
  • 位时间:单个逻辑位的传输时间,由4个段组成,总长度为8~25个TQ,可自定义配置;

  • 采样点(SP):读取总线电平的时刻,位于位时间的60%~80%处(信号最稳定),采样值即为该位的逻辑值。

位时间的4个段核心作用:

段名称英文缩写位数(TQ)核心作用
同步段SS1实现节点时序同步,信号跳变沿最好出现在此段
传播时间段PTS1~8吸收信号的物理延迟(发送/接收/总线传播延迟)
相位缓冲段1PBS11~8补偿信号跳变沿的误差,重同步时可延长
相位缓冲段2PBS22~8补偿时钟累积误差,重同步时可缩短

同步跳转宽度(SJW)(1~4TQ)定义了重同步时的最大调整范围,通过延长PS1或缩短PS2来校准位时间,超过了SJW,就会被强制按总线的“标准时间”对齐,避免节点时钟偏差过大导致采样错误。

通信速率计算

CAN 总线为异步通信,无专用时钟线,总线上所有通讯节点需统一约定两个核心参数,即可唯一确定 CAN 通讯的波特率:

  • 单个 时间量子(Tq) 的时间长度(由 CAN 控制器系统时钟分频得到);
  • 每个数据位所占的 Tq 总数(即位时间,由 SS+PTS+PS1+PS2 的 Tq 数之和构成)。

波特率配置示例(8MHz 系统时钟,1Mbps 波特率)

基础参数计算

  • 系统时钟:8 MHz
  • 分频系数:64 分频
  • 单个 Tq 时间长度:Tq=8MHz/64=125ns
  • 位时间占用 Tq 数:8 Tq
  • 总位时间:8×125ns=1μs
  • 对应波特率:1/1μs=1Mbps

位时序各段 Tq 分配(8Tq 总长度)

表格

位时序段英文缩写分配 Tq 数对应时间功能说明
同步段SS1 Tq125ns实现节点时序同步,信号跳变沿优选此段
传播时间段PTS1 Tq125ns补偿短距离总线的物理延迟(发送 / 接收 / 传播延迟)
相位缓冲段 1PS14 Tq500ns补偿信号跳变沿误差,重同步时可延长
相位缓冲段 2PS22 Tq250ns补偿时钟累积误差,重同步时可缩短

同步跳转宽度(SJW)配置

  • SJW 分配:1 Tq
  • 最大调整时间:125ns
  • 采样点位置:位于 PS1 结束处,即第 6 Tq(SS+PTS+PS1),占位时间的 75%,确保信号稳定后采样。

同步方式

CAN总线通过两种同步方式确保所有节点的采样点对齐,保障异步通信的可靠性:

  • 硬同步:仅在帧起始(SOF)处触发,强制将本地时钟的同步段与总线跳变沿对齐,复位时间段计数器,用于帧传输的初始同步;

  • 再同步:帧传输过程中,若检测到总线跳变沿与本地时钟偏差超过SJW,通过延长PBS1缩短PBS2实现动态同步,每次调整量≤SJW,用于补偿通信过程中的时钟偏差。

STM32中bxCAN控制器的应用

STM32芯片内置bxCAN(Basic Extended CAN)控制器,支持CAN 2.0A/B协议,可高效实现CAN总线通信,核心用于管理CAN报文的发送/接收,降低CPU负载。

bxCAN控制器基本特性

框图

bxCAN环回模式

环回模式是bxCAN的调试模式,通过将CAN_BTR寄存器的LBKM位置1开启,核心特点:

  • 控制器将自身发送的报文,经验收筛选后作为接收报文存储到接收邮箱;
  • 无需外接CAN收发器和物理总线,可直接测试CAN控制器的发送/接收功能;
  • 适用于前期程序调试,验证报文配置、发送/接收逻辑的正确性。

CAN总线轮询测试程序(环回模式)

基于STM32标准库,实现环回模式下的CAN报文轮询发送/接收,核心功能为:配置CAN→发送指定报文→接收报文→验证报文一致性,测试通过则点亮指定LED。

/* Private define ------------------------------------------------------------*//* Private typedef -----------------------------------------------------------*/typedefenum{FAILED=0,PASSED=!FAILED}TestStatus;/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/__IOuint32_tret=0;/* for return of the interrupt handling */volatileTestStatus TestRx;/* Private function prototypes -----------------------------------------------*/TestStatusCAN_Polling(void);/** * @brief 配置CAN控制器,通过轮询方式进行发送和接收测试 * @param None * @retval PASSED - 接收数据验证成功, FAILED - 接收数据验证失败 */TestStatusCAN_Polling(void){CAN_InitTypeDef CAN_InitStructure;// CAN初始化结构体CAN_FilterInitTypeDef CAN_FilterInitStructure;// CAN过滤器初始化结构体CanTxMsg TxMessage;// CAN发送消息结构体CanRxMsg RxMessage;// CAN接收消息结构体uint32_tuwCounter=0;// 超时计数器uint8_tTransmitMailbox=0;// 发送邮箱编号(0-2)/* 使能CAN总线的时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);/* 复位CAN外设寄存器到默认值 */CAN_DeInit(CAN1);/*--------------------- CAN基本参数配置 ---------------------*/CAN_InitStructure.CAN_TTCM=DISABLE;// 禁用时间触发通信模式CAN_InitStructure.CAN_ABOM=DISABLE;// 禁用自动离线管理CAN_InitStructure.CAN_AWUM=DISABLE;// 禁用自动唤醒模式CAN_InitStructure.CAN_NART=DISABLE;// 启用自动重传(禁用非自动重传)CAN_InitStructure.CAN_RFLM=DISABLE;// 禁用接收FIFO锁定模式(新消息覆盖旧消息)CAN_InitStructure.CAN_TXFP=DISABLE;// 禁用发送FIFO优先级(按ID优先级发送)CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;// 设置为环回模式(自发自收)CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;// 同步跳转宽度 = 1个时间量子/*--------------------- CAN波特率配置 ---------------------*//* 在42MHz CAN时钟下配置175kbps波特率 */CAN_InitStructure.CAN_BS1=CAN_BS1_6tq;// 时间段1 = 6个时间量子CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;// 时间段2 = 8个时间量子CAN_InitStructure.CAN_Prescaler=16;// 预分频值CAN_Init(CAN1,&CAN_InitStructure);// 应用CAN配置/*--------------------- CAN过滤器配置 ---------------------*/CAN_FilterInitStructure.CAN_FilterNumber=0;// 使用过滤器组0CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;// 标识符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;// 32位过滤器// 设置过滤器ID(全0表示接收任意ID)CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器ID高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;// 过滤器ID低16位// 设置过滤器屏蔽位(全0表示不屏蔽任何位)CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;// 屏蔽位高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;// 屏蔽位低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;// 接收到的消息分配到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 激活过滤器CAN_FilterInit(&CAN_FilterInitStructure);// 应用过滤器配置/*--------------------- 发送CAN消息 ---------------------*/// 配置发送消息TxMessage.StdId=0x11;// 标准标识符 = 0x11TxMessage.RTR=CAN_RTR_DATA;// 数据帧(非远程帧)TxMessage.IDE=CAN_ID_STD;// 标准标识符(非扩展标识符)TxMessage.DLC=2;// 数据长度 = 2字节TxMessage.Data[0]=0xCA;// 数据字节0 = 0xCATxMessage.Data[1]=0xFE;// 数据字节1 = 0xFE// 发送消息并获取使用的邮箱编号(0,1或2)TransmitMailbox=CAN_Transmit(CAN1,&TxMessage);/* 等待消息发送完成(带超时保护) */uwCounter=0;while((CAN_TransmitStatus(CAN1,TransmitMailbox)!=CANTXOK)&&(uwCounter!=0xFFFF)){uwCounter++;}/* 检查是否发送超时 */if(uwCounter==0xFFFF){returnFAILED;// 发送失败}/*--------------------- 等待接收CAN消息 ---------------------*/uwCounter=0;// 等待FIFO0中至少有1条消息(带超时保护)while((CAN_MessagePending(CAN1,CAN_FIFO0)<1)&&(uwCounter!=0xFFFF)){uwCounter++;}/* 检查是否接收超时 */if(uwCounter==0xFFFF){returnFAILED;// 接收超时}/*--------------------- 接收并解析CAN消息 ---------------------*/// 初始化接收消息结构体RxMessage.StdId=0x00;// 预设标准标识符 = 0RxMessage.IDE=CAN_ID_STD;// 预设为标准标识符RxMessage.DLC=0;// 预设数据长度 = 0RxMessage.Data[0]=0x00;// 预设数据字节0 = 0RxMessage.Data[1]=0x00;// 预设数据字节1 = 0// 从FIFO0接收消息CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);/*--------------------- 验证接收到的消息 ---------------------*/// 检查标识符是否匹配if(RxMessage.StdId!=0x11){returnFAILED;// 标识符不匹配}// 检查帧类型是否匹配(标准帧)if(RxMessage.IDE!=CAN_ID_STD){returnFAILED;// 帧类型不匹配}// 检查数据长度是否匹配if(RxMessage.DLC!=2){returnFAILED;// 数据长度不匹配}// 检查数据内容是否匹配(组合两个字节为16位值)if((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE){returnFAILED;// 数据内容不匹配}// 所有验证通过,返回测试成功returnPASSED;}intmain(){LED_Init();/* CAN transmit at 125Kb/s and receive by polling in loopback mode */TestRx=CAN_Polling();if(TestRx!=FAILED){/* OK *//* Turn on LED1 */GPIO_ResetBits(GPIOF,GPIO_Pin_9);//输出低电平}else{/* KO *//* Turn on LED2 */GPIO_ResetBits(GPIOE,GPIO_Pin_14);//输出低电平}while(1){}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/16 0:12:13

MySQL 进阶篇: 锁机制深度解析

目录 前言 一、锁的核心概述 1.1 锁的定义与作用 1.2 MySQL 锁的粒度分类 二、全局锁 2.1 定义与核心作用 2.2 语法与操作流程 &#xff08;1&#xff09;加全局锁 &#xff08;2&#xff09;数据备份&#xff08;结合 mysqldump 工具&#xff09; &#xff08;3&…

作者头像 李华
网站建设 2026/3/15 23:10:28

Java 竞赛党必看:字符串操作的正确姿势与常用模板

文章目录一 Java中常用方法1. 基础获取类2. 比较与判断类3. 修改与转换类&#xff08;产生新字符串&#xff09;4. 分割与合并5.StringBuilder二 . 四种字符串必会技能1.字符串与数字的切换A.String 转 int / longB. int/long 转 String2.字符与ASCII 码A.字符转数字B. 字母移位…

作者头像 李华
网站建设 2026/3/15 19:17:22

AI 不再单打独斗:一文看懂“多智能体 (Multi-Agent)”协作模式

引言&#xff1a;为什么我们需要“多智能体”&#xff1f;在过去的一年里&#xff0c;我们习惯了向一个“全知全能”的 AI&#xff08;比如 ChatGPT&#xff09;提问。它能写诗、能编程、能陪聊&#xff0c;仿佛无所不能。但是&#xff0c;当你试图让它完成一个真正复杂的任务时…

作者头像 李华