STM32F105双CAN开发板制作:原理图与9个例程全解析

发布时间:2026/9/1 2:47:37
STM32F105双CAN开发板制作:原理图与9个例程全解析 简介本资源是一套面向嵌入式初学者与CAN通信开发者的完整学习套件聚焦STM32F105系列双CAN总线硬件设计与驱动实践解决CAN节点开发中原理图参考缺失、协议栈调试困难、多外设协同验证不足等典型问题。压缩包共含数十个文件具体数量未提供主体为PDF格式的硬件原理图含STM32F105R8T6与双TJA1050 CAN收发器电路、Keil工程源码及配套说明文档总大小24.16MB其中9个软件例程覆盖ADC电压采集串口转发、CRC校验、双CAN 500Kbps通信、USART/LED/TIM/SysTick基础外设操作及按键查询控制等核心场景代码结构清晰、注释完整便于逐模块理解与移植。已有142人下载学习特别适合开展车载通信原型开发、工业现场总线教学实验或毕业设计硬件选型验证。 做双CAN开发板我是吃过亏的。早期拿两块F103拼CAN总线软件凑合能跑硬件一查全是问题后来把方案改成STM32F105R8T6配两路TJA1050收发器用了挺长时间才把这套双CANbus开发板从原理图到例程完整整理出来。这篇博客就围绕这套板子的硬件PD版原理图和9个软件例程源码展开讲清楚为什么选这个单片机、TJA1050外围怎么设计、双CAN通道怎么布局以及例程里到底写了哪些东西。对于正在做CAN总线相关项目或者准备用手头板子入门CAN通信的朋友这个内容都可以直接参考。板子本身解决的是两个问题一是把物理层的收发从控制器里独立出去二是给CAN1和CAN2真正提供两路可以同时工作的总线接口。硬件部分可以直接照着打样软件部分有现成的收发、滤波、桥接例程属于拿到手就能开始改的类型。1. 项目概览这块双CAN板是做什么的1.1 为什么双CAN方案偏偏选STM32F105R8T6STM32F105系列在ST产品线里属于“互联型”和更常见的F103相比最大的差异之一就是内置了两个bxCAN控制器。F103通常只有一个CAN如果要做双通道最简单的办法是用两片F103或者外扩独立的CAN控制器比如MCP2515但这两种方案都有明显的代价。外扩MCP2515走SPI软件上要处理SPI命令时序还要维护控制器内部的寄存器和滤波器配置比较繁琐。两片F103方案更麻烦两个单片机之间怎么通信、固件怎么同步、调试时怎么区分故障源全都要额外设计。而F105R8T6本身集成两个CAN内核相当于把“硬件双通道”直接放进了MCU里。CAN1和CAN2共用一套帧收发底层资源软件上只需要处理好滤波器分配和邮箱使用就可以让两路CAN同时工作。因此对双CAN这种需求来说选F105比外扩方案省事得多。R8T6这个封装后缀意味着LQFP64引脚、64KB Flash、20KB SRAM、工作温度范围-40到85度。做CAN节点、数据网关、仪表采集这类应用这个资源基本够用。如果后续要跑更大的协议栈可以升级到F105VCT6或者107系列板子的主控核心不用大改。1.2 TJA1050收发器CAN控制器和物理总线之间的“翻译官”STM32内部的bxCAN控制器输出的信号不是物理总线上的差分电平它是LVTTL逻辑电平不能直接接到CAN_H和CAN_L上。这个时候需要CAN收发器把逻辑信号变成总线上的差分信号并且在接收时把差分信号还原成逻辑电平。TJA1050就是干这个的。TJA1050是NXP的一代经典收发器兼容PCA82C250的引脚定义可以直接替换老设计。它的工作电压是5V驱动能力强通信速率最高支持1Mbps而且内部集成了短路保护、过热保护和TXD显性超时保护。对于开发板这种需要频繁插拔总线、误接线的场景这几个保护功能非常重要。像我现在手里这块板子选TJA1050而不是更老的82C250主要就是看中它的EMC表现和这些保护机制。1.3 这块双CAN板能干什么双CAN的实际应用非常典型电动自行车控制器、工业设备状态采集、汽车仪表调试、机器人底盘通信几乎只要有多个CAN节点需要互联双CAN就有用武之地。具体到这块开发板它提供了两路独立的CAN接口每一路都可以单独配置波特率、过滤器和工作模式。你可以在CAN1上接一个设备CAN2上接另一个设备然后通过MCU实现两路总线之间的数据转发或协议转换。这就是标准的CAN网关功能。9个例程里专门有双CAN透传示例做网关原型特别顺手。另外要说一下PD版原理图这个事。我自己理解所谓PD版主要是指这个板子的硬件已经过了性能验证不是那种随手画的demo原理图。电源、时钟、CAN收发、接口保护这些环节都做了比较完整的设计照着打样出来是可以直接烧程序跑的。这一点比单纯拿一个半成品原理图要可靠。2. 硬件原理设计拆解最小系统与CAN通道2.1 最小系统电源、时钟、复位、调试口一个都不能少先看电源部分。这块板子的输入一般是USB 5V板子上通过AMS1117-3.3把5V降到3.3V给MCU供电。CAN收发器TJA1050用的是5V直接从输入电源取不经过1117。这一点要注意如果只有3.3V供电TJA1050是没法正常工作的TJA1050必须5V供电。有人想省一路电源用3.3V给TJA1050结果总线电平完全不对后面会讲到。时钟方面F105外部接了8MHz晶振配合内部PLL倍频到72MHz系统时钟。板上预留两个22pF负载电容晶振到MCU的走线要短。另外F105的BKP区还有一个32.768kHz的备用晶振位置如果板上做RTC功能就贴上不做就空着不影响CAN功能。复位电路是一个按键加一个10k的上拉电阻标准RC复位。调试接口用的是SWD只占用PA13和PA14两个引脚比JTAG省IO这个在开发板上已经很常见了。注意原理图里SWD接口最好留一个3.3V和GND这样调试器供电和连接都方便。2.2 TJA1050外围电路5V供电、3.3V逻辑、120Ω终端电阻TJA1050的引脚不多外围电路写得对不对直接决定这路CAN能不能稳定工作。我按引脚逐个说。1脚TXD接MCU的CAN_TX引脚4脚RXD接MCU的CAN_RX引脚。这里要特别强调STM32的IO如果能容忍5V可以直接和TJA1050的RXD相连因为TJA1050的RXD输出高电平是5VSTM32F105的引脚是FT5V容忍的所以不需要加电平转换。很多第一次做的人在这里犹豫半天其实FT引脚直接连没有问题。但前提是MCU侧引脚确实标注为FT不能想当然全连。3脚VCC接5V2脚GND接地。5脚Vref是参考电压输出内部输出VCC/2这个引脚一般悬空或者接个小电容去耦不建议拿它给别人供电。6脚和7脚是CANL和CANH这是总线端重点来了。总线上需要两个120Ω终端电阻一个在网络最左端一个在最右端。对于开发板通常的做法是在板上放一个120Ω电阻通过跳线帽或0Ω电阻决定是否接入。如果调试时只有一块板子就把板载终端电阻接上如果接的是真实总线且总线两端已经有终端电阻这块板的终端就要断开否则总线阻抗会偏低。8脚S是静音模式控制。S脚拉高时进入静音模式只能收不能发拉低或者悬空内部有下拉就是正常收发模式。可以用一个GPIO去控制S脚做总线诊断和故障恢复时非常有用。TJA1050的总线端还需要考虑ESD。开发板阶段可能不加但如果是产品化设计CANH和CANL对地之间一定要加ESD二极管或者TVS管。常见的有PESD1CAN、SMAJ24CA这种选型主要看工作电压和钳位能力。另外还可以加共模电感抑制共模噪声很多车载CAN模块上都会加。2.3 双通道布局与信号完整性CANH/CANL不能随便布原理图画好之后PCB走线如果乱来照样不行。双CAN板上有两路CAN每一路的CANH/CANL都是差分对走线时要保持平行、等长、紧耦合。两个通道之间最好拉开距离别让CAN1的差分线贴着CAN2走避免互相串扰。再一个细节是TJA1050的VCC去耦电容应该尽量靠近3脚和2脚之间常见做法是0.1uF加10uF并联。晶振对地电容、复位电容这些也都尽量靠近芯片。原理图是“逻辑连接”PCB是“物理实现”后者对信号质量的影响非常大。还有接地问题。MCU的地和TJA1050的地是同一个地网络不要割裂。如果将来做隔离CANTJA1050那边要换成隔离收发器比如ISO1050或者数字隔离器加1050电源也要分离开。但那是另一个话题这套开发板做的是非隔离版本地是共用的。2.4 拿到原理图后先查这几个点拿到这份原理图或者任何类似的双CAN原理图我建议按这个顺序做初步检查。第一确认两路CAN的TXD/RXD分别接到了哪个引脚。F105的CAN1是PA11/PA12CAN2通常是PB12/PB13。注意PA11和PA12同时也是USB的DP/DM引脚如果板子同时做了USB就要看有没有引脚复用冲突以及编译时有没有对USB做Disconnect控制。第二查终端电阻是不是可以通过跳线断开。如果固定焊接在板上那这块板就只适合当总线端点用不能挂在总线中间。第三查TJA1050的S脚是否被拉到了固定电平。如果原理图上S脚悬空是正常模式如果通过10k下拉到地也是正常模式如果设计成GPIO控制要确认GPIO默认输出低否则一上电就进了静音模式板子永远发不出数据。第四查电源容量。TJA1050工作时每个通道大约几十毫安两个通道加上MCU输入电源电流余量要够。USB供电通常500mA够用但如果是那种劣质USB线压降一大5V往下掉CAN总线的差分电平也会跟着出问题。3. 软件例程源码解析9个例程的内容与用法3.1 9个例程按什么思路组织这套资料的软件部分一共9个例程组织结构比较清晰从CAN1单路自测开始逐步到双CAN互通最后是中断、滤波这类工程开发常用的场景。我按我实际跑过的顺序列一下读者可以照着这个顺序练习。例程1CAN1回环模式自发自收。不需要接总线板子自己发自己收主要用于验证CAN外设和收发器基本工作。例程2CAN1正常模式发送。例程3CAN1正常模式接收轮询方式。例程4CAN1中断方式接收。例程5CAN1过滤器配置示例按ID过滤。例程6CAN2回环模式自发自收。例程7CAN2正常模式收发。例程8双CAN透传CAN1收到的数据从CAN2发出。例程9CAN1/CAN2不同波特率收发测试。这9个例子覆盖了90%的开发场景。其中第8个是网关类应用的核心原型第9个则回答了一个常见疑问两路CAN能不能用不同波特率工作答案是可以的因为CAN1和CAN2虽然共用一套底层资源但位时序寄存器是独立的配置的时候各设各的就行。3.2 bxCAN初始化时钟、GPIO、滤波器分配初始化部分通常分三步。第一步是打开时钟这里有一个很典型的坑无论你只用CAN1还是CAN2建议都把CAN1和CAN2的时钟一起打开。因为在F105互联型里CAN2的滤波器是复用CAN1的如果CAN1时钟没开CAN2的滤波器配置可能不生效接收就收不到。GPIO部分CAN引脚要配置为复用推挽输出。这类代码看起来简单但方向错了就不通。CAN_RX引脚要配置为浮空输入CAN_TX引脚配置为复用推挽输出速率设置成2MHz或者50MHz都行关键是复用模式不能错。滤波器分配是双CAN最需要注意的地方。F105内部CAN1有28个filter bankCAN2的滤波器从CAN1那里匀出来用。常见做法是调用CAN_SlaveStartBank(14)把前14个filter bank留给CAN1后14个留给CAN2。如果这个函数不调用或者数值不对CAN2收到数据但进不了filter表现就是明明总线上有报文程序就是收不到。波特率计算也要说清楚。CAN外设挂在APB1总线上F105在72MHz系统时钟下APB1最高36MHz。波特率公式是Baud PCLK1 / (Prescaler × (BS1 BS2 1))。比如要跑500kbpsPCLK1是36MHz设Prescaler6BS18BS23算下来就是36M / (6 × 12) 500kbps。我整理一个常用配置表方便读者参考。目标波特率PCLK1PrescalerBS1BS2实际波特率采样点1Mbps36MHz38tq3tq36M / (3×12) 1M75%500kbps36MHz68tq3tq36M / (6×12) 500k75%250kbps36MHz128tq3tq36M / (12×12) 250k75%125kbps36MHz248tq3tq36M / (24×12) 125k75%要注意这只是其中一种取点方式BS1和BS2还可以有其他组合具体要参考总线采样点要求。很多工业协议标准推荐采样点放在87.5%附近如果你的项目有严格要求要按采样点需求反过来算分频系数而不是直接套表。3.3 收发代码骨架与中断处理初始化做完发送和接收就比较直接了。标准外设库的发送函数是CAN_Transmit接收函数是CAN_Receive。我这里用标准库风格的字段示意HAL库思路也类似关键是理解参数含义。CAN_InitStructure.CAN_SJW CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 CAN_BS1_8tq; CAN_InitStructure.CAN_BS2 CAN_BS2_3tq; CAN_InitStructure.CAN_Prescaler 6; // 500kbps CAN_Init(CAN1, CAN_InitStructure);正常模式发送有个关键条件总线上必须至少有一个其他节点在接收否则这个帧发送出去没有节点ACK发送就会失败。这也是很多第一次调CAN的人最容易卡住的地方——回环模式能收到一改正常模式就发不出去第一反应是代码问题其实是因为总线上没有第二个节点。中断接收比较常用核心是在CAN_ITConfig里打开接收FIFO0的中断然后在中断服务函数里调用CAN_Receive从对应的FIFO把报文取走。要注意处理完中断后把标志位清掉否则会一直进中断。另外中断服务函数里尽量不要做耗时的协议解析只把报文拷贝到一个环形缓冲区主循环再慢慢处理这样不容易丢帧。这是嵌入式开发的通用经验CAN中断里同样适用。3.4 双CAN透传实验让CAN1的数据从CAN2转发出去双CAN透传例程是这套资料里最有代表性的一个。思路很简单CAN1的接收中断里读到一帧报文直接调用CAN2的发送函数把它发出去。反过来CAN2接收CAN1发送就是双向透传。实际写的时候有两个细节要注意。第一双CAN同时工作时两个接收中断是独立的CAN1_IRQHandler处理CAN1CAN2_IRQHandler处理CAN2不能混。第二转发时如果CAN2总线处于BusOff或者发送失败要处理错误状态不要让一帧坏数据反复重发导致总线拥堵。用这个例程做原型可以实现一个最简单的协议转换CAN1上跑250kCAN2上跑500k两边设备各自按自己的波特率通信MCU在中间做桥接。例程9里专门做了这种不同波特率下的验证实际测试下来只要FIFO深度够用、主循环处理及时不会出现明显的帧丢失。4. 调试与踩坑实录双CAN开发常见问题4.1 硬件问题收发器发烫、总线无ACK、终端电阻没接对先说发烫。TJA1050正常工作时温度正常如果摸上去有明显发烫多半是CANH和CANL接反或者把5V和GND接错了。CANH/CANL接反后收发器虽然不会立刻烧掉但总线上所有节点都会通信失败因为差分逻辑颠倒了。终端电阻问题更隐蔽。总线没有ACK表现就是一直发送失败很多人以为是软件问题其实可能是总线上只有你一个节点没有人回应。这种情况要么再加一个节点要么开启控制器的回环模式确认软件链路。半双工总线上没有第二个节点时即使板载终端电阻接好了也不会自己产生ACK。这是CAN物理特性决定的。另一个常见问题是示波器看波形。正常差分波形在显性位时CANH会从2.5V升到3.5VCANL会降到1.5V隐性位都是2.5V。如果只在CANH上看到波形CANL上纹丝不动收发器或者终端接线多半有问题。4.2 软件问题滤波器“打架”、CAN2收不到、BusOff恢复滤波器“打架”这个现象非常经典。只有一个CAN工作时一切都正常两个CAN同时使能后CAN2的报文老是进到CAN1里或者CAN2收不到。排查方法很简单检查是否调用了CAN_SlaveStartBank以及CAN1和CAN2的filter bank区间是否重叠。我自己的建议是CAN1用bank 0到13CAN2用bank 14到27两边各留一点余量别用满。BusOff也值得说。如果总线上连续发生错误CAN控制器会进入BusOff状态自动断开总线。要恢复软件可以重新初始化CAN或者使能自动总线恢复功能。在标准库初始化里通过CAN_InitStructure.CAN_ABOM这个参数可以开启自动恢复。开这个功能之后如果某一瞬间总线被干扰恢复会快很多。CAN2收不到还有一个容易被忽略的点引脚配置。CAN2的TXD/RXD通常是PB12/PB13如果GPIO配置成了别的复用功能或者板子上CAN2的引脚被某个外设占用了现象就是CAN2初始化正常但完全收不到。看原理图时先确认这两个引脚没有接到别的设备上。4.3 不上示波器的排查方法如果手头没有示波器也可以做初步排查。第一用CAN分析仪或者USB-CAN工具挂在总线上看报文。如果没有分析仪可以用回环模式验证MCU到收发器的链路回环模式能自发自收说明CAN外设本身工作正常改正常模式发送失败大概率是总线上没有第二个节点如果回环正常但接上另一个节点后两边都收不到就往物理层查重点看终端电阻、CANH/CANL接线和收发器供电。这套排查思路的核心逻辑就是分层先隔离MCU再隔离收发器最后看总线。总线通信问题90%都能用这个方法定位。我自己在这些年的调试里用这套方法救了不少次效率比乱试代码高很多。5. 扩展思路从双CAN板到CANopen、本文还有配套的精品资源点击获取