第三十六章 CAN——控制器局域网络接口
第三十六章 CAN——控制器局域网络接口
目录
第三十六章 CAN——控制器局域网络接口
1 CAN通信概述
1.1 简介
1.2 功能特点
1.3 CAN帧结构与类型
1.4 标识符与优先级
2 W55MH32的bxCAN模块详解
2.1 功能特点
2.2 硬件资源与内存映射
2.3 时钟与波特率
3 bxCAN工作模式与状态转换
3.1 工作模式
3.2 测试模式:静默与环回
4 报文发送与接收处理机制
4.1 发送处理流程
4.2 接收管理与FIFO机制
5 标识符过滤系统解析
5.1 过滤机制的核心价值
5.2 屏蔽位模式与列表模式
5.3 过滤器优先级规则
6 错误管理与总线健康监测
6.1 错误检测与计数器机制
6.2 离线恢复机制
6.3 错误中断与状态监控
7 应用场景
7.1 工业自动化网络
7.2 汽车电子系统
8 注意事项
8.1 硬件连接与终端配置
8.2 波特率一致性配置
8.3 过滤器与FIFO管理
8.4 错误处理与恢复机制
8.5 低功耗模式操作规范
9 程序设计
9.1 CAN_LoopBack例程
9.1.1 CAN初始化
9.1.2 CAN数据发送
9.1.3 CAN数据接收
9.1.4 串口接收
9.1.5 主程序
9.1.6 下载验证
9.2 CAN_Normal例程
9.2.1 下载验证
10 总结
控制器局域网(Controller Area Network, CAN)作为工业自动化和汽车电子领域的核心通信技术,以其高可靠性和实时性著称。下面我们将基于W55MH32以太网单片机的bxCAN(基本扩展 CAN)模块,系统讲解CAN通信的原理、架构及实际应用要点,和大家一起学习和使用这一技术。
1 CAN通信概述
1.1 简介
CAN(Controller Area Network)是一种用于实时控制的串行通信总线,由博世公司开发,广泛应用于汽车电子、工业自动化等领域。
1.2 功能特点
CAN接口有以下特点:
- 多主通信机制:网络中所有节点均可在任意时刻主动发送数据,无需中央控制器协调。当多个节点同时发送时,通过标识符仲裁决定优先级,确保高优先级消息优先传输。
- 非破坏性总线仲裁:仲裁过程基于标识符的二进制值,数值越小优先级越高。仲裁失败的节点会自动停止发送,避免总线冲突。
- 错误处理:集成CRC校验、应答校验等多种错误检测机制,检测到错误时自动发送错误帧,并通过错误计数器实现故障界定(主动错误、被动错误、离线状态)。
- 实时性保障:通信速率最高可达1Mbps(短距离),满足实时控制场景需求。
1.3 CAN帧结构与类型
CAN协议定义了四种帧类型,每种帧具有特定的结构和功能:
帧类型 | 作用 | 结构特点 |
数据帧 | 传输数据 | 包含帧起始、仲裁段、控制段、数据段、CRC段、应答段和帧结束,数据长度0-8字节。 |
远程帧 | 请求其他节点发送数据 | 无数据段,仲裁段标识符用于标识请求的消息,接收节点接收到远程帧后发送对应数据帧。 |
错误帧 | 检测到错误时发送 | 由错误标志(6个连续显性位)和错误界定符(8个隐性位)组成,所有节点检测到错误时发送。 |
过载帧 | 通知其他节点自身接收缓冲器满 | 用于延缓数据传输,由过载标志和过载界定符组成。 |
1.4 标识符与优先级
CAN帧通过标识符(ID)确定优先级,ID越小优先级越高。
W55MH32支持两种帧格式:
- 标准帧:11位ID。
- 扩展帧:29位ID。
标识符不代表节点地址,而是与消息内容相关。例如,汽车中“发动机转速”的消息可能对应标识符0x100,所有订阅该消息的节点均可接收。
2 W55MH32的bxCAN模块详解
2.1 功能特点
W55MH32 集成的 bxCAN(Basic Extended CAN)模块是一款高性能 CAN 控制器,专为减轻 CPU 负荷设计,其关键特性包括:
- 协议兼容性:完全支持CAN 2.0A和2.0B主动模式,波特率最高1Mbps。
- 发送处理能力:3个独立发送邮箱,支持优先级配置和时间戳记录(发送帧起始时刻的定时器值)。
- 接收管理机制:2个3级深度的接收FIFO(FIFO0和FIFO1),硬件自动管理报文存储,减少CPU干预。
- 灵活的过滤系统:14个可配置的过滤器组,支持32位或16位过滤宽度,可设置为屏蔽位模式或标识符列表模式。
- 时间触发通信:支持TTCM模式,内部16位定时器为报文添加时间戳,适用于对实时性要求极高的场景。
2.2 硬件资源与内存映射
bxCAN模块的硬件资源包括:
- 引脚连接:通过CANTX和CANRX引脚连接外部收发器(如TJA1050),总线需接120Ω终端电阻。
- 寄存器组:包含控制寄存器(CAN_MCR)、状态寄存器(CAN_MSR)、发送状态寄存器(CAN_TSR)、接收FIFO寄存器(CAN_RF0R/CAN_RF1R)等,共32个32位寄存器,地址范围0x00至0x31C。
- 共享内存:与USB模块共用512字节SRAM,用于数据收发缓冲,二者不可同时使用。
2.3 时钟与波特率
bxCAN的时钟源自APB1总线,其波特率计算公式为:
波特率 = 系统时钟 / [2 × CAN_BRP × (CAN_SJW + 1 + CAN_BS1 + 1 + CAN_BS2 + 1)]
- CAN_BRP:波特率分频器,范围1~1024。
- CAN_SJW:重新同步跳跃宽度,决定总线相位误差的补偿能力。
- CAN_BS1/CAN_BS2:时间段1 和时间段2,用于定义采样点位置和位时序。
例如,当系统时钟为72MHz,设置CAN_BRP=9、CAN_SJW=1、CAN_BS1=6、CAN_BS2=3时,波特率为1Mbps,采样点位于75%位时间处,兼顾抗干扰性和同步能力。
3 bxCAN工作模式与状态转换
3.1 工作模式
bxCAN支持三种主要工作模式,通过CAN_MCR寄存器配置:
初始化模式
- 进入条件:软件设置CAN_MCR.INRQ=1,等待CAN_MSR.INAK=1确认。
- 功能:仅在此模式下可配置波特率(CAN_BTR寄存器)、过滤器组参数(位宽、模式、FIFO关联等)。
- 注意事项:初始化完成后需退出该模式才能正常通信,退出时需等待总线空闲(检测到11个连续隐性位)。
正常模式
- 工作状态:支持完整的收发功能,节点与总线同步后即可发送和接收报文。
- 同步机制:通过检测帧起始位(SOF)的上升沿实现位同步,后续通过重新同步调整相位误差。
- 典型应用:工业控制中的数据交互、汽车ECU间的实时通信。
睡眠模式
- 低功耗设计:时钟停止,仅保留唤醒逻辑,功耗显著降低。
- 唤醒方式:软件清CAN_MCR.SLEEP位,或硬件检测到总线活动(需设置CAN_MCR.AWUM=1)。
- 应用场景:电池供电设备的节能模式,如车载传感器的待机状态。
3.2 测试模式:静默与环回
为便于开发调试,bxCAN支持两种测试模式,需在初始化模式下配置CAN_BTR寄存器:
静默模式(SILM=1)
- 特性:可接收数据帧和远程帧,但发送时仅输出隐性位,不影响总线状态。
- 用途:用于分析总线活动,不干扰现有通信,如故障诊断时的总线监听。
环回模式(LBKM=1)
- 特性:发送的报文直接在内部回环至接收端,忽略CANRX引脚输入。
- 用途:自测试场景,无需外部硬件即可验证收发功能,如模块出厂前的自测。
环回静默模式(SILM=1+LBKM=1)
- 组合特性:兼具环回和静默功能,发送报文不影响外部总线,仅内部回环测试。
- 安全测试:适用于"热自测试",避免干扰实际总线通信。
4 报文发送与接收处理机制
4.1 发送处理流程
bxCAN的发送流程由硬件自动管理,软件只需配置邮箱并请求发送:
- 邮箱选择:3个发送邮箱(邮箱0~2),空闲时可选择任意邮箱。
- 参数配置:设置标识符(STDID/EXID)、帧类型(数据帧/远程帧)、数据长度(DLC)和数据内容。
- 发送请求:置位CAN_TIxR.TXRQ位,邮箱状态变为"挂号",等待仲裁。
- 仲裁与发送:仲裁成功后进入"发送中"状态,发送完成后CAN_TSR.TXOK位置1,邮箱重置为空闲。
发送优先级规则
- 标识符优先:CAN_MCR.TXFP=0时,标识符数值小的报文优先发送;标识符相同时,邮箱号小的优先。
- FIFO优先:CAN_MCR.TXFP=1时,按发送请求的先后顺序排队,适用于分段发送场景。
4.2 接收管理与FIFO机制
接收处理通过2个3级深度FIFO实现,完全由硬件管理:
- 有效报文判定:正确接收(无CRC错误、格式错误等)且通过过滤器检查的报文为有效报文。
- FIFO存储:有效报文按接收顺序存入FIFO,FIFO0和FIFO1各自独立,可通过过滤器配置关联到不同FIFO。
- 状态标识:CAN_RF0R/FIFO1R中的FMP[1:0]位指示FIFO中的报文数量(0~3),满时FULL位被置1。
- 溢出处理:可配置FIFO锁定模式(CAN_MCR.RFLM=1),此时新报文会被丢弃;否则最新报文覆盖旧报文。
时间戳与过滤器匹配序号
- 时间戳:每个接收报文记录帧起始时刻的16位定时器值,存入CAN_RDTxR.TIME[15:0],用于分析报文延迟。
- 过滤器匹配序号(FMI):记录匹配的过滤器组编号,存入CAN_RDTxR.FMI[7:0],软件可据此快速区分报文类型。
5 标识符过滤系统解析
5.1 过滤机制的核心价值
CAN网络中,节点通常只关注部分报文,过滤器的作用是硬件层面筛选有效报文,减轻CPU负荷。bxCAN的过滤系统具有以下特点:
- 14个过滤器组:每个组可独立配置,支持标准帧和扩展帧过滤。
- 可变位宽:每个组可设置为32位单过滤器或2个16位过滤器。
- 双模式配置:屏蔽位模式或标识符列表模式,灵活适应不同场景。
5.2 屏蔽位模式与列表模式
屏蔽位模式
- 工作原理:每个过滤器组包含1个标识符寄存器和1个屏蔽寄存器,屏蔽位为1的位置需严格匹配,为0的位置"不关心"。
- 典型应用:过滤一组相关报文,如标识符0x100~0x1FF的标准帧,可设置标识符为0x100,屏蔽码为0x0FF。
标识符列表模式
- 工作原理:两个寄存器均作为标识符寄存器,报文必须与其中一个完全匹配才会通过过滤。
- 典型应用:精确过滤特定报文,如只接收标识符为0x200的扩展帧,可设置两个寄存器均为0x200的扩展帧格式。
5.3 过滤器优先级规则
当报文匹配多个过滤器时,优先级由以下规则决定:
- 位宽优先:32位过滤器优先级高于16位过滤器。
- 模式优先:列表模式优先级高于屏蔽位模式。
- 编号优先:过滤器组编号小的优先级高(0-13)。
例如,32位列表模式的过滤器组0优先级高于16位屏蔽位模式的过滤器组1,确保关键报文优先处理。
6 错误管理与总线健康监测
6.1 错误检测与计数器机制
bxCAN通过发送错误计数器(TEC)和接收错误计数器(REC)实现故障界定:
- 错误类型:支持位错误、填充错误、CRC错误、格式错误、应答错误等,错误码存入CAN_ESR.LEC[2:0]。
- 计数器更新:
- 发送错误时TEC加1,接收错误时REC加1。
- 成功发送/接收时,TEC和REC减1(超过127时减至120)。
- 状态转换:
- TEC或REC > 127时进入错误被动状态,此时发送错误帧为隐性位。
- TEC > 255时进入离线状态,无法收发报文,需通过自动恢复或软件干预重新上线。
6.2 离线恢复机制
离线状态的恢复方式由CAN_MCR.ABOM位决定:
- 自动恢复(ABOM=1):检测到128次11个连续隐性位后自动恢复为错误主动状态。
- 手动恢复(ABOM=0):软件需先请求进入初始化模式,再退出,等待总线同步后恢复。
6.3 错误中断与状态监控
通过CAN_IER寄存器可配置多种错误中断:
- 错误警告中断(EWGIE=1):TEC或REC ≥ 96时触发,提示总线可能出现异常。
- 错误被动中断(EPVIE=1):进入错误被动状态时触发,需关注总线稳定性。
- 离线中断(BOFIE=1):进入离线状态时触发,需启动恢复流程。
- 上次错误码中断(LECIE=1):每次错误时更新错误码并触发中断,便于快速定位问题。
7 应用场景
7.1 工业自动化网络
- 多设备协同控制:如PLC与传感器、执行器间的实时数据交互,通过CANopen协议实现设备联网。
- 抗干扰设计:采用隔离收发器(如CTM1051)和屏蔽双绞线,总线两端接120Ω终端电阻,降低电磁干扰影响。
7.2 汽车电子系统
- 车载网络:连接发动机控制单元(ECU)、ABS、仪表盘等,遵循J1939或CANopen协议。
- 低功耗需求:利用睡眠模式和唤醒功能,减少待机功耗,满足汽车电源管理要求。
8 注意事项
8.1 硬件连接与终端配置
- 总线两端必须接入120Ω终端电阻,中间节点无需额外电阻,避免阻抗不匹配导致信号反射。
- 工业场景建议使用隔离收发器(如CTM1051)和屏蔽双绞线,屏蔽层单点接地以降低电磁干扰。
8.2 波特率一致性配置
- 所有节点的波特率参数(CAN_BRP、BS1、BS2、SJW)必须完全一致,建议通过寄存器硬编码避免计算误差。
- 长距离通信(>100m)需降低波特率至50kbps以下,并将采样点后移至80%位时间处(增大BS1参数)。
8.3 过滤器与FIFO管理
- 未使用的过滤器组需设置为非激活状态(CAN_FA1R对应位清0),避免无效报文占用资源。
- 接收FIFO需定期查询或启用中断(如FMPIE),防止因软件处理延迟导致报文溢出。
8.4 错误处理与恢复机制
- 监控发送/接收错误计数器(TEC/REC),超过96时触发预警,超过127时切换至降级模式。
- 离线恢复时,若使用手动模式(ABOM=0),需确保退出初始化模式后等待总线同步完成(CAN_MSR.INAK=0)。
8.5 低功耗模式操作规范
- 进入睡眠模式前需确认所有发送邮箱为空(CAN_TSR.TME=1),唤醒时优先使用硬件总线活动检测(AWUM=1)以降低功耗。
9 程序设计
9.1 CAN_LoopBack例程
CAN_LoopBack例程实现了CAN总线回环测试程序,通过串口接收指令控制CAN数据发送,并自动接收回环数据进行打印输出,用于验证CAN控制器功能。以下是实现过程和结果验证:
9.1.1 CAN初始化
CAN_Mode_Init()函数是W55MH32的CAN总线初始化函数,内容如下:
uint8_t CAN_Mode_Init(uint8_t tsjw, uint8_t tbs2, uint8_t tbs1, uint16_t brp, uint8_t mode)
{GPIO_InitTypeDef GPIO_InitStructure;CAN_InitTypeDef CAN_InitStructure;CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLENVIC_InitTypeDef NVIC_InitStructure;
#endifRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //reuse push pullGPIO_Init(GPIOB, &GPIO_InitStructure); //initialize ioGPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //pull up inputGPIO_Init(GPIOB, &GPIO_InitStructure); //initialize io//CAN unit settingsCAN_InitStructure.CAN_TTCM = DISABLE; //non time triggered communication modeCAN_InitStructure.CAN_ABOM = DISABLE; //software automatic offline managementCAN_InitStructure.CAN_AWUM = DISABLE; //Sleep mode Wake up via software (clear the SLEEP bit of CAN- > MCR)CAN_InitStructure.CAN_NART = ENABLE; //prohibit automatic transmission of messagesCAN_InitStructure.CAN_RFLM = DISABLE; //message not locked new overwrite oldCAN_InitStructure.CAN_TXFP = DISABLE; //priority is determined by the message identifierCAN_InitStructure.CAN_Mode = mode; //Mode settings: mode: 0, normal mode; 1, loop mode;//set baud rateCAN_InitStructure.CAN_SJW = tsjw; //Resynchronize jump width (Tsjw) to tsjw + 1 time unit CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tqCAN_InitStructure.CAN_BS1 = tbs1; //Tbs1=tbs1+1 unit of timeCAN_BS1_1tq ~CAN_BS1_CAN_InitStructure.CAN_BS2 = tbs2; //Tbs2=tbs2+1 unit of timeCAN_BS2_1tq ~ CAN_CAN_InitStructure.CAN_Prescaler = brp; //The frequency division factor (Fdiv) is brp + 1CAN_Init(CAN1, &CAN_InitStructure); //Initialize CAN1CAN_FilterInitStructure.CAN_FilterNumber = 0;//filter0CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //shielding modeCAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //32 bit widthCAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;//32 bit idCAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; //32 bit maskCAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //filter 0 is associated with fifo0CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;//activate filter 0CAN_FilterInit(&CAN_FilterInitStructure); //filter initialization#if CAN_RX0_INT_ENABLECAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIFO0 message registration interruption allowed.NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // the primary priority is 1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // the secondary priority is 0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
#endifreturn 0;
}
该函数通过配置GPIOB引脚(PB8接收上拉、PB9发送复用)和CAN1控制器,设置工作模式(含回环测试)、位时序参数(同步段、位段1/2、分频系数)以确定波特率,使用32位ID屏蔽过滤器接收所有消息,并可选择性开启FIFO0中断(需定义CAN_RX0_INT_ENABLE),最终完成CAN总线的初始化配置,为通信做准备。
9.1.2 CAN数据发送
Can_Send_Msg()为CAN总线数据发送函数:
uint8_t Can_Send_Msg(uint8_t *msg, uint8_t len)
{
uint8_t mbox;
uint16_t i = 0;CanTxMsg TxMessage;TxMessage.StdId = 0x12; // standard identifierTxMessage.ExtId = 0x12; // set extension identifierTxMessage.IDE = CAN_Id_Standard; // standard frameTxMessage.RTR = CAN_RTR_Data; // data frameTxMessage.DLC = len; // the length of the data to be sentfor (i = 0; i < len; i++)TxMessage.Data[i] = msg[i];
mbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;while ((CAN_TransmitStatus(CAN1, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF)) i++; //waiting for the end of sendingif (i >= 0XFFF) return 1;return 0;
}
此程序首先配置CAN帧参数(标准ID为0x12、标准数据帧、数据长度由参数指定),将待发送数据填充至发送缓冲区,然后调用发送函数并通过邮箱状态轮询机制(最多等待0XFFF次)确认发送结果,最终返回成功(0)或失败(1)。
9.1.3 CAN数据接收
Can_Receive_Msg()为CAN总线数据接收函数:
uint8_t Can_Receive_Msg(u8 *buf)
{
uint32_t i;CanRxMsg RxMessage;if (CAN_MessagePending(CAN1, CAN_FIFO0) == 0) return 0; //no data received exit directlyCAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //read datafor (i = 0; i < 8; i++)
buf[i] = RxMessage.Data[i];return RxMessage.DLC;
}
通过检查CAN1的FIFO0接收缓冲区状态,若有数据则读取CAN帧信息(含ID、数据等),将有效数据(最多8字节)复制到用户缓冲区,并返回实际数据长度(DLC),若无数据则直接返回0,实现了简洁的非阻塞式CAN数据接收功能。
9.1.4 串口接收
GetCmd()为USART1串口单字符接收函数:
uint8_t GetCmd(void)
{
uint8_t tmp = 0;if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)){
tmp = USART_ReceiveData(USART1);}return tmp;
}
通过检查接收缓冲区非空标志位(RXNE)判断是否有数据可读,若有则读取并返回接收到的字符(8位),若无则返回0。
9.1.5 主程序
main()函数为CAN总线回环测试主程序:
int main(void)
{
uint8_t res, i, key;
uint8_tcanbuf[8];RCC_ClocksTypeDef clocks;delay_init();UART_Configuration(115200);RCC_GetClocksFreq(&clocks);printf("\n");printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);printf("CAN LoopBack Test.\n");CAN_Mode_Init(CAN_SJW_1tq, CAN_BS2_8tq, CAN_BS1_9tq, 4, CAN_Mode_LoopBack); //CAN initialize loopback mode,baud rate 500Kbpswhile (1){if (GetCmd() == 's'){for (i = 0; i < DATA_LEN; i++){
canbuf[i] = 0x5A + i;}
res = Can_Send_Msg(canbuf, 8); //send 8 bytesif (res == 0)printf("Can Loop Back Send Data Success\n");elseprintf("Can Loop Back Send Data Fail\n");} key = Can_Receive_Msg(canbuf);if (key){printf("Can Loop Back Recv Data Success\n");for (i = 0; i < key; i++){printf("canbuf[%d] = 0x%x\n", i, canbuf[i]);}}}
}
通过初始化系统时钟、UART1和CAN控制器(配置为回环模式,波特率500Kbps),在主循环中监听串口输入,当接收到“s”字符时发送8字节测试数据(0x5A~0x61),并持续检查CAN接收缓冲区,若收到数据则打印内容,实现自收自发的通信验证。
9.1.6 下载验证
程序下载运行后,首先打印了系统各时钟的频率和示例名称,我们手动通过串口发送“s”之后,W55MH32便会通过CAN接口发送数据并接收来实现回环测试。发送和接收成功后都会打印出对应的提示信息,接收成功后同时也会将接收缓冲区的内容打印出来:
9.2 CAN_Normal例程
CAN_Normal是CAN总线正常模式通信测试程序,与回环测试不同,它需通过物理总线与外部CAN节点通信。该例程除了CAN初始化的CAN模式参数变成的CAN_Mode_Normal之外,CAN初始化函数内容、发送、接收函数、主程序等与CAN_LoopBack例程保持一致。改动如下:
CAN_Mode_Init(CAN_SJW_1tq, CAN_BS2_8tq, CAN_BS1_9tq, 4, CAN_Mode_Normal); //baud rate 500Kbps
9.2.1 下载验证
程序下载运行后,首先打印了系统各时钟的频率和示例名称,通过串口发送“s”后,W55MH32便会通过CAN接口发送数据,发送成功后串口打印“Can Normal Send Data Success”的信息:
10 总结
本文聚焦W55MH32的bxCAN模块,详解CAN通信核心内容。先介绍CAN协议特性与帧结构,再解析bxCAN的发送邮箱、接收FIFO及工作模式,接着阐述收发机制、过滤规则、错误管理和波特率配置,最后从硬件连接、参数匹配、过滤配置等方面给出示例程序以及讲解,帮助大家理解CAN的使用。