ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32F103RCT6最小系统板设计制作全流程:从原理图到MDK配置

STM32F103RCT6最小系统板设计制作全流程:从原理图到MDK配置 前一阵把手上的STM32F103RCT6核心板焊完、调通前后折腾了差不多一个周末。这板子是我给自己做的第3块最小系统板前面两块分别是C8T6和F407VET6这次换成RCT6图的就是它256KB Flash和48KB SRAM跑一些稍微复杂点的逻辑、日志缓冲、字库缓存都宽松很多。这篇文章把这次从原理图设计、PCB打样、手工焊接到MDK工程配置、固件库移植、SWD下载调试的完整过程捋一遍。网上关于C8T6最小系统的资料已经多到溢出来了但RCT6在引脚封装、启动配置、Flash容量差异上还是有一些小坑这篇文章重点讲这部分给也想自己画板子、不想一直用开发板的同学做一个参考。说句实在话最早玩STM32的时候我也直接买现成的核心板几十块钱还带USB转串口省事是真省事。但玩到后面你会发现核心板上的引脚引出、电源布局、晶振位置不一定符合你自己的项目需要尤其是做电机驱动、传感器阵列、带LCD显示屏这类东西的时候接口位置乱、走线绕、还得飞线特别难受。自己做一块最小系统板核心价值不是省钱而是“知道自己这块板子的每一根走线是怎么走的、每个电容是干什么用的”后续在外围电路上翻车的时候排查起来会非常快。这篇文章的核心就是记录这块STM32F103RCT6最小系统板从设计到配置的全过程重点在MCU配置环节包括Keil工程怎么建、固件库怎么选、下载器怎么配、常见报错怎么解。1. 整体设计与方案选型1.1 为什么是RCT6而不是C8T6或者RBT6先看一颗料怎么选。STM32F103系列里大家用得最多的是C8T648脚64KB Flash20KB SRAM。做个小车、点个灯、跑个逻辑控制完全够用而且价格便宜、资料满天飞。但这几年随着屏幕、传感器、通信协议栈往项目里越塞越多64KB Flash真的有点吃紧。我上一个用C8T6的项目光UI界面加中文字库就占掉了差不多40KB Flash再塞协议解析、日志存储就开始扣扣搜搜了。RCT6同样是LQFP64封装引脚兼容RB、RC、RD、RE这一整个家族只是Flash和SRAM容量不同。RCT6是256KB Flash、48KB SRAM主频还是72MHzCortex-M3内核。比RBT6128KB Flash/20KB SRAM容量翻倍价格也就贵几块钱性价比很高。引脚兼容这个点太重要了。如果你之前用的是C8T6LQFP48要换RCT6还得重新画板子。但如果像我这次一样直接从设计阶段就选LQFP64封装以后想升级到RE512KB或者降级到RB只需要换芯片板子不用动。底板和核心板分离的设计思路也是这个道理核心板定义好接口底板按项目需要自己画迭代速度快很多。1.2 最小系统板到底“最小”到什么程度很多初学者对“最小系统”的理解就是芯片加电源、加晶振、加复位能跑起来就行。这个理解对吧对但不完全。STM32F103RCT6要真正稳定运行至少需要这几块电源系统3.3V供电每个电源引脚都要就近放置100nF去耦电容芯片旁边再放大容量的钽电容或电解电容做低频滤波。时钟系统8MHz主晶振加两个负载电容还有32.768kHz的RTC晶振如果用到RTC或者低功耗唤醒就需要。复位电路NRST引脚上拉电阻加对地电容经典配置是10kΩ上拉加100nF电容。启动配置BOOT0和BOOT1引脚的电平设置决定芯片从哪里启动。下载调试接口SWD四线SWDIO、SWCLK、GND、3.3V足够用建议把NRST也引出来。去耦和滤波这个最容易忽略但又最致命。我这次做的板子除了这些最小必须项还额外加了电源指示灯、用户LED、一键复位按键、USB转串口预留接口算是一个“实用型最小系统板”。不加这些也能跑但调试的时候有颗LED真的方便太多。当然板子引出的排针尽量把所有IO都引出来方便后续飞线或者插底板。1.3 供电方案选型LDO还是DCDC最小系统板的输入电源一般有两个来源USB的5V或者外部直流电源。我这次把两种都做了兼容板载一个USB Micro接口同时留了一个5V和GND的焊盘方便外接电源。5V转3.3V的方案纠结了一下。用DCDC效率高但外围器件多电感选型也讲究在最小系统板上属于过度设计。板子整体电流不大LDO完全够用还安静纹波也干净对ADC采样友好。我选的是AMS1117-3.3便宜大碗手册上写着最大1A输出实际稳定输出500mA没问题驱动传感器、OLED、小屏这类外设够了。如果后续外设功耗大可以换成RT9193或者ME6211这类低压差LDO压差更低、纹波更小但引脚不兼容得改板子。对了AMS1117输入输出端都要加电容。输入端并10μF钽电容和100nF陶瓷电容输出端并22μF和100nF具体取值看手册推荐值别偷懒这些电容直接影响电源稳定性。2. 硬件设计核心细节解析2.1 电源引脚的每个电容都有讲究STM32的数据手册上写得很明白每个VDD引脚需要接一个100nF的陶瓷电容且尽量靠近引脚放置。RCT6有4个VDD引脚加1个VDDA加上VREF数下来要在芯片周围摆7~8个100nF电容。很多人画板子的时候觉得电容多随手放几个就算完事。实际上高频去耦电容的位置比容值更重要。如果电容离引脚太远走线电感会抵消掉电容的高频滤波效果等于白放。我的做法是LQFP64芯片四周均匀布置100nF 0402电容每个VDD或VDDA旁边都有就近的电容位。这个细节在你用电烙铁飞线调试的时候感觉不出来但遇到莫名其妙的复位重启、ADC采样毛刺大的时候回来检查电源去耦绝对有收获。大容量储能电容方面我放了两个一个47μF钽电容放在板子电源入口处负责整个板子的低频储能一个10μF陶瓷电容放在芯片电源输入附近。为什么不用两个大电解因为储能电容需要容值大但不同容值的电容谐振频率不同小容值陶瓷电容高频特性好大容值电解/钽电容低频储能强两者搭配效果最好。2.2 主晶振电路参数怎么定8MHz晶振配两个负载电容这个电路看着简单但参数选错了会导致晶振起振困难、频率偏大偏小甚至完全不起振。晶振的负载电容参数取决于晶振自身的规格。以我用的这颗8MHz无源晶振为例规格书上写着负载电容CL20pF那么两个谐振电容取值要满足CL(C1*C2)/(C1C2)寄生电容的经验公式。通常两个电容取相同值假设寄生电容约5pF则C1C2约为30pF。但实际设计中直接按晶振厂商推荐的20pF~22pF来取值也问题不大因为STM32内部有集成反馈电阻外部不并联1MΩ电阻也能起振只是加上更保险。这里说一个大坑晶振旁边要走地线隔离不要和高速数字信号线贴着走。我有一次画板子为了省空间把SCL时钟线和晶振线并行走了一段结果I2C通信偶尔卡死、主频异常后来把晶振下方铺地、把走线拉开才解决。晶振电路周围铺一圈地铜对稳定性提升非常明显。2.3 复位电路和启动模式配置NRST引脚上拉10kΩ到3.3V对地接100nF电容按下按键时拉低复位松开后电容充电延时复位释放防止按键抖动。这个是教科书电路照抄就行。BOOT0和BOOT1的处理很多开发板直接用一个跳线帽或者拨码开关来切换。我这次用的方式是在引脚上各焊一个10kΩ下拉电阻默认都是低电平即从主Flash启动正常跑用户程序。如果有人想要串口ISP下载只需要把BOOT0飞线短接到3.3V上再复位一下就行。特别注意BOOT0不能悬空。悬空状态下引脚电平不确定有可能导致芯片启动到系统存储器BootLoader而不是用户Flash表现为程序烧不进去或者上电不运行。这个坑我见过很多新手踩排查的时候先量BOOT0电平。2.4 SWD下载接口与JTAG取舍下载调试接口我强烈建议用SWD四根线搞定SWDIO、SWCLK、GND、3.3V。如果用手头的ST-Link V2连上这四根线就能下载和在线仿真。JTAG需要5根线还占用的IO多而且是20Pin标准接口在最小系统板上太占地方。但有几个细节值得注意。SWDIO和SWCLK是PA13和PA14它们默认就是SWD功能但如果用户代码里面把这两个引脚复用成了GPIO下次下载就会失败。解决办法是烧录时按住复位键点击下载在开始下载瞬间松开复位键让芯片在复位状态下进入下载流程。ST-Link可以在MDK里勾选“Reset and Run”这样每次下载后自动复位运行。另外建议把NRST也引到下载接口。SWD协议里不接NRST也能下载但如果你在程序里禁用了SWD引脚就只能通过NRST硬件复位的方式配合下载器找回烧录口。我在板子上引了5Pin的SWD排针3V3、SWDIO、SWCLK、GND、NRST调试的时候非常方便不用每次重新插拔。3. PCB布局与手工焊接实操3.1 LQFP64的布局要点LQFP64封装是0.5mm引脚间距引脚密布局的时候最忌讳把电容放得太远。我的布局思路是芯片居中四边留出走线通道和去耦电容位置。100nF去耦电容统一放在芯片背面对应电源引脚的位置需要开过孔或者正面靠近引脚的地方保证走线尽可能短。8MHz晶振放在芯片旁边远离板边和功率器件晶振正下方铺地并打过孔阵列。排针接口分布在板子两侧方便搭面包板和插底板。电源入口、LDO、储能电容放在一角和芯片之间用地隔离。布局这东西没有绝对标准但核心原则只有一个高频和敏感信号线越短越好电源路径越宽越好大电流回路不要和小信号回路共用一段走线。电源走线我加了加粗处理默认信号线是0.25mm电源主干线改成0.8mm3.3V这条网络尽量整板铺铜降低压降和地弹噪声。铺铜间隙设小一点避免细长的地线孤岛。3.2 手工焊接LQFP64的经验0.5mm间距的LQFP64芯片手工焊接对新手来说是比较有挑战的一件事但掌握了方法其实难度没那么大。我的焊接流程供参考先在焊盘上均匀上一层薄锡再把芯片对准方向放上去对齐所有引脚后用焊锡将四个角固定。然后从一个角开始把焊锡丝压在引脚上让熔化的焊锡自然覆盖引脚和焊盘一整排拖过去。引脚多、间距小直接拖焊容易连锡所以拖完后要用吸锡带清理多余焊锡。吸锡带配助焊剂效果立竿见影引脚之间干干净净。焊完先别急着上电用万用表蜂鸣档检查相邻引脚有没有短路重点是VDD和GND之间不要短路。LQFP64有4个VDD和4个VSS任意一组短接都会导致上电烧板。这个步骤不能省宁可检查三遍也不要上电冒烟。3.3 首次上电检查流程焊接完到烧录之前建议按下面的顺序做检查用放大镜或手机微距镜头检查所有引脚是否有虚焊、连锡。万用表蜂鸣档测VDD和GND之间是否短路正常应该是开路或有大电容充电的滴一声后断开。不插芯片或者不焊芯片的情况下先给板子供电量3.3V输出是否正常。确认3.3V正常后再焊芯片重新测一次VDD/GND。用示波器没有的话用万用表频率档检查8MHz晶振两个引脚是否有振荡波形正常起振后电压约在1.6V~1.9V之间波动。我第一次自己做板子的时候第2步没认真做直接上电结果AMS1117发烫一查发现芯片焊接时有个引脚连锡把3.3V和地短在了一起。从那以后每次焊接完上电前我都会老老实实测一遍电源对地阻抗。这个习惯救过我好几次板子。4. MCU固件配置与下载调试环境搭建4.1 MDK工程搭建与芯片型号选择硬件焊接完成进入“MCU配置”这个主题。首先是搭建开发环境。我用的是Keil MDK 5.x装好以后第一件事是在Pack Installer里安装STM32F1系列的Device Family Pack。如果装过F4的开发环境也要确认F1的包在因为F1和F4是不同的Pack。新建工程的时候Device选型要选对。很多人用的习惯是在搜索框输入“STM32F103RC”然后选了“STM32F103RC”而不是“STM32F103RCT6”这在MDK里是同一个选项因为MDK的Device列表是按型号族归类的选了STM32F103RC就包含了RCT6。但如果你选了“STM32F103RB”最终生成的Flash算法和链接脚本就会按128KB来程序超过128KB就链接报错这是个隐蔽问题。这里特别提醒一下MDK工程建立时选择Device后会自动配置好相应的芯片型号但你必须手工确认Output选项卡里“Create HEX File”有没有勾选。如果你需要生成HEX文件烧录到芯片这一步不能漏我在新手阶段就因为这个勾没打上整了半天生成的HEX文件。4.2 固件库包选择标准外设库还是HAL库STM32F103这一代芯片的开发方式有三种主流选择寄存器直接操作、标准外设库StdPeriph、HAL库配合CubeMX生成代码。我的建议是如果是从零学起直接学HAL库也没什么问题STM32CubeMX生成初始化代码效率高F1系列也支持得很好。但如果你手上有很多老项目的代码、例程都是基于标准外设库写的那用标准外设库也不丢人。我这次用的是标准外设库V3.5理由很实在一是我手头的RCT6固件库包和例程都是这个版本二是我要移植之前项目的代码标准库兼容起来更省事。标准和HAL之争这里不展开只提一点STM32F103标准外设库在MDK工程里需要在C/C选项卡的Define里加两个宏USE_STDPERIPH_DRIVER和STM32F10X_HD。第一个宏是告诉编译器启用外设驱动库第二个是告诉编译器当前芯片属于高密度器件RCT6的Flash是256KB属于高密度类别对应ST芯片密度分类中HD。如果你漏了STM32F10X_HD这个宏编译的时候极大概率会报错或者链接异常因为库内部很多条件编译是根据这个宏来展开的。4.3 标准外设库工程结构我这里把RCT6的工程目录结构列出来照着建就行不用过度纠结Project/ ├─ User/ main.c、stm32f10x_it.c、system_stm32f10x.c ├─ Core/ startup_stm32f10x_hd.s启动文件 ├─ Periph/ stm32f10x_conf.h、stm32f10x.h ├─ Periph/src/ stm32f10x_gpio.c、stm32f10x_rcc.c等外设库源文件 └─ Periph/inc/ 外设库头文件启动文件必须用startup_stm32f10x_hd.s而不是ld.s或者md.s。HD代表高密度适用于Flash容量在256KB~512KB之间的F103器件刚好覆盖RCT6。MD版本适用于中密度64KB~128KB如果选错程序可能运行不正常甚至完全跑不起来。4.4 ST-Link调试器配置与常见报错接下来说调试器配置。MDK里点击魔法棒Options for Target切到Debug选项卡右侧选择“ST-Link Debugger”然后点旁边的Settings。这里要检查两个东西一是右侧的“Flash Download”里选中的Programmer算法必须是“STM32F10x High-density 256K Flash”二是Reset策略建议选“Hardware Reset”有些ST-Link固件可以在连接时自动复位目标芯片。最常见的三个报错分别说一下第一个是No Target Connected。这个基本上是接线问题SWDIO、SWCLK、GND三根线必须接对而且目标板要上电。注意ST-Link V2供电能力有限如果目标板上有大电流外设尽量单独供电ST-Link只负责下载和调试不要让它承担负载电流。第二个是RDDI-DAP Error。这个报错通常是芯片进入了低功耗模式或者SWD引脚被程序改成了普通GPIO。解决办法是按住板子上的复位键不放点击下载等MDK提示连接成功后立刻松开复位键。如果每次都这么麻烦还有一个终极办法把BOOT0拉高并复位进入BootLoader模式用FlyMcu这类串口ISP工具清除Flash之后SWD就能重新连上了。第三个是Flash Download failed - Cortex-M3。这个一般是Flash算法选错了去Utilities或者Flash Download里检查是不是选的High-density或者芯片Flash被写保护了。写保护解除方式是用ST-Link Utility这类工具连接芯片选择Option Bytes把Write Protection级别改成Disabled然后重新下载即可。4.5 最小系统验证代码配置完成后先烧一个最小验证代码确认芯片、晶振、下载链路都没问题。下面这段代码实现的功能是PA0引脚配置为推挽输出以500ms间隔翻转电平用万用表或者LED观察波形。#include stm32f10x.h void Delay(volatile uint32_t nCount) { while(nCount--) { } } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); while(1) { GPIO_SetBits(GPIOA, GPIO_Pin_0); Delay(7200000); GPIO_ResetBits(GPIOA, GPIO_Pin_0); Delay(7200000); } }如果这段代码能正常让LED闪烁说明最小系统板从硬件到软件全部打通了。Delay函数里7200000这个数字在72MHz主频下大约是100ms左右的延时不做精确计时用只是验证心跳。这里补充一个易错点MDK工程默认使用外部8MHz晶振作为系统时钟源如果你板子上没焊晶振或者晶振没起振程序会一直卡在SystemInit里面表现出来就是程序下载成功但完全没反应。排查方法是直接在调试状态下全速运行在SystemInit里设断点看是不是卡在等待HSERDY标志位置位。要是卡住优先查晶振电路和负载电容。5. 常见问题与排查技巧实录5.1 上电后芯片发热严重芯片发热第一件事就是断电然后量VDD和GND之间的阻抗。小于10Ω基本可以确定焊接短路。用万用表跟在引脚上逐一排查或者借助热成像仪看发热点没有热成像仪就把助焊剂洗干净后仔细观察有没有锡珠残留。0402的电容非常容易被锡珠桥接短路焊完以后清理助焊剂要仔细。5.2 晶振不起振首先确认晶振是好的换一颗试试。然后查负载电容是否虚焊电容焊接不良会导致起振条件不满足。还可以在晶振两个引脚并联1MΩ电阻加强反馈帮助起振。另外检查晶振是否和旁边走线靠太近这个在Layout阶段就要注意。5.3 程序能下载但运行异常主频感觉不对如果你用的是标准外设库检查system_stm32f10x.c里#define SYSCLK_FREQ_72MHz有没有打开。默认情况下如果定义的是SYSCLK_FREQ_8MHz或SYSCLK_FREQ_36MHz程序能跑但外设时序全部错乱串口波特率对不上、延时不准。这种情况不仔细看非常难排查。5.4 SWD下载时好时坏这个是接触不良居多。检查排针焊接质量杜邦线是否松动。另外把SWD接线尽量缩短线太长会增加信号反射高速下载时容易失败。实在不行把MDK里SW Mode的Max Clock从4MHz降到1MHz试试稳定性会好很多。5.5 最小系统板vs开发板调试差异最后说一句经验之谈自己画的最小系统板调试起来和买来的开发板最大的区别是少了板载的USB转串口没有调试打印通道。我建议在底板或者外设板上预留一个USB转TTL模块接口CH340或者CP2102都行调试的时候插上去就能用串口打印。串口打印调试是嵌入式开发里效率最高的手段之一没有这个口出问题就得靠猜板子再小也要把调试口留好。我自己画的核心板都预留了PA9、PA10、GND三根串口引脚调试体验会舒服很多。这块RCT6最小系统板目前已经被我用到了一个环境监测小项目上跑着SHT30温湿度传感器加一个0.96寸OLED屏256KB Flash随便造代码写得再奔放也不用担心空间。回头再看自己做最小系统板的意义其实是倒逼你把芯片的数据手册、电路设计、启动配置这些最基础的东西全部吃透。买来的核心板用一百次你也不会知道BOOT0为什么要接下拉电阻但自己画过一次这些东西就长在脑子里了。如果后续还想扩展可以考虑在核心板上加一个SD卡座用来存日志或者把这颗RCT6的FSMC接口用起来接一个TFTLCD屏幕F103的FSMC驱动屏幕还是很流畅的外扩SRAM也行。硬件这东西就是这样板子做好了后面能玩的路子就宽了。
返回列表