news 2026/9/16 14:25:41

先楫HPM6750/HPM6450 CAN-FD实战:从协议到采样点调优

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
先楫HPM6750/HPM6450 CAN-FD实战:从协议到采样点调优

简介:面向上海先楫HPM6750与HPM6450高性能MCU的CAN/CAN-FD通信代码工程,适合嵌入式开发者在汽车电子、工业自动化等场景快速落地高速可靠通信。资源共3个文件,约6KB,包含C源码、TXT说明与Markdown文档:其中C文件提供CAN控制器初始化、波特率配置、滤波器设置及收发函数示例;文档则讲解标准帧/扩展帧结构及FD模式的数据段与CRC段差异。压缩包以.c/.txt/.md为核心,结构紧凑,便于对照调试。目前已有546人学习下载。通过这份示例,开发者可掌握HPM6750/HPM6450内建CAN控制器的寄存器配置方法,理解5Mbps更高数据速率下的时钟调整与FD模式开启步骤,并基于清晰函数接口和测试建议快速移植到自有项目中,是构建CAN/CAN-FD通信节点的实用起点。资源容量虽小,但覆盖了协议关键实现点,适合作为入门参考或排错模板。

1. 上海先楫HPM6750跑CAN-FD,为什么这题值得做

先楫HPM6750是国产MCU里少有的、把“高主频”和“硬实时总线”同时交到工程师手里的芯片:双核RISC-V、主频600MHz起步,片内带多路CAN控制器,其中一路支持CAN-FD,这本身就是个自然的组合。但在实际项目里,很多人第一次接触HPM6750是从伺服驱动、车载网关或工业控制器的换芯开始的,工作负载是存量CAN总线,空闲时想往CAN-FD迁移,于是会遇到两件事:第一,普通CAN例程能跑通标准帧,却发不出FD帧;第二,配置FD时反复调采样点和SJW,波形在BRS切换处出现毛刺,或者对端节点直接进bus off。

这个标题把HPM6750和HPM6450放在一起写,核心是在同一份外设驱动上做复用:两个型号的CAN-FD控制器寄存器布局一致,工程里只需要用宏切换型号与引脚,业务代码不必动。这篇文章按“协议差异—硬件接入—驱动实现—参数调优—验证与后向兼容”的顺序,把从“能发帧”到“敢上总线”的路径讲透。适合正在做存量总线升级、CAN网关或伺服驱动的嵌入式工程师,也适合刚拿到先楫开发板、想直接上手CAN-FD的入门者。

2. CAN-FD协议差异与HPM6750的CAN硬件特征

2.1 CAN-FD相对CAN 2.0的帧结构变化:DLC、BRS与CRC

很多人以为CAN-FD只是把速率提高了一档,实际改动是结构性的。以下表格对比两代协议在关键字段上的差异,这也是后面配置寄存器和解析报文时最容易出错的地方。

字段CAN 2.0(经典CAN)CAN-FD
最高标称速率典型1Mbps仲裁段最高1-2Mbps
数据段速率与仲裁段相同可达2Mbps、5Mbps、8Mbps,由收发器决定
最大载荷8字节64字节
DLC编码0-8直接对应字节数0-8对应0-8字节,9-15映射为12/16/20/24/32/48/64字节
CRC多项式15位CRC17位CRC(0-16字节)、21位CRC(17-64字节)
BRS位不存在存在,控制帧内是否切换数据段速率
位填充规则每5个电平均匀插入1个填充位每17位有至少4个显性位,避免反相?实际为每17位检查

表中最后一行是数据段的位填充规则:CAN-FD填充计数器最多到16位,CRC段填充有固定规则,所以抓波形时如果看到数据段长度与预期不一致,先怀疑CRC段填充和DLC字节数映射,而不是立即怀疑时钟精度。

CAN-FD重新定义了DLC值9到15的字节含义。经典CAN里DLC必须小于等于8,超过8会被当作8处理;CAN-FD里DLC=9表示12字节,DLC=10表示16字节,DLC=11表示20字节,DLC=12表示24字节,DLC=13表示32字节,DLC=14表示48字节,DLC=15表示64字节。写驱动时需要用一张静态映射表转换,不能直接做位运算。

2.2 一个控制帧内部的两段速率:为什么采样点要放在两个寄存器里

CAN-FD仲裁段负责ID、控制位和ACK,数据段负责载荷。仲裁段要与线上的所有节点保持相同的位时序,保证仲裁、应答等机制可靠;数据段则在BRS位为显性之后切换到更高的位速率。因此控制器内部分别用标称位时序寄存器NBTP和数据位时序寄存器DBTP,采样点必须分开计算。

HPM6750的CAN外设采用博世M_CAN内核,寄存器体系中CAN_NBTP配置标称段,CAN_DBTP配置数据段,两个寄存器结构几乎一致,都包含DIV、TSEG1、TSEG2和SJW字段。这样设计的好处是:仲裁段用在线的1Mbps,数据段切到5Mbps,升级旧节点时只需保证仲裁段参数一致,数据段速率可以逐步放宽。

下面用一段C语言结构体说明这两段位时序在配置层的形态,只做寄存器映射示意,具体偏移以芯片手册为准:

typedef struct { uint32_t div; /* 分频系数,控制Tq粒度 */ uint32_t tseg1; /* 相位缓冲段1加传播段 */ uint32_t tseg2; /* 相位缓冲段2 */ uint32_t sjw; /* 同步跳跃宽度 */ } can_bit_time_t; can_bit_time_t nominal_time; /* 仲裁段参数,填入CAN_NBTP */ can_bit_time_t data_time; /* 数据段参数,填入CAN_DBTP */

HPM6750的CAN时钟由芯片内部的PLL分频后产生,计算位时序前要确认时钟树中CAN模块的实际频率。常见做法是把CAN时钟源固定在一个整数频率上,例如40MHz,这样1Mbps可以做到每个位时间均匀的整数个Tq,采样点也更稳定。

2.3 HPM6750与HPM6450的通用硬件接入

HPM6750片内多个CAN控制器中,至少有一路支持CAN-FD,其余为经典CAN;HPM6450同样分出FD控制器和普通CAN控制器,这也是标题里强调两款型号可共用驱动的原因。工程上我一般把支持FD的通道固定在CAN0,用于高速数据链路,CAN1做经典CAN慢速总线,业务层再通过统一的发送接口选择通道。

收发器是CAN-FD链路里最容易忽视的一环。经典CAN收发器最高一般只保证2Mbps,跑5Mbps时上升沿变缓,采样点附近可能采到不定态。要跑5Mbps以上,应选用支持ISO 11898-2:2016的收发器,这类芯片明确标注支持CAN-FD,TXD/RXD环路延时要小于波特率位时间的50%。

收发器特性是否能跑CAN-FD推荐场景
经典CAN收发器(仅支持最高1Mbps)存量低速CAN
低速FD收发器(支持2Mbps)短距离节点
高速FD收发器(支持5/8Mbps)网关、伺服、整车节点

接线方面,HPM6750的CAN控制器TXD/RXD信号经过收发器后接入CAN_H和CAN_L,末端节点需要120Ω终端电阻,两个端节点各一个。收发器的VIO参考电压要接与HPM6750 IO电源一致的电平,否则TXD引脚的逻辑电平不匹配,现象是帧能发出但总线上全是错误帧。

时钟方面需要特别注意:CAN模块工作频率并非固定值,代码中应通过时钟接口获取当前CAN时钟频率,再代入位时序计算器。如果直接用经验值40MHz,而实际时钟树配置为25MHz,波特率会整整偏出百分之六十,总线上一帧都收不到,且这个错误在示波器上很难直观看出。

3. 初始化HPM6750 CAN-FD的最小代码与收发帧路径

3.1 时钟使能与引脚复用

初始化CAN-FD的第一步不是设置波特率,而是打开时钟和配置引脚复用。先楫SDK里每个外设都有一个时钟门控开关,CAN0对应一个时钟控制宏,GPIO的复用功能需要把TXD/RXD引脚切换到CAN信号。

#include "hpm_soc.h" #include "hpm_can.h" void can_fd_clock_io_init(void) { /* 使能CAN0外设时钟 */ clock_add_to_group(clock_can0, 0); /* 配置TXD引脚为CAN0_TXD复用功能 */ IOC->PAD[IOC_PAD_PD09].FUNC_CTL = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(1); IOC->PAD[IOC_PAD_PD10].FUNC_CTL = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(1); }

代码逻辑说明:第一步调用clock_add_to_group把CAN0挂到时钟组,确保外设寄存器可访问;第二步通过IOC引脚复用寄存器把PD09、PD10分别映射到CAN0_TXD和CAN0_RXD。不同板卡引脚不同,HPM6450对应引脚编号可能不同,实际工程中建议在板级头文件里定义宏,不要直接写死引脚号。

参数说明:ALT_SELECT_SET后面的数字是由芯片引脚复用表决定的索引,改成错误值不会报错,但引脚上完全没有波形。调试时可通过读取IOC寄存器确认复用功能是否生效。

3.2 用NBTP和DBTP计算采样点并填充寄存器

采样点是在一个位时间内进行电平采样的时刻,通常用百分比表示。CAN-FD仲裁段采样点推荐75%到80%,数据段推荐75%左右,太低容易采到前一位的边沿,太高容易被后一位的相位段遮挡。M_CAN的位时间由同步段、传播段和相位缓冲区组成,同步段固定为1个Tq,TSEG1对应传播段加相位缓冲段1,TSEG2对应相位缓冲段2。

#define CAN_CLK_HZ 40000000UL static void can_fd_calc_bit_time(can_bit_time_t *bt, uint32_t target_bps, uint8_t sample_point) { uint32_t tq_num = CAN_CLK_HZ / target_bps; uint32_t seg1, seg2; /* TSEG2 = (1 - sample_point) * tq_num */ seg2 = tq_num * (100 - sample_point) / 100; seg1 = tq_num - seg2 - 1; /* 减去固定同步段 */ bt->div = 0; bt->tseg1 = seg1 - 1; /* 寄存器值从0开始 */ bt->tseg2 = seg2 - 1; bt->sjw = 1; /* 默认1,BRS切换场景可调大 */ }

逻辑说明:target_bps传500000或5000000,sample_point传80表示80%。tq_num是一个位时间内Tq总数,因为同步段占1个Tq,所以采样点位置是(1 + TSEG1) / (1 + TSEG1 + TSEG2)。寄存器值需要减1,因为M_CAN中TSEG字段为0表示1个Tq。

参数说明:以40MHz时钟、目标2Mbps、80%采样点为例,一个位时间共20Tq,TSEG1寄存器值应为14,TSEG2寄存器值应为4。若目标波特率改为5Mbps,位时间只有8Tq,采样点计算会出现较大舍入误差,因此数据段采样点一般给75%更合适,否则舍入后实际值可能跳到71%或83%。

得到两组位时序后,分别写入CAN_NBTP和CAN_DBTP,然后退出初始化模式:

void can_fd_mode_enable(CAN_Type *base, bool enable_fd) { uint32_t cccr = base->CCCR; cccr &= ~CAN_CCCR_INIT_MASK; base->CCCR = cccr; /* 请求离开初始化模式 */ if (enable_fd) { base->CCCR |= CAN_CCCR_FDOE_MASK | CAN_CCCR_BRSE_MASK; } }

逻辑说明:FDOE位使能FD格式,BRSE位使能BRS速率切换,两个位必须同时置1才能跑FD且让数据段用DBTP。只置FDOE不置BRSE,控制器能发FD帧但数据段仍用NBTP速率,这是很多例程“能发出FD帧但数据段没提速”的原因。

3.3 发送一帧CAN-FD:从TX Buffer到发送请求

M_CAN的发送路径上有多个发送缓冲,可以安排多个待发帧,控制器按优先级自动仲裁。发送前需要填充发送缓冲元素,再置位对应的发送请求位。先楫SDK把这一步封装成了发送结构体,用户只需要填充ID、DLC和数据部分。

can_tx_frame_t tx_frame = {0}; tx_frame.id = 0x123; tx_frame.id_type = CAN_ID_STD; tx_frame.dlc = CAN_DLC_WORD_8; /* 8字节 */ tx_frame.fd_frame = true; tx_frame.brs_enable = true; memcpy(tx_frame.data, payload, payload_len); can_send_message(CAN0, &tx_frame);

逻辑说明:fd_frame=true表示按FD帧格式发送,brs_enable=true表示在数据段切换高速率;如果brs_enable=false,即使配置了FD模式,数据段也保持与仲裁段相同速率。dlc字段直接用帧格式枚举,不用手动做DLC映射,SDK内部会完成映射。

参数说明:ID标准帧只有11位,超过0x7FF会被截断;扩展帧支持29位ID,但要把id_type改成CAN_ID_EXTpayload_lendlc不一致时,常见做法是以dlc为准,不足部分自动补0,超过部分由库完成填充,业务代码应保证payload_len <= 64

发送完成判断有两种:轮询发送缓冲状态位,或等发送完成中断。轮询方式在低负载时最直观,高负载时建议使用发送中断释放缓冲,避免阻塞主循环。

3.4 接收过滤与中断处理

接收侧的过滤规则决定哪些报文进入FIFO、哪些被丢弃。M_CAN有两种接收存储方式:FIFO和专用接收缓冲。先楫SDK默认配置为FIFO模式,中断服务程序里读取报文后需要做字节序处理。

HPM_IRQ_HANDLER(irq_can0_handler) { can_rx_frame_t rx_frame; can_receive_message(CAN0, &rx_frame); if (rx_frame.fd_frame) { /* 声明实际数据字节数 */ len = can_fd_dlc_to_bytes(rx_frame.dlc); process_fd_payload(rx_frame.data, len); } }

逻辑说明:接收中断会逐个弹出FIFO中的报文,fd_frame标志指示是否为CAN-FD帧。多字节payload在HPM6750内部是小端存储,发送到总线时按字节顺序发出,不存在控制器层面的字节序转换问题;业务协议里定义多字节字段时,建议统一采用小端排列,接收端直接memcpy取出,避免手工字节交换带来的隐患。

参数说明:can_fd_dlc_to_bytes负责把DLC映射到实际字节数,这是FD报文解析最容易被忽略的一步。经典CAN里dlc=15按8字节处理,FD里却是64字节,若沿用旧解析逻辑会漏数据。

4. 采样点、SJW与bus off恢复的参数调优

4.1 一组可以直接抄的CAN-FD参数表

以下参数基于CAN时钟40MHz给出,仲裁段和数据段分开配置。表格中的数值已经做过采样点舍入,可直接填入NBTP和DBTP寄存器。

用途仲裁段速率数据段速率TSEG1值TSEG2值SJW实际采样点
FD低速调试500kbps2Mbps仲裁19,数据14仲裁4,数据41/180% / 75%
FD常规伺服500kbps5Mbps仲裁19,数据3仲裁4,数据11/180% / 75%
FD高速网关1Mbps5Mbps仲裁39,数据3仲裁9,数据12/180% / 75%
纯经典CAN500kbps不适用194180%

需要说明的是,表格中的TSEG字段值已经是写入寄存器的值,即已经减1。若目标板卡的CAN时钟不是40MHz,必须重新计算并核对采样点,不能直接套用,否则帧间同步误差会在长时间运行后积累,表现为偶发CRC错误。

4.2 SJW、BRS切换与时钟源的三个坑

第一个坑是SJW设置过小。SJW决定控制器在收到总线跳变时最多能把采样点挪动多少Tq,仲裁段SJW设为1在很多总线长度较长的场景下会失去同步能力,尤其当总线上混有不同容差的节点时,建议仲裁段SJW设为2,数据段保持1即可。注意SJW增大后,TSEG2的有效范围会变小,SJW不能超过TSEG2。

第二个坑是BRS切换的毛刺。数据段速率越高,位时间越短,收发器环路延时对采样点的影响越明显。常见做法是数据段采样点从75%往回调到70%,不要因为想提高时序余量而调到80%以上。数据段SJW保持1,用来吸收相邻等幅位之间的抖动。

第三个坑是时钟源选择。HPM6750的CAN时钟如果在运行中被动态调频,比如DVFS改变CPU频率而CAN时钟来自同一PLL分支,会导致实际波特率漂移。我一般会把CAN时钟固定到独立PLL输出,并在初始化前打印CAN内核时钟频率做日志记录,便于分析线上故障。

4.3 bus off恢复策略与物理层排错

总线off是CAN控制器检测到128次连续错误后进入的离线状态。HPM6750的M_CAN支持自动恢复和手动恢复两种方式,自动恢复由硬件在检测到总线空闲后自动重新参与通信,适合对中断不敏感的场景。

void can_bus_off_recover(CAN_Type *base) { /* 检查bus off状态 */ if (base->PSR & CAN_PSR_BO_MASK) { /* 进入初始化模式后重新退出,完成复位恢复 */ base->CCCR |= CAN_CCCR_INIT_MASK; base->CCCR &= ~CAN_CCCR_INIT_MASK; } }

逻辑说明:这段代码的核心是置位INIT再清除INIT,让控制器内部错误状态机复位。CAN协议规定节点重新参与通信前需要等待128个连续空闲位,硬件会在退出初始化模式后自动完成这个等待,不需要软件延时。

参数说明:如果业务层要求快速恢复,可以缩短错误计数器的攀升时间,但不要滥用。频繁的bus off恢复会破坏总线分时,影响其他节点。遇到总线错误时,先区分是控制器错误还是物理层错误:打开CAN分析仪抓波形,看是否有连续的显性错误帧,如果分析仪提示can not open com port,多数是收发器未上电或USB分析仪的端口被占用,而不是控制器配置问题。

总线负载率也是排查重点。CAN-FD数据段虽然速率提升,但仲裁段时间仍按标称速率计算,当节点数超过10个且每帧都发64字节时,仲裁段占用率会明显上升。建议在业务层统计每毫秒的发送帧数,并预留20%的空闲带宽,避免突发流量把总线挤满。

5. 验证CAN-FD链路的三层手段与存量总线兼容

5.1 控制器回环测试

先楫SDK把M_CAN的测试模式封装为回环功能,配置后不接外部收发器也能完成自测。回环模式适合在硬件尚未准备好时验证控制器初始化、DLC映射和中断逻辑:

void can_fd_loopback_test(void) { CAN0->CCCR |= CAN_CCCR_TEST_MASK; CAN0->TEST |= CAN_TEST_LBCK_MASK; }

回环开启后,发送的FD帧会直接进入接收FIFO,fd_frame标志、brs_enable标志和负载数据都会原样回来,可以借此验证发送数据与接收数据是否一致。注意回环模式不经过收发器,因此无法测试物理层信号质量,帧能回环成功不代表总线波形合格。

5.2 用逻辑分析仪做波形级验证

回环通过后,把收发器接入测试网络,用支持CAN-FD解码的逻辑分析仪观察波形。重点看BRS位之后的数据段位时间是否变短,以及数据段最后一位到CRC定界符的转换过程是否平滑。如果数据段长度与DLC映射不一致,波形上会看到多出来的填充位,直接对拍报文的DLC字段即可定位。

没有逻辑分析仪时,可以用示波器测量CAN_TX引脚的波形宽度,发送一帧已知波特率的FD帧,计算一个显性位的宽度是否与数据段配置吻合。硬件波形验证后再接入CAN分析仪,做双向互发,确认两边帧ID、速率和采样点配置一致。

5.3 与经典CAN节点共存并平滑迁移

存量总线上升级CAN-FD,最稳妥的做法是保持仲裁段参数与旧节点相同,数据段速率先不启用BRS,让FD节点按经典CAN速率发送FD帧。之后逐步升级对端节点,再统一开启BRS,这样能最大程度降低总线停摆风险。如果节点驱动支持自动识别,可以在初始化后先发送经典CAN帧,收到特定诊断请求再进入FD模式,这也是主机厂网关常用的激活逻辑。

最后一层技巧是验证FD链路的实际可用吞吐。对64字节payload、2Mbps数据段做一次1000帧的批量发送,统计总耗时,可以算出仲裁段和数据段各自占用的总线时间,从而评估是否真的需要更高的数据段速率。用这个数据反向校准采样点和SJW,比盲目调参数更可靠。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 14:25:33

小波模极大值实现奇异点检测:从Lipschitz指数到MATLAB实践

简介&#xff1a;这份资源面向需要掌握小波分析与信号奇异性检测的MATLAB使用者&#xff0c;围绕小波模极大值方法提供了可直接运行的实现脚本。资源聚焦连续高斯小波&#xff08;cgau&#xff09;在信号突变点提取与特征定位中的应用&#xff0c;适合科研入门者或工程开发人员…

作者头像 李华
网站建设 2026/9/16 14:24:26

STM32F407智能报警系统毕设工程详解:从RCC到CAN的外设协同

简介&#xff1a;面向计算机科学与技术、电子信息工程等专业的毕设或课程作业&#xff0c;这是一套完整的STM32F407智能报警系统项目包&#xff0c;涵盖从需求分析、硬件搭建到固件编写、系统联调与测试优化的全流程。项目以Cortex-M4内核的STM32F407为主控&#xff0c;涉及传感…

作者头像 李华
网站建设 2026/9/16 14:24:12

res-downloader 实战指南:视频号、抖音与 m3u8 的无水印资源下载

res-downloader 实战指南&#xff1a;视频号、抖音与 m3u8 的无水印资源下载 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader …

作者头像 李华
网站建设 2026/9/16 14:22:53

身份基同态加密实现密封电子拍卖

简介&#xff1a;本资源是一套面向计算机相关专业本科生与研究生的毕业设计/课程设计级区块链安全应用项目&#xff0c;实现基于Hyperledger Fabric的密封电子拍卖协议&#xff0c;并融合身份基同态加密&#xff08;IBHE&#xff09;算法保障投标隐私与可验证性。项目代码经完整…

作者头像 李华
网站建设 2026/9/16 14:19:13

社区智慧养老平台:SpringBoot+Vue全栈实现与权限业务解析

简介&#xff1a;这是一份基于SpringBoot的社区智慧养老监护管理平台完整项目源码包&#xff0c;面向Java初学者、课程设计/毕业设计学生及养老信息化研究者。平台围绕老年人健康监护、生活照护、紧急响应、社交互动等场景&#xff0c;整合SSM框架&#xff0c;实现了多角色权限…

作者头像 李华
网站建设 2026/9/16 14:16:47

四旋翼无人机PD轨迹跟踪的MATLAB仿真与增益整定

简介&#xff1a;面向无人机控制领域研究者和工程师&#xff0c;这份基于MATLAB的四旋翼无人机PD轨迹跟踪算法资源包提供了完整的控制实现方案。包含比例微分控制、加速度控制及无人机动力学模型仿真等环节&#xff0c;可用于轨迹跟踪控制策略的设计与验证。压缩包共16个文件&a…

作者头像 李华