
简介面向STM32F103C8T6智能小车开发者的一份核心板硬件工程设计资源。整套图纸用Altium Designer绘制覆盖原理图、PCB图与元件库不仅适用于智能小车也可移植到其他STM32F103C8T6核心板场景适合嵌入式入门者学习画板也适合创客直接打样制作。压缩包内含61个文件大小15.09MB主要包括AD工程源文件SchDoc、PcbDoc、SchLib、PcbLib、DRC检查报告、网络表、预审PDF以及多版本备份便于查看设计细节与追踪演进。设计已由作者实际打样并验证通过硬件可靠度较高附带的设计规则检查文件还可以辅助排查布线隐患。目前已有1065人学习下载若还需配套驱动板可搜索“STM32智能小车驱动板原理图和PCB图”组合构成完整小车方案。1. 拿到 STM32 智能小车核心板压缩包先想清楚要干什么如果你在某个资料站或学长网盘里看到“STM32 智能小车核心板原理图和 PCB 图.rar”这个文件名大概率不是第一次接触单片机。这个东西解压出来就是一份 Altium Designer 或嘉立创的工程——原理图告诉你芯片引脚怎么连PCB 图告诉你怎么布板而“核心板”这三个字意味着它不包含电机驱动和传感器只是最小系统加上必要的接口排针。你的任务不是欣赏电路而是要把这块板子读懂、改对、或者直接制板回来自己焊然后配上一块电机驱动板和几个红外传感器拼出一台能巡线、能避障的小车。这篇博文会从原理图的最小系统开始讲起再落到 PCB 布局怎么排最后给出把板子跑起来的固件骨架和排错路径。全程不依赖某个具体开源项目的源码只按一线工程师拿到这类资料时“先看电源、再看时钟、然后接口、最后写驱动”的顺序来拆解保证你解压后不迷路。2. STM32 最小系统原理图的五个必读模块2.1 电源树先于一切从 USB 或 DC 口扒起打开原理图先别盯着 STM32 看第一件事是顺着电源入口理出整棵电源树。最常见的设计是 USB 5V 或 7.4V 锂电池经过一个二极管防反接再进入稳压芯片。核心板上通常用 AMS1117-3.3有些新设计会用 ME6211 这类低压差 LDO压差低到 0.2V适合电池电压偏低时仍能稳住 3.3V 输出。电源部分要确认三件事输入电压范围是多少是否在你的小车电源选择范围内3.3V 输出电容用的是不是 10uF 100nF 的组合LDO 的 ESR 要求是否满足有没有电源指示灯和防反接二极管没有的话焊接时容易烧片子。# 电源部分的元件位号习惯仅作参考以实际原理图为准 U2 AMS1117-3.3 Vin5V, Vout3.3V, Iout 最大 1A C5 10uF/0805 输入侧滤波电容 C7 100nF/0603 输出侧高频去耦 D1 SS14 防反接肖特基二极管注意 AMS1117 的压差在 800mA 时大约 1.2V这意味着输入电压至少要 4.5V 才能稳定输出 3.3V。如果你用的是两节 18650 串联约 7.4V那就没问题如果打算用 USB 直接供电5V 输入压差只剩 1.7V还行但低电量时会掉到稳压范围之外。阅读原理图时把电源路径的电容值顺带记下来后面做 PCB 检查时要用到。2.2 时钟电路与复位电路最容易照抄却抄错的两块STM32 核心板的时钟源有两种。一种是用 8MHz 无源晶振配合两个 20pF 负载电容接到 OSC_IN/OSC_OUT另一种是直接从 STM32 内部 HSI 启动省掉外部晶振。你在原理图上看到 Y1 和 C9、C10 就是前者Y1 丝印旁边标着 8.000MHz两个电容取值通常在 10~22pF 之间具体要查晶振的 CL负载电容规格。晶振电路常见的错误是电容接地走线太长、晶振底下铺铜、两个负载电容没对称放置。后面 PCB 布局时会展开说原理图阶段只确认一点——是否有并联一个 1MΩ 反馈电阻在晶振两端。有些低成本设计会省略它实际也能起振但起振时间和稳定性会差一些。复位电路更直接NRST 引脚接一个 100nF 电容到地再通过 10K 电阻上拉到 VCC。这个 RC 时间常数大约是 1ms足够让 STM32 在上电时完成内部复位。有个判断技巧如果你看到 NRST 直接接 VCC 没有任何电阻电容那这块核心板省略了外部复位电路靠 STM32 内部 POR 工作也能跑但调试器连接时更容易出现握手失败。2.3 BOOT 引脚与下载电路决定你能不能烧进程序BOOT0 和 BOOT1 的接法只在原理图阶段排错最直观。BOOT1 一般直接拉地BOOT0 则通过一个 10K 电阻下拉到地同时引出焊盘或短接帽。这个设计允许你把 BOOT0 上拉到 3.3V 进入 ISP 下载模式而默认下拉则从 Flash 启动。如果你发现 BOOT0 悬空没接电阻——悬空的 CMOS 输入引脚会随机读高低电平下载后程序偶尔跑飞就是这里埋的雷。下载调试接口方面2025 年的核心板基本标配 SWD四根线SWDIO、SWCLK、VCC、GND有些还会带一个 NRST。原理图上标识通常是 P1 或 J1旁边注明“SWD”字样。个别老核心板还会拉出一组串口 TX/RX 来做串口下载如果你用的是 ST-Link 或者 DAP-LinkSWD 足够了串口下载口可以空着不焊。# SWD 接口顺序常规接法 Pin1 VCC(3.3V) Pin2 SWDIO Pin3 SWCLK Pin4 GND注意 ST-Link 的 SWD 线序和这块板子的丝印未必一致接线前对照原理图确认别盲目按颜色插。SWDIO 和 SWCLK 不要接反接反后调试器报错“No target connected”很多人误以为芯片坏了其实是线序问题。2.4 最小系统通用性判断这套设计能不能跑 RTOS 和 FSMC看核心板原理图的最高层次判断是确认它是“最小系统板”还是“带外设的增强板”。以 STM32F103C8T6 为例最小系统板会引出全部 20 个 GPIO 到两排 2.54mm 排针外设只保留板载 LEDPC13、按键、USB 从机口。这种设计在智能小车场景下有个好处——电机驱动和传感器接口全部外接核心板布线和底层驱动可以独立调好再拼到小车底盘上。而如果你看的是 STM32F103ZET6 的核心板通常会有 FSMC 液晶屏接口、SDIO、16 位排针等。对智能小车来说ZET6 的核心板有点浪费C8T6 就能干完循迹避障的全部活而且功耗更低。原理图阶段判断标准就一条GPIO 引出数量是否满足小车外设需求电机 PWM 至少 4 路、编码器至少 4 路、红外循迹至少 2 路、超声波 2 路、OLED 备用 4 路合计约 16 个引脚。C8T6 有 37 个 GPIO除去晶振和下载占用的仍有余量。2.5 电机驱动与传感器接口核心板如何外接动力系统核心板本身不带电机驱动这是设计边界。原理图上你看到的电机相关引脚其实是引出的 PWM 输出和电源接口比如标着 TIM1_CH1、TIM2_CH2 的排针孔。智能小车用 H 桥驱动板如 TB6612FNG时接线方式是STM32 引脚驱动板信号说明PA0PWMA左轮占空比信号PA1AIN1左轮方向控制PA2AIN2左轮方向控制PA6PWMB右轮占空比信号PA7BIN1右轮方向控制PB0BIN2右轮方向控制注意 PWM 信号必须来自定时器的通道引脚普通 GPIO 只能输出高低电平不能输出可调占空比的方波。F103 的 TIM2、TIM3、TIM4 各有 4 个通道足够两路电机 PWM。原理图里只需要确认这些引脚被引出到排针如果某个脚被板载外设占用了改固件时要重新映射定时器通道。3. PCB 布局与制板原理图正确不等于板子能车3.1 布局顺序从核心到外圈电源和 MCU 中心化PCB 布局的思路和原理图阅读不一样你不能照着原理图信号流从左到右铺而要把板子当成一个物理系统来安排。核心板的布局顺序一般是MCU 居中偏上晶振紧贴 MCU 引脚去耦电容在 MCU 电源脚正对面排针分布在两侧电源 LDO 在输入接口附近指示灯远离晶振。布局时用位号图做一致性检查确保 PCB 上的 C5 就是原理图里的 C5D1 就是那个防反接二极管。这个动作是 Gerber 文件发给板厂前必做的。如果你用的是嘉立创 EDA它有“位号检查”功能能自动比对如果你在用 Altium就得手动交叉查重点查电阻电容的容值丝印和焊盘编号。电源通路要短而粗。从输入端子到 LDO 再到 MCU 的 VCC 引脚走线宽度至少 0.5mm 以上电机驱动电流不走核心板电机是外接的但核心板上的电源总线仍然要为舵机等大电流外设预留余量。电源线先到 MCU 再分支去其他外设的星型连接方式比链式连接更好能减少负载变化对 MCU 供电的干扰。3.2 晶振与去耦电容的位置优先级最高晶振布局是整个核心板 PCB 质量的分水岭。8MHz 晶振要放在 MCU 的 OSC_IN/OSC_OUT 引脚之间不要超过 5mm 走线距离两个负载电容分别从晶振两端引出在同一侧接地地孔直接打到主地层不要共用过孔穿过信号层。晶振区域下方不得走任何数字信号线尤其是 USART 和定时器的 PWM 线这些信号的谐波会干扰晶振起振。# 晶振布局的几何约束AD 里按 MM 单位设置 Y1 中心距 MCU 边缘 3~5mm C9、C10 分别距 Y1 两端小于 2mm Y1 下方禁止布线区域 0.5mm 半径 两个地过孔间距不超过 3mm如果晶振电容的实际封装是 0402 或 0603设计时要留意焊盘到晶振引脚焊盘的连线不能形成锐角建议用 45 度角走线。去耦电容方面每个电源引脚对应的 100nF 电容必须放在引脚背面的地平面旁过孔直接连接电容的地焊盘和主地层不要四处拉长线。3.3 排针接口与信号线的接线顺序技巧核心板两侧排针是它的对外骨架排针的顺序定义直接影响后面接线是否顺手。优秀的设计会把电源脚集中在一端——最上面 3 个脚是 VCC、GND、3V3下面才是 GPIO——这样外接电机驱动板时电源跳线不会横跨整块板子。信号线走线尽量在外层不要内外层反复换层。STM32F103 的 GPIO 自带施密特触发器和 ESD 保护但输入口走线过长且贴近 PWM 线时会产生串扰引起循迹信号误判。排针封装选择上直插排针的机械强度优于排母但排母方便插拔。核心板如果有固定孔四个角各一个 2.0mm 通孔用于锁铜柱这样装在小车底盘上不会因为振动导致接触不良。外接插线端子如果是 XH2.54 或者 PH2.0注意丝印标注正负极反转会直接烧毁超声波的电源管理芯片。对比参数和适用场景核心板布局里常见的取舍如下设计选择优点缺点适用场景双层板成本低、制板快地平面不完整、EMI 稍差学习板、课程设计四层板完整地层、信号质量好成本高约一倍竞赛小车、量产原型贴片排针不占空间、更小巧机械强度弱固定外设的小车直插排针耐用、拔插方便板子面积更大换模块频繁的开发阶段3.4 板厂打样的参数设置与常见加工坑PCB 画好后导出的 Gerber 文件发板厂时有三项参数必须确认板厚1.6mm 标准、铜厚1oz 常规大电流回路可加粗到 2oz、表面处理有铅喷锡最便宜无铅价格略高对核心板性能没有实质影响。还有一个容易忽略的是最小线宽/间距嘉立创、捷配等常规板厂默认为 6mil 线宽 6mil 间距如果你画的时候用了 5mil 线间距干到板厂那边会直接给你报制造问题或者更糟的是被自动改宽导致布局改变。值得专门说到的一个坑引脚间距 0.65mm 的 LQFP48 封装焊盘中心距才 0.5mm过孔只能放在封装外侧放内侧会造成焊盘短路。打印 1:1 图纸或三维预览确认一下排针和电容没有压到芯片顶部这个动作能省一次打板费。还有位号图的问题如果原理图里有两张图纸页且页码重复为 1导出网表时元件会错乱EDA 工具在 DRD 前必须消除页码重复。4. 固件骨架与下载验证把板子变成能跑的小车4.1 从核心板到最小电机控制的代码路径核心板焊好后第一个验证固件不需要复杂逻辑只需让两个 LED 闪烁、串口输出“OK”就走完了从芯片上电到外设工作的完整链路。用 STM32CubeMX 生成工程时晶振源要选 Crystal/Ceramic Resonator对应 8MHz 外部晶振如果选错为内部 RC系统时钟会从 64MHz 掉到 8MHzPWM 频率会同步偏差。# CubeMX 关键配置项 RCC: HSE Crystal/Ceramic Resonator SYS: Debug Serial Wire USART1: Asynchronous, 115200-8-N-1 GPIO: PC13 Output Push Pull, Label LED Clock: HSE - PLL x9 - SYSCLK 72MHz生成代码后打开 main.c在while(1)里加一句HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(500);然后在串口助手看有没有周期性的数据输出。注意 CubeMX 生成的函数HAL_Delay()依赖 SysTick 中断如果你在代码里关了中断优先级设置延时就会失效。4.2 TIM 定时器产生电机 PWM频率选择与占空比设置真正驱动电机时PWM 频率的选择很讲究不能想当然。直流减速电机的调速频率在 10kHz~20kHz 之间效果最好低于 5kHz 会听到明显的啸叫声高于 20kHz 电机的电感感抗增大电流反而上不去。我用 F103 驱动 TB6612PWMA 设定为 10kHz占空比从 0 到 999以 1000 为满占空比基准线性调。// TIM2 PWM 初始化核心参数 htim2.Instance TIM2; htim2.Init.Prescaler 72 - 1; // 72MHz / 72 1MHz 计数频率 htim2.Init.Period 100 - 1; // 1MHz / 100 10kHz PWM htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; // 通道 1 配置PA0 输出 sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 50; // 初始占空比 50% sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(htim2, sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim2, TIM_CHANNEL_1);参数解释Prescaler 为 71 是因为定时器时钟来自 APB1 的 72MHz在标准时基配置下分频后得到 1MHz 计数时钟Period 为 99所以 PWM 周期是 100 个计数即 10kHzPulse 设为 50 时占空比为 50/100 50%。改__HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, duty)可以动态调速duty 范围 0~99。方向控制就简单了AIN1 和 AIN2 两个 GPIO 一个给高一个给低电机正转反过来就是反转。程序里封装一个motor_left(int speed)函数speed 正数前进负数后退内部判断正负后修改 GPIO 和占空比。4.3 使用 ST-Link 连接调试器的连接顺序和故障定位连接调试器时按 ST-Link、杜邦线、核心板 SWD口 的顺序操作优先接入 GND再接 SWCLK、SWDIO最后接 VCC如果 ST-Link 有输出能力。上电后打开 Keil 或 STM32CubeIDE点下 Download 按钮前先点一下 Settings 看 SWD 设备是否被识别设备列表里出现 ARM CoreSight SW-DP 就是一个好信号。常见的五种故障按出现频率排序故障现象排查点解决手段No target connected接线是否反了交换 SWDIO 和 SWCLK下载成功但程序不跑BOOT0 被拉高确认 BOOT0 跳线在低电平运行时 LED 微弱供电不足 3.3V测量 LDO 输出电压上电后芯片发热电源反接或 3.3V 短路用万用表蜂鸣档测 VCC 对 GND串口输出乱码波特率不匹配确认 CubeMX 和串口助手都是 115200SWD 连接失败时要区分是板子的问题还是调试器的问题拿 ST-Link 的 3.3V 和 GND 去测量核心板的输入电源如果电压正常再查 SWDIO 和 SWCLK 是否有短路到地的迹象。如果 ST-Link 连过其他板子没问题那问题基本出在核心板这侧。4.4 核心板配合电机驱动的整车上电时序整车上电时如果不注意时序第一下就可能烧驱动芯片。正确流程先让驱动板电源上电电机电源单独接电池延迟 100ms再让 STM32 核心板上电。这是因为 TB6612 这类电机驱动在供电稳定前逻辑输入高阻态可能让 AIN1 和 AIN2 同时为高造成直通短路。如果你把核心板和驱动板共用同一个电源开关很多小车底盘确实这么做可在核心板代码里加一个上电保护初始化时先把 AIN1、AIN2 和 PWMA 全部拉低延时 50ms 后再置为有效状态。这样即便驱动先上电电机也不会立刻转动。// 上电电机保护代码片段 HAL_GPIO_WritePin(AIN1_GPIO_Port, AIN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(AIN2_GPIO_Port, AIN2_Pin, GPIO_PIN_RESET); __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, 0); HAL_Delay(50); // 之后再进入主循环设置实际占空比现象说明如果你上电瞬间小车猛冲一下说明这段保护代码没生效检查 GPIO 是否初始化在正确状态。还有一种情况是 PWM 启动函数HAL_TIM_PWM_Start()里占空比还没设置就被调用了通道在默认 Pulse 值下输出高电平——这也会造成猛冲务必先 SET_COMPARE 再 Start。5. 用串口示波器验证控制环路的三个进阶步骤5.1 把 PWM 波形拉到虚拟示波器引脚复用观察技巧当小车跑起来但不听话时你需要能看到 PWM 波形才能知道是驱动板的问题还是代码的问题。如果没有实体示波器用 ST-Link 虚拟示波器不够现实但可以用串口加一个 GPIO 翻转来近似看控制周期。做法是在定时器更新中断里翻转一个空闲 GPIO然后在 main 函数里把串口数据按时间戳打印就能在串口绘图软件比如匿名的地面站或者简单的 SerialPlot里看到控制量随时间的变化。这个方法不直接看 PWM而是看“控制周期是否卡住”。如果 GPIO 翻转时间间隔不均匀说明中断被阻塞了比如在中断里调用了HAL_Delay()或者长串口发送。核心板调试时我习惯留一个空闲 GPIO 作为心跳引脚既方便调试器逻辑分析仪测量也可以在死循环排查时快速定位哪段代码卡住。5.2 读取编码器数据定时器编码器模式的参数设置参考智能小车有了核心板之后理论上应加装霍尔编码器电机才能测速和闭环。F103 的定时器编码器模式把两个输入通道配置为 A/B 相正交信号计数器按编码器旋转方向增减。CubeMX 里把 TIM2 的两个通道设为 Encoder Mode不需要手动初始化 GPIO 复用硬件自动捕获。// 编码器模式初始化关键参数 htim2.Init.Prescaler 0; htim2.Init.Period 65535; htim2.Init.CounterMode TIM_COUNTERMODE_UP; // 编码器模式忽略此字段 sConfigIC.Polarity TIM_ICPOLARITY_RISING; sConfigIC.Filter 10; // 数字滤波消除机械抖动 HAL_TIM_Encoder_Start(htim2, TIM_CHANNEL_ALL); int16_t encoder_value (int16_t)__HAL_TIM_GET_COUNTER(htim2);编码器计数范围是 16 位有符号数正转增反转减(int16_t)转换不能丢。读取间隔建议固定为 10ms 或 20ms差值除以时间就是转速。如果你的电机编码器只有单相输出没有正交 A/BF103 的编码器模式用不了得接外部中断配合定时器计数精度会低一些。5.3 开环转闭环PID 参数由粗到细的调节顺序核心板调试里最有质变的一步是从“给一个占空比让它走”变成“读编码器让它稳在一固定速度上”。PID 参数的粗调遵循一个固定流程先只调 P让它能接近目标但有静差再加 I 消掉静差最后加 D 抑制超调。如果初始速度波动超过目标值的 30%说明 P 太小如果电机一直抖动则是 P 太大或 D 太敏感。// 位置式 PID 的简化实现只用于核心板逻辑验证 float pid_result Kp * error Ki * integral Kd * (error - last_error); // 限制输出范围 if (pid_result 990) pid_result 990; if (pid_result -990) pid_result -990;调节先从小车悬空状态开始轮子离地看速度响应是否能把编码器读数稳定在目标值附近。稳定后放到地上试跑如果地上跑的和悬空的表现差异很大优先检查电池电压是否在核心板稳压范围之外或者电机驱动板的电流限流是否触发。闭环控制的采样时间固定在 20ms避免用不固定的线程延时不然 PID 输出会和实际转速不同步。5.4 位号图与实物对照的最终验证清单最后回到开头那份“原理图和 PCB 图.rar”在所有调试完成后做一次完整对照。把 PCB 实物和位号图逐点对一遍重点检查排针丝印上的编号与原理图网络标号一致VCC 排针量一下和 LDO 输出的 3.3V 是否导通GND 对地是否零欧姆每个排针上的信号用万用表蜂鸣档从 MCU 的对应引脚位置反测回去。值得养成的习惯是在小车项目稳定运行后把这份对照表导出为文本格式存到和压缩包同一目录后续改板子或者换芯片型号时按表核对电源、时钟、BOOT、排针四块能省去从头翻原理图的时间。如果你搭配的是 STM32F405 类的新板子原理图结构几乎相同只是电源电压更低、去耦电容数量更多把 C8T6 的调试经验搬过去最多两天就能上手。本文还有配套的精品资源点击获取