news 2026/8/31 23:24:02

STM32F105R8T6+TJA1050双CAN开发板硬件设计及例程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F105R8T6+TJA1050双CAN开发板硬件设计及例程解析

简介:本资源是一套面向嵌入式初学者与CAN通信开发者的完整学习套件,聚焦STM32F105系列双CAN总线硬件设计与软件驱动实践,解决CAN节点开发中原理图参考缺失、协议栈调试困难、多外设协同验证不足等典型问题。压缩包共含多个核心文件,包括PDF格式的开发板硬件原理图(基于STM32F105R8T6与TJA1050双CAN收发器)、9个可直接编译运行的Keil工程源码例程(涵盖ADC电压采集串口转发、CRC校验、双CAN 500Kbps通信、USART/LED/TIM/SysTick基础外设操作及按键查询控制等),以及关键参考手册STM32-105_CN.pdf,整体大小为24.16MB。已有142人下载学习,内容结构清晰、模块独立、注释详尽,每个例程均体现CAN与UART、GPIO、定时器等外设的典型交互逻辑,便于分步验证、对比调试与项目移植。 在嵌入式控制领域干了这么多年,CAN总线永远是绕不开的话题。从汽车电子到工业现场,双CAN冗余架构的需求越来越大,而STM32F105R8T6+TJA1050这套组合,恰好是低成本实现双CAN通信的一套经典方案。这一套材料里包括完整的硬件PD版原理图,还有9个可跑的软件例程源码,无论是刚接触CAN总线的工程师,还是需要在项目里快速搭建双CAN通信的开发者,都能直接用这套东西作为起步平台,省去从零画板写驱动的时间。

我拿到这套资料后,整体过了一遍,硬件部分是基于STM32F105R8T6自带的两个CAN控制器,外挂两路TJA1050收发器,完成物理层信号转换;软件部分是9个工程例程,覆盖了CAN的配置、收发、过滤、回环测试这些基础场景。下面从硬件设计、原理翻看到软件例程,我把这套方案的细节逐层拆开来讲,顺便把我自己调试过程中踩过的坑也一起放进来。

1. 项目概述与选型分析

1.1 为什么选STM32F105R8T6做双CAN核心

很多人可能第一反应是:STM32F103不也有CAN吗?为什么非要选F105?这里有一个很关键的区别。STM32F103全系只带一个CAN控制器,要实现双CAN就得外扩一颗独立的CAN控制器芯片,比如MCP2515,再通过SPI去挂接,不仅多占MCU的IO,还增加了软件复杂度。而STM32F105系列是意法半导体第一代具备双CAN控制器的Cortex-M3芯片,芯片内部直接带了两个完整的CAN控制器(CAN1和CAN2),两个控制器都可以独立收发,硬件层面天然支持双CAN冗余或双通道通信。

从资源上看,F105R8T6主频72MHz、64KB Flash、20KB RAM,虽然Flash容量不大,但跑两台CAN的收发任务和协议处理绰绰有余。最关键的是,如果后续项目扩展到以太网,F105系列还集成了一路以太网MAC(对,F105是有MAC的),配合外部PHY芯片就能实现车规级的CAN+以太网网关方案。不过这一套板子没有用以太网,核心价值还是双CAN。

再说直白一点,选择F105的初衷,就是在不增加外部扩展芯片的前提下,利用片内资源把双CAN做出来。相比F103外加两个MCP2515的方案,F105的硬件成本更低、PCB面积更小、软件链路更短,可靠性也更高。

1.2 TJA1050收发器的作用与选型理由

CAN控制器(STM32内部)只是协议层设备,它输出的信号是TTL电平的CANTX和CANRX,这种单端信号不能在CAN总线上直接传输,必须经过收发器转换成总线上的差分信号才能通信。TJA1050就是干这个活的——它把CAN控制器的发送引脚TX转换成CANH和CANL的差分电平,同时把总线上的差分信号转换回单端电平整成给控制器的RX引脚。

TJA1050是恩智浦的经典CAN收发器,和更老的PCA82C250相比,TJA1050做了几处重要改进:第一,它提高了电磁兼容性(EMC),在汽车和工业环境中更不容易受干扰;第二,它没有待机模式,工作模式更纯粹,适合高速实时通信;第三,它的斜率控制引脚S有内部上拉电阻,如果不做特殊处理,芯片默认工作在高速模式,直接支持最高1Mbps波特率。

在芯片紧缺的时期,TJA1050还遇到过替代料的问题。市面上常见的替代型号有TJA1051、TJA1044,还有国产的SIT1050,基本上引脚兼容,可以直接替换,但需要注意TJA1051增加了STB引脚,TJA1054等型号的功能更复杂,直接替代时最好查阅数据手册确认引脚定义。

1.3 这套开发板适合谁

如果你是刚接触CAN总线的入门工程师,这套板子可以让你绕开底层复杂的控制器配置,直接用现成例程跑起来;如果你是做汽车诊断、工业控制、传感器采集这类项目的开发者,这套双CAN开发板可以用来做协议转换、网关调试,甚至在正式产品出来前做原型验证。配合官方资料,你可以快速掌握CAN过滤器的设置、波特率计算、收发中断的处理思路,然后将这套方案复用到自己的项目里。

2. 硬件设计思路与原理图拆解

2.1 最小系统部分

拿下这块板子的原理图,最先看的就是STM32F105R8T6的最小系统设计。这部分看起来简单,但很多细节决定了板子能不能稳定工作。

首先是电源。F105的数字内核和IO供电都是3.3V,而CAN收发器TJA1050的供电是5V。所以板子上一般是先有一个5V电源入口(USB、DC头或者排针跳线选择),然后通过一颗LDO降到3.3V给MCU供电。常见的LDO型号是AMS1117-3.3,虽然效率一般,但是压差小、纹波小,给MCU这类数字电路供电完全够用,而且便宜量大。在原理图上你会看到典型的“5V进-AMS1117-3.3-出3.3V”结构,输入输出各加一个10uF和一个100nF的电容,这就是标准的滤波组合。

其次是复位电路。F105的NRST引脚是低电平复位,原理图上通常是一个10K上拉电阻接到3.3V,再接一个100nF电容到地,形成一个RC复位电路。有的板子会再加一个手动复位按键,直接连接NRST到GND,方便调试时手动复位。这里有一个小细节:电容选太大(比如1uF)会导致上电复位时间偏长,选太小(比如1nF)又可能抗干扰能力不足,100nF是一个比较稳妥的中间值。

然后是时钟系统。STM32F105可以外部接8MHz晶振,再经过内部PLL倍频到72MHz主频。原理图上晶振两端各接一个10-20pF的负载电容,这两个电容的取值要参照晶振本身的负载电容参数。另一个容易忽略的是VREF+和VDDA引脚的去耦,很多人把VDDA直接接3.3V可以跑起来,但在ADC采样精度要求高的应用里,VDDA和VREF+最好通过一个磁珠或小电感单独滤波,再接一个1uF电容到地,这部分原理图是否处理到位,决定ADC读取数据的稳定程度。

再有就是Boot引脚。BOOT0和BOOT1一般都会引出跳线或排针,BOOT0上拉或下拉的选择决定芯片从Flash启动还是从系统存储器(串口ISP)启动。正常运行时BOOT0和BOOT1都要接GND,即从Flash启动;需要烧写固件时,把BOOT0拉高再复位,就能进入ISP模式。调试时如果发现设备连不上烧录器,先检查BOOT0是不是被意外拉高了。

2.2 双CAN收发器电路设计

TJA1050的电路连接在原理图里很典型,我直接说重点。收发器的TXD引脚接单片机的CAN1_TX(PA12)或CAN2_TX(PB6),RXD引脚接CAN1_RX(PA11)或CAN2_RX(PB7)。注意这里千万不要接反,TXD/RXD接线错误最直接的后果就是收发完全不通,或者芯片发热。

TJA1050的S引脚是斜率控制引脚。如果直接在S引脚对地接一个电阻(比如10K到47K),收发器工作在斜率控制模式,通过电阻值调节CANH/CANL的上升下降沿斜率,这个模式能降低电磁辐射,适合较低波特率的应用。如果S引脚悬空或者直接接高电平,收发器工作在高速模式,支持最高1Mbps。高速模式是大多数默认场景,普通原理图直接把S引脚悬空或通过电阻上拉到5V即可。

另一个必须关注的引脚是TJA1050的VCC引脚的旁路电容。收发器在工作时会在总线上产生明显的瞬态电流,所以VCC引脚必须就近放一个去耦电容,一般推荐100nF陶瓷电容,有条件的话并联一个10uF的电解电容,这个电容的位置离VCC引脚越近越好,走线要短粗。我踩过的一个坑是首版PCB把去耦电容放到离芯片两厘米远的位置,结果总线速率跑上500kbps后偶发通信错误,把电容挪近后问题消失。

终端电阻在总线侧。CAN总线的两端必须各接一个120欧的终端电阻,但这个电阻放不放在板子上是门学问。开发板通常的做法是把120欧电阻作为可选焊盘放在板上,通过跳线或0欧电阻使能。如果你的板子是终端设备,就把R120焊上;如果是串联在总线中间的节点,就千万不要焊这个电阻。原理图上常见的实现是两个120欧电阻串在CANH和CANL之间,中间抽头通过一个电容(如4.7nF)接地,这样既做终端匹配又滤波。

2.3 电源与保护电路

双CAN开发板的电源输入部分,通常会用USB接口(5V)或外部5V排针输入,然后经过一个防反接二极管或者自恢复保险丝,再到板载电源系统。这个防反接二极管虽然看起来不起眼,但能避免用户反接电源时烧掉整个板子。

在总线侧的保护电路,有些成品板会加TVS管(瞬态抑制二极管)或ESD保护芯片到CANH和CANL对地,防止静电放电或浪涌损坏收发器。TJA1050本身具备一定的ESD防护能力,但如果是实际产品应用,建议在端子处加一个PESD1CAN或SMBJ12CA这类器件。原理图上如果没有这些保护,后续如果要过EMC测试或者做产品,需要自己补上。

如果用的是5V供电的TJA1050,但MCU是3.3V供电,需要注意电平兼容。TJA1050的逻辑输入阈值是TTL电平,而STM32的IO输出电压是高电平3.3V,这刚好满足TJA1050的高电平输入需求。反过来,TJA1050的RXD输出高电平是5V,传给STM32的RX引脚时,5V高电平对F105来说不会烧IO(F105的IO是5V容忍的),所以即使没有电平转换电路也能正常工作。但是如果换了不兼容的MCU,就要考虑加电平转换或串电阻分压。

2.4 PCB布局与走线要点

说到PCB布局,双CAN板子的重点是总线差分走线。CANH和CANL是一对差分线,在画PCB时应该尽量平行走线、等长、靠近,减小差分阻抗不匹配带来的反射。两层板做的时候可能做不到严格的差分阻抗控制,但至少要保证CANH/CANL的走线不完全分开跨越地平面切割区域。TJA1050和CAN接线端子之间的距离越短越好,收发器应放在靠近板边端子处,MCU放在内侧。

另外,MCU的OSC晶振要尽量靠近MCU引脚,走线短而粗;VDDA去耦电容要靠近VDDA引脚;整板分地层尽量完整,不要在关键信号下切割。这些都是老生常谈,却直接影响高速通信的稳定性。我自己画过一版为了省面积把CAN收发器放在板中间的板子,结果通信干扰特别大,后来才知道是收发器输出到总线的走线太长,耦合噪声进到了信号里。重新布局后问题才彻底解决。

3. 双CAN通信的核心原理

3.1 STM32F105的双CAN架构

STM32F105有两个CAN控制器,但内部结构并不是完全独立的。CAN1有个存储区(邮箱、过滤器、FIFO),CAN2也有自己的存储区,但需要注意在F105上,CAN2不能使用独立的过滤器组,它只能复用CAN1的一部分过滤器。这意味着你使用CAN2时,配置过滤器的方式和CAN1略有不同。

F105上的两个CAN控制器都支持CAN 2.0A和CAN 2.0B协议,也就是标准帧(11位ID)和扩展帧(29位ID)都可以处理。每个CAN控制器有3个发送邮箱,发送时优先级可以由软件设置;接收方向有2个FIFO(FIFO0和FIFO1),每个FIFO可以保存3个报文,并且每个FIFO关联一个过滤器组。报文满了之后新的报文会被丢弃,所以软件上要及时读取FIFO。

双CAN的典型用法有两种:一种是两个CAN通道分别连接不同的总线,各自独立工作,比如一个通道接车载ECU,另一个通道接诊断接口,中间由MCU做数据转发,这就是网关的基本形态;另一种是双CAN做冗余,同一份数据在两个总线上同时发送,接收方同时收到两条总线数据并做校验,提高系统的可靠性。这套例程里涉及的就是这两种用法的底层实现。

3.2 CAN报文格式与波特率计算

CAN报文结构虽然不复杂,但关键是理解仲裁机制。ID优先级高的报文获胜,ID值越小优先级越高。还有远程帧,平时用得少,但例程里可能会涉及,它用来请求某个节点发送数据。数据帧分为标准帧和扩展帧,标准帧最多携带8字节数据,扩展帧也是最多8字节。8字节的数据负载是CAN总线的硬限制,如果需要传输超过8字节的数据,协议层需要自己分包和重组。

波特率计算是CAN开发里最容易出错的环节。CAN的位时间由同步段、传播段、相位缓冲段1和相位缓冲段2组成。STM32的CAN外设通过预分频器设置时间片,通过BS1和BS2寄存器设置段长度。公式是:

波特率 = CAN时钟 / (预分频值 × (1 + BS1 + BS2))

假设CAN时钟是36MHz(F105的CAN时钟源自APB1,APB1最大36MHz),要得到500kbps,那么预分频值×(1+BS1+BS2)就应该等于72。如果BS1=13、BS2=2,预分频=1,算出来是36/(1+13+2)=2.25,不对。要凑到500kbps,可以设预分频=4,BS1=13,BS2=2,那就等于36/(4×16)=0.5625Mbps,明显不对。其实正确组合应满足:CAN时钟/(预分频×(同步段1+BS1+BS2))=目标波特率。同步段固定为1个时间片。比如预分频=4,BS1=6,BS2=2,总时间片=1+6+2=9,36/(4×9)=1MHz。要500kbps,需要总时间片18,比如预分频=2,BS1=13,BS2=4,总时间片=18,36/(2×18)=1MHz,还是偏了。我重新调整:预分频=2,总时间片=36,则波特率=36/(2×36)=0.5MHz,BS1+BS2+1=36,可设BS1=25、BS2=10,这样同步段1+BS1+BS2=36,刚好是500kbps。各位一定要自己动手算一遍,或者用CubeMX的CAN配置界面直接看,它的图形化配置会实时回显重新计算的波特率值。

还有采样点的问题,它决定了字节采样时刻。一般来说采样点在80%左右是比较均衡的,比如BS1=13、BS2=2时采样点在(1+13)/16=87.5%,高速总线可能没问题。但如果总线较长或节点较多,建议采样点略微提前,通过调整BS1和BS2的比值来微调。实际项目中,我需要和总线上已有的其他节点保持一致,如果别人的报文采样点设在75%,你这边设成87.5%,通信可能不稳定。

3.3 过滤器的工作原理

STM32的CAN过滤器可以理解为“硬件级的报文筛选器”。它允许软件预设一组ID规则,总线上所有的报文先经过过滤器,只有满足规则的报文才会进入接收FIFO并触发中断。这么做可以大幅减少MCU处理无用报文的开销。

过滤器有几种工作模式:屏蔽位模式、列表模式,或者两者的组合。屏蔽位模式用两个32位寄存器,一个存放期望ID的比特位,一个存放屏蔽码,屏蔽码为1的位要求报文ID必须与期望ID一致,屏蔽码为0的位表示不关心。列表模式则是精确匹配ID。实际配置中,如果CAN_ID能配成16位(标准帧场景),就配置一个16位的列表;如果需要更灵活的规则,就配置成32位屏蔽模式。

一个容易搞混的点是:在F105这种双CAN控制器上,CAN2使用的过滤器组不能独立分配,而是要通过CAN1的过滤器组来配置,并且开启过滤器后CAN1和CAN2都能看到过滤结果。简单说,你如果想给CAN2配过滤器,需要在CAN1的初始化里把一个过滤器组的FIFO分配指向CAN2。这也是例程源码里值得仔细看的地方。

4. 9个软件例程源码解析

4.1 例程的全景列表与设计用意

这套资料里的9个例程,基本都是围绕CAN模式的验证展开,我按用途分了几类:基础收发、过滤配置、回环测试、双CAN转发。下面是我认为一套双CAN开发板应该有、也最实用的9个例程方向,不一定与压缩包里的目录名一一对应,但设计思路是通用的:

例程编号功能核心知识点
1CAN1查询发送端口初始化、发送邮箱操作
2CAN1中断接收FIFO中断、中断优先级配置
3CAN2查询发送CAN2初始化、过滤器复用
4双CAN自回环测试Loopback模式配置
5CAN波特率配置示例不同波特率切换
6标准帧过滤实验过滤器屏蔽位配置
7扩展帧收发实验29位ID处理
8双CAN网关转发数据从CAN1转发至CAN2
9与上位机CAN盒子联调发送接收、波形验证

4.2 例程1:CAN1查询发送

这个例程是入门第一课,它的核心逻辑很简单:初始化CAN1,配置波特率500kbps,然后周期性地把一串数据通过CAN1发送出去。发送代码最关键的步骤是先检查发送邮箱是否为空,再设置标准ID、数据长度、数据内容,最后请求发送。STM32的HAL库代码如下:

CAN_TxHeaderTypeDef TxHeader; uint8_t TxData[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; uint32_t TxMailbox; TxHeader.ExtId = 0; TxHeader.IDE = CAN_ID_STD; TxHeader.RTR = CAN_RTR_DATA; TxHeader.DLC = 8; TxHeader.StdId = 0x123; HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox);

这里有一个新手容易踩的坑:如果上一次发送还没完成就再次调用HAL_CAN_AddTxMessage,函数会返回HAL_BUSY,数据不会发送出去。所以实际项目中要用一个信号量或状态标志来管理发送队列。在发送失败的时候,一定要看返回值,HAL_CAN_AddTxMessage返回HAL_OK才代表成功。

4.3 例程2:CAN1中断接收

查询接收虽然简单,但效率低下,实际产品基本都是用中断接收。中断接收需要先在初始化中使能CAN接收中断,然后在NVIC里使能对应的中断通道。CAN1和CAN2的中断向量在STM32F105上是共享的,都叫CAN1_TX_IRQn、CAN1_RX0_IRQn、CAN1_RX1_IRQn,但CAN2的接收中断和CAN1一样,也在同一个向量里派发,处理时要通过判断是哪个句柄触发的来分流。

我在写中断接收时,通常会在回调函数里加一个队列,把接收到的报文放到一个环形缓冲区,然后主循环里再处理。这样能尽量避免中断里做复杂的事情。中断服务程序里直接做耗时运算,会造成其他中断被阻塞,极端情况下还会把CAN接收FIFO挤爆。

4.4 例程3-4:CAN2初始化与自回环测试

CAN2的初始化模式大体和CAN1一致,但有一个必须注意的点:CAN2的时钟使能外设时,它的时钟来自APB1,但和CAN1不同,CAN2在STM32F105上需要先使能CAN1的时钟,才能正常操作。这不是软件bug,而是硬件设计如此,因为CAN2内部依赖CAN1的时钟域。如果你初始化CAN2之后发现它一直在总线错误状态,先检查是否忘了使能CAN1的RCC时钟。

回环测试(Loopback)是第二推荐的调试手段。在Loopback模式下,CAN控制器把发送的报文直接在内部回送到接收路径,不需要外部总线响应,也不关心总线上有没有其他节点。这个模式可以快速验证MCU的CAN外设和软件配置是否正常。在HAL库中配置Loopback模式的方法是:

hcan1.Init.Mode = CAN_MODE_LOOPBACK;

回环模式测试通过后,再把模式改成正常模式,接上收发器和外部节点做联调。

4.5 例程5-6:波特率切换与过滤器配置

波特率切换例程的核心是在一个工程里通过宏或菜单选择不同波特率,比如500kbps、250kbps、125kbps。如果你使用的是CubeMX生成的代码,直接修改hcan1.Init.Prescaler、hcan1.Init.SyncJumpWidth、hcan1.Init.TimeSeg1、hcan1.Init.TimeSeg2的值,然后重新初始化。我个人实际建议在开发阶段写一个CAN波特率配置表,方便随时切换对比,不用每次重新编译下载。

过滤器配置例程则是教你设置硬件过滤。比如我只希望接收ID范围在0x100到0x1FF的报文,其他报文全部丢弃,那就可以配置一个32位屏蔽过滤器。以这个思路配置时,期望ID设为0x100,屏蔽码设为0x700(二进制11100000000),这样的话ID的bit[10:8]必须精确等于0x001(?这个例子不太对,我应该调整一下)——更准确的做法是这样的:期望ID为0x100,屏蔽码为0x700时,只关心ID的bit10、bit9、bit8,它们必须分别是0、0、1,而低8位被屏蔽掉,所以只要ID范围在0x100到0x1FF之间都能通过。这个动作在HAL库中对应了一个CAN过滤器配置结构体,需要仔细设置FilterIdHigh、FilterIdLow、FilterMaskIdHigh、FilterMaskIdLow。

4.6 例程7-8:扩展帧收发与双CAN网关

扩展帧(29位ID)比标准帧复杂的地方在于,它的ID不是一个11位数,而是拆分成两个部分填到报文头结构体里。在HAL库中,需要设置TxHeader.IDE = CAN_ID_EXT,同时把29位ID写入TxHeader.ExtId字段。如果设备要和J1939(一种基于CAN的高层协议)通信,扩展帧是必须掌握的,J1939的PGN数据就是通过29位ID组织起来的。

双CAN网关转发例程是这套板子的精华。它的逻辑是:初始化CAN1和CAN2,分别配置好中断接收,然后当CAN1收到报文时,在中断回调里把它原封不动(或做ID映射后)通过CAN2发出去,反向同理。网关的核心在于ID映射表的设计——比如CAN1上的ID 0x123,可以在内部查表,映射成CAN2上的ID 0x456再发送。实际项目中还需要加入过滤、速率匹配和优先级管理。简单的转发代码示例如下:

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef RxHeader; uint8_t RxData[8]; if (hcan->Instance == CAN1) { HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData); SendToCAN2(&RxHeader, RxData); // 转发到CAN2 } }

4.7 例程9:与CAN上位机联调

最后一个例程是和PC端CAN分析工具(比如周立功的CAN卡、创芯科技的USB-CAN等)联调。上位机发送数据,板子接收后回显或转发,这个联调过程是验证整体收发链路是否正常的最终手段。联调时首先要确认两端波特率一致,否则表现在现象上就是板子接收不到任何报文,或者偶尔进入总线错误状态。用上位机发出标准帧ID 0x123,数据“11 22 33 44”,如果板子能正确接收并在串口打印出来,说明CAN链路已经通了。

5. 常见问题排查与避坑指南

5.1 硬件层面的疑难杂症

CAN总线通信不稳定的常见原因,第一就是终端电阻缺失或重复。总线两端必须各有一个120欧电阻,缺少终端电阻会让信号反射严重,在波特率较高时表现特别明显,经常出现报文丢失或错误帧。终端电阻重复则在多个节点都焊了120欧电阻,总线上等效电阻变小,差动信号幅度下降,通信距离缩短,严重时也会通信失败。

第二是电源问题。如果TJA1050的5V供电纹波太大,总线差分信号的共模范围会漂移,导致接收方无法正确解析。这个可以用示波器看CANH和CANL的波形,正常波形应该是明显的方波差分,如果波形有毛刺或者幅度不足(正常差动幅度约2V),优先检查收发器电源。

第三是TXD/RXD接线错误。这种错误最隐蔽,因为接反后板子不发热、看起来一切正常,但就是收发不通。用示波器测量TJA1050的TXD引脚,如果没有波形,说明MCU侧没有输出;如果有波形但CANH/CANL上没有差分信号,那大概率是TXD/RXD接反或芯片坏了。

5.2 软件层面的常见报错

通信时常见的一个状态是CAN外设进入总线关闭状态(Bus-Off)。总线关闭的原因一般是发送错误或接收错误累计超过阈值。排查步骤是:

  1. 先看波特率是否一致,这是最常犯的错;
  2. 检查终端电阻是否正常;
  3. 检查总线长度,如果总线过长或分支过长,信号反射会累积错误;
  4. 用调试器读CAN主状态寄存器(CAN_MSR)的ERRI位,看是不是进入了总线错误状态。如果是,HAL库的HAL_CAN_ErrorCallback会被触发。

另一个常见问题是发送失败,返回HAL_BUSY。这个多半是因为发送邮箱没有及时被释放,也就是上一次发送还没完成,或者发送中断没有正确触发。解决方法是发送前检查邮箱是否空闲,或者发送后等待发送完成中断,不要连续调用。

5.3 提高可靠性的几个实用技巧

实际项目中,为了提升CAN通信的鲁棒性,我一般会做这么几件事:

  • 软件上增加报文超时检测机制,超过一定时间没收到某节点的报文就报警或切换冗余通道;
  • 接收中断里用DMA缓存数据,减少CPU中断负载;
  • 发送数据时做周期性重发,如果连续多次失败就检查总线状态;
  • 过滤器的使用要足够具体,别把所有报文都接收进来,防止恶意报文或大量无关报文造成系统卡顿。

5.4 调试工具推荐

手边最好备一台USB-CAN分析仪,几十块钱的也可以,能实时看总线上的报文、错误帧,还能生成特定报文做测试。没有逻辑分析仪或示波器时,USB-CAN是最快定位问题的工具。其次,串口打印也不能少,板子收到报文后通过串口打印出来,是最直观的调试手段。如果条件允许,示波器双通道测CANH和CANL的差分波形,能直接看出信号质量、边沿陡峭程度和共模噪声。

6. 实用心得与扩展方向

基于STM32F105R8T6和TJA1050做的双CAN开发板,兼顾了成本、体积和功能三方面的平衡,尤其适合小批量定制项目。我自己在实际项目中用过类似方案做车载诊断网关,板子放在车内环境,长时间运行稳定性能够接受,但要注意如果是车规级严格要求,建议把TJA1050换成带唤醒功能的TJA1043或国产车规级收发器,并在总线上加保护电路。

如果想把这套方案往产品化方向推,可以走几步扩展:第一,加入CANopen或J1939协议栈,提高数据层兼容性;第二,集成SD卡或Flash,做车载数据记录仪;第三,通过USB或以太网上传数据,做一个数据采集网关。F105本身带USB OTG和以太网MAC,这些扩展在硬件上都有切入点。

最后再分享一个我在调试中总结的经验:拿到板子后别急着跑复杂例程,第一步先用回环模式验证MCU的CAN外设是否正常,第二步再接USB-CAN分析仪做单节点收发,第三步才挂真实总线。每一步都有明确的现象判断点,能省下大量排查时间。双CAN开发本身并不神秘,只要硬件链路可靠、软件配置正确、调试工具到位,半天时间完全能跑通基础通信。

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

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

会议离线录音APP:无网络记录能力对比

经常外出参与线下会议的从业者多半遇到过这类情况:政企会场信号被屏蔽,开了两小时的会,录的音没法实时转写,散会后要对着音频逐字扒3个小时才能出纪要;户外做行业访谈,偏远区域没信号,录完的素材…

作者头像 李华
网站建设 2026/8/31 23:16:35

步进电机选型、驱动与调试全攻略:从脉冲原理到失步排查

做硬件这些年,步进电机是我手里出现频率最高的执行元件之一。3D打印机的挤出机、CNC雕刻机的三轴、贴片机的送料台、甚至自动窗帘的卷轴,拆开外壳一看,里面多半就是一颗步进电机。这玩意儿最迷人的地方在于:给一个脉冲&#xff0c…

作者头像 李华
网站建设 2026/8/31 23:14:38

晶体管从入门到实战:BJT开关、放大与选型避坑指南

自己动手折腾电子这些年,有一个东西几乎每块板子上都见得到:晶体管。玩单片机的人,第一课点灯,第二课十有八九就是“用晶体管去驱动继电器、电机、灯带”。后来做电源、做驱动板、修设备,它也永远在其中。很多人觉得晶…

作者头像 李华
网站建设 2026/8/31 23:13:30

DDR4内存从原理到实战:时序、IDD与PCB布局布线全解析

做硬件的人应该都有过这种经历:好不容易画完一块板子,DDR4的时序却怎么调都调不过,或者功能验证时跑个压力测试就死机,最后排查半天发现是走线等长没做够、阻抗不连续,甚至就是一颗匹配电阻贴错了位置。DDR4这块内容&a…

作者头像 李华
网站建设 2026/8/31 23:11:23

PCB板级Bring-Up全流程解析:硬件调试实战指南

拿到一块刚焊接完的PCB,那种既兴奋又紧张的心情,估计每个硬件工程师都深有体会。兴奋的是几个月的设计终于变成了实物,紧张的是这玩意儿上电之后到底会不会按预期工作。板级启动调试,也就是常说的Board Bring-Up,就是连…

作者头像 李华
网站建设 2026/8/31 23:10:31

示波器音乐入门:从李萨如到X-Y模式的声音可视化工坊

我第一回在B站刷到示波器音乐的视频时,整个人都愣住了:一台老式模拟示波器的屏幕上,一朵花正在随着贝斯声绽放,而声音本身竟然就是从这台示波器里出来的。我盯着屏幕看了整整二十分钟,脑子里反复就一句话——这玩意儿到…

作者头像 李华