☰
STM32F103开发板入门实战:从环境搭建到外设进阶全指南
2026/10/31 6:27:21 网站建设 项目流程

1. 拿到板子先别急着点灯:STM32F103开发板入门全景拆解

STM32F103开发板到手的那一刻,很多人第一反应是插上USB线看灯亮不亮。这个动作没错,但如果你打算长期玩下去,最好先花二十分钟把整块板子的脉络理清楚。STM32F103是意法半导体基于ARM Cortex-M3内核的32位微控制器,主频常见72MHz,片上Flash从16KB到1MB不等,SRAM从6KB到96KB,封装形式有LQFP48、LQFP64、LQFP100等。市面上常见的“最小系统板”通常引出所有GPIO,搭配8MHz晶振和32.768kHz RTC晶振,板载一个用户LED、一个复位按键、一个BOOT选择跳线,有的还带USB转串口芯片和MicroSD卡座。

这块板子能做什么?简单说,凡是需要“感知—判断—控制”的电子项目,它几乎都能扛。从串口打印调试信息、定时器捕获测频率、PWM驱动电机,到CAN总线通信、USB设备模拟、SD卡文件读写,再到跑FreeRTOS做多任务调度,STM32F103都是极佳的练手平台。它适合谁?电子类专业学生做毕业设计、嵌入式初学者建立寄存器与库函数思维、硬件工程师验证外设电路、创客做小批量产品原型,都能从这块板子上获得实实在在的收益。

我见过太多人买了板子之后卡在“环境装不上”“下载不进去”“灯不亮”这三步,然后板子就吃灰了。这篇文章就是要把这些坑一个个填平,从工具链选型到第一个工程跑通,从GPIO操作到串口、定时器、CAN、USB的实战要点,再到常见故障排查,全部用从业者的视角讲清楚。你不需要先学完C语言再来看,也不需要买昂贵的仿真器,跟着走就能把板子跑起来。

2. 开发环境搭建:工具链选型与工程创建

2.1 Keil、IAR还是VSCode加开源工具链

工具链的选择直接决定你后续的开发体验。Keil MDK是国内STM32教学最常用的环境,优势是安装简单、器件包齐全、调试器兼容性好,缺点是要么用社区版(有代码大小限制),要么购买授权。IAR编译效率高、优化强,但授权费用更高,初学者一般不考虑。VSCode加ARM GCC加OpenOCD加Cortex-Debug插件这套组合完全免费,代码提示和版本管理体验好,但配置launch.json和tasks.json对新手有一定门槛。

我的建议是:如果你跟着学校课程或培训班走,直接用Keil MDK 5,安装STM32F1xx_DFP器件支持包即可。如果你习惯现代编辑器、想用Git管理代码,那就上VSCode方案。两条路都能走通,关键是别在工具链上反复横跳,选一个先跑通再说。

注意:Keil 5和Keil C51可以共存,但安装顺序有讲究。先装C51再装MDK,或者分别装在不同目录,否则注册表冲突会导致其中一个无法正常编译。

2.2 芯片包安装与新建标准库工程

Keil MDK安装完成后,打开Pack Installer,搜索STM32F1,找到Keil::STM32F1xx_DFP并安装。这个包里面包含启动文件、外设寄存器定义头文件、标准外设库的示例工程。安装完成后,新建工程时选择STM32F103C8或你板子上实际使用的型号。

新建标准库工程的步骤:第一,在Keil中Project→New uVision Project,选择芯片型号;第二,在弹出的Run-Time Environment里勾选CMSIS的CORE和Device的Startup,不勾选Device的StdPeriph Drivers(因为我们要手动添加标准库);第三,把ST官方标准外设库的inc和src目录拷贝到工程目录下,在Keil中添加Group并加入需要的.c文件;第四,在Options for Target的C/C++选项卡里添加头文件路径和宏定义USE_STDPERIPH_DRIVER, STM32F10X_MD。

这里有个细节:STM32F103C8T6属于中容量产品,宏定义用STM32F10X_MD;如果是RC、VC、ZE等大容量型号,用STM32F10X_HD;小容量用STM32F10X_LD。选错了会导致启动文件里的中断向量表长度不匹配,程序跑飞。

2.3 下载器选择与接线要点

下载器常见的有ST-Link V2、J-Link OB、DAPLink。ST-Link原厂或兼容版价格便宜,配合Keil和STM32CubeProgrammer都好用。J-Link速度快、支持芯片多,但正版价格高,兼容版固件容易掉。DAPLink开源方案多,适合喜欢折腾的人。

接线方面,SWD模式只需要四根线:3.3V、GND、SWDIO、SWCLK。有些板子还引出SWO用于printf重定向,但初学者可以先不接。注意:下载器的3.3V不要和板子外部电源同时供电,否则可能倒灌。如果板子已经通过USB供电,下载器只接GND、SWDIO、SWCLK三根线即可。

提示:STM32芯片第一脚怎么确认?看芯片表面的小圆点或缺口,逆时针数第一脚。LQFP封装在左上角有一个圆点标记,QFN封装在底部有散热焊盘和定位标记。接反VCC和GND会瞬间烧芯片,上电前务必用万用表蜂鸣档确认。

3. 第一个工程:从GPIO点灯到串口打印

3.1 时钟树配置与延时函数

STM32F103的时钟源有三种:HSI内部8MHz RC、HSE外部8MHz晶振、PLL倍频输出。标准库工程里SystemInit函数默认把HSE 8MHz经过PLL 9倍频到72MHz作为SYSCLK,AHB不分频,APB1二分频得36MHz,APB2不分频得72MHz。这个配置在system_stm32f10x.c里定义,初学者不需要改,但要知道为什么APB1最高只能36MHz——因为外设设计如此,超频会导致定时器、串口等工作异常。

延时函数有两种写法:一种是软件循环的delay_ms,靠空指令消耗时间,不精确但够用;另一种是用SysTick定时器做精确延时。标准库的delay.c通常用SysTick实现,配置为1ms中断一次,在中断里递减计数。注意:如果在中断服务函数里调用delay_ms,而SysTick优先级低于当前中断,会导致死等。所以delay函数不要在中断里用,或者改用DWT周期计数器做微秒级延时。

3.2 GPIO输出:点亮第一颗LED

点灯的本质是配置GPIO为推挽输出模式,然后拉低或拉高对应引脚。以STM32F103C8T6的PC13为例,板载LED通常阳极接3.3V,阴极接PC13,所以输出低电平点亮。代码步骤:第一,使能GPIOC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);第二,定义GPIO_InitTypeDef结构体,设置GPIO_Pin为GPIO_Pin_13,GPIO_Mode为GPIO_Mode_Out_PP,GPIO_Speed为GPIO_Speed_50MHz;第三,调用GPIO_Init(GPIOC, &GPIO_InitStructure);第四,在while(1)里GPIO_ResetBits(GPIOC, GPIO_Pin_13)点亮,GPIO_SetBits熄灭,中间加delay_ms。

实测下来,PC13驱动能力较弱,建议只用来点LED,不要驱动大电流负载。如果需要驱动继电器或电机,用三极管或MOS管扩流,或者换用PA、PB口。

3.3 串口打印:printf重定向与调试技巧

串口是嵌入式开发最重要的调试手段。STM32F103有3个USART,USART1挂在APB2上,最高4.5Mbps;USART2和USART3挂在APB1上,最高2.25Mbps。配置步骤:使能USART和GPIO时钟,配置TX为复用推挽输出,RX为浮空输入或上拉输入,设置波特率、数据位、停止位、校验位,使能USART和接收中断。

printf重定向的方法是重写fputc函数,在里面调用USART_SendData并等待发送完成。注意:Keil默认使用MicroLIB时,fputc的重定向方式略有不同,需要在Options for Target的Target选项卡里勾选Use MicroLIB。如果不勾选,需要自己实现_sys_write等底层函数。

实操心得:串口助手收不到数据,先检查TX和RX是否交叉连接,再确认波特率是否一致,最后用示波器或逻辑分析仪看TX引脚有没有波形。如果波形正常但数据乱码,多半是晶振频率和代码里配置的不一致,比如板子是8MHz晶振但代码按12MHz算。

4. 外设进阶:定时器、CAN、USB与常见模块

4.1 定时器捕获测频率与PWM输出

STM32F103有多个定时器,TIM1和TIM8是高级定时器,TIM2到TIM5是通用定时器,TIM6和TIM7是基本定时器。测频率用输入捕获模式:配置定时器为向上计数,通道为输入捕获,设置预分频器和自动重装载值,在捕获中断里读取CCR寄存器的值,两次捕获的时间差就是周期。注意:输入信号频率不能超过定时器时钟除以预分频器后的频率,否则会漏捕获。

PWM输出用输出比较模式:配置定时器为PWM模式1或2,设置ARR决定周期,CCR决定占空比。驱动舵机时,周期20ms,高电平0.5ms到2.5ms对应角度0到180度。驱动直流电机时,PWM频率建议在10kHz到20kHz之间,太低会有啸叫,太高会导致MOS管开关损耗增大。

4.2 CAN通信突然连不上的排查思路

CAN总线在汽车电子和工业控制中很常见。STM32F103自带CAN控制器,需要外接CAN收发器如TJA1050或SN65HVD230。通信突然断掉,常见原因有:终端电阻缺失或阻值不对,CAN总线两端各需要120欧姆终端电阻;波特率配置不一致,采样点位置不同也会导致通信失败;总线短路或断路,用万用表测CANH和CANL之间的电阻,正常约60欧姆;收发器供电异常,TJA1050需要5V供电,SN65HVD230需要3.3V。

排查步骤:先用示波器看CANH和CANL的差分波形,正常应该有明显的差分信号;再检查STM32的CAN模式配置,是否处于正常模式而非环回或静默模式;最后用CAN分析仪抓包,看是否有错误帧。

4.3 USB设备开发:从虚拟串口到自定义HID

STM32F103的USB外设是全速设备,支持控制传输、中断传输、批量传输、同步传输。做USB设备开发,推荐用ST官方的USB FS Device库,里面包含虚拟串口、HID、MSC等例程。虚拟串口最简单,改一下描述符和端点配置就能用,电脑端免驱。自定义HID需要自己写报告描述符,注意报告长度和端点缓冲区大小匹配。

注意:STM32F103的USB和CAN共用SRAM,如果同时使用,需要调整内存分配。USB时钟必须精确为48MHz,通常用HSE 8MHz经过PLL倍频得到,不能直接用HSI,否则枚举会失败。

4.4 常见模块实战:超声波、ILI9341、DS3231

超声波测距模块HC-SR04用定时器输入捕获测回波高电平时间,距离等于时间乘以声速除以2。注意温度对声速有影响,高精度场景需要温度补偿。ILI9341读ID是A1A1,说明SPI通信正常,如果读出来是0000或FFFF,检查片选、复位、背光引脚和SPI模式。DS3231是I2C接口的高精度RTC,内置温补晶振,走时比STM32内部RTC准得多,注意I2C上拉电阻一般4.7k到10k。

5. 常见问题速查与避坑经验

5.1 下载失败与程序跑飞的典型原因

下载失败最常见的原因是BOOT引脚状态不对。STM32F103的BOOT0和BOOT1决定启动模式:BOOT0=0从主Flash启动,BOOT0=1且BOOT1=0从系统存储器启动(用于串口下载),BOOT0=1且BOOT1=1从SRAM启动。用SWD下载时,BOOT0必须为0。如果芯片被读保护,需要先用STM32CubeProgrammer解除保护,但会擦除全部Flash。

程序跑飞的另一个原因是中断向量表偏移没设置。如果程序从0x08000000开始跑,不需要改;如果做了IAP升级,APP程序从0x08004000开始,需要在SystemInit之后调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000)。

5.2 串口乱码、延时卡死、JTAG禁用问题

串口乱码先查波特率,再查晶振。如果板子用的是8MHz晶振但代码里HSE_VALUE定义为8000000,一般没问题;如果板子实际是12MHz但代码按8MHz算,波特率就会偏。延时卡死多半是在中断里调用了delay_ms,或者SysTick优先级配置不当。禁用JTAG释放PB3和PB4作为普通GPIO时,调用GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)即可,但注意这样会禁用JTAG,SWD仍然可用。

5.3 常见问题速查表

现象可能原因排查方法
下载器识别不到芯片SWDIO/SWCLK接反、BOOT0为高、芯片读保护检查接线、拉低BOOT0、解除读保护
LED不亮GPIO时钟未使能、引脚配置错误、LED极性判断错用万用表测引脚电平、查原理图
串口无输出TX/RX未交叉、波特率不对、fputc未重定向交换TX/RX、示波器看波形、检查MicroLIB
CAN通信失败终端电阻缺失、波特率不一致、收发器供电异常测总线电阻、示波器看差分信号、查供电
USB枚举失败时钟不是48MHz、描述符错误、端点配置冲突查PLL配置、用USB分析仪抓包
定时器捕获不准预分频器设置不当、输入信号频率过高降低输入频率、调整预分频
程序跑飞中断向量表偏移未设、堆栈溢出、数组越界查启动文件、增大堆栈、加断言

5.4 独家避坑技巧

第一,买板子时优先选带ST-Link的套餐,省去单独买下载器的麻烦,而且兼容性好。第二,焊接排针时先焊四角定位,再焊中间,避免歪斜。第三,调试时养成先看电源再看信号的习惯,3.3V和GND短路是最容易烧板子的。第四,代码里多用assert_param和错误处理,早期发现配置错误。第五,用Git管理工程,每次改完能回退,比复制文件夹靠谱得多。

6. 从入门到项目:学习路径与资源推荐

6.1 分阶段学习路线

第一阶段,跑通GPIO、串口、定时器,能点灯、能打印、能延时。第二阶段,玩转中断、PWM、ADC、I2C、SPI,能读传感器、能驱动屏幕、能调电机。第三阶段,上RTOS、文件系统、USB、CAN,能做多任务数据采集和通信网关。第四阶段,做完整项目,比如鱼缸控制器、报站程序、PID温控、毕业设计。每个阶段都要动手写代码,光看视频不动手等于没学。

6.2 常用库与框架选择

标准库适合学习寄存器操作,代码直观但移植性差。HAL库适合快速开发,ST官方主推,配合STM32CubeMX能自动生成初始化代码。LL库介于两者之间,效率高但抽象少。RTOS方面,FreeRTOS资料最多,RT-Thread国产生态好,两者都值得学。Modbus协议栈可以用agile_modbus,轻量且易移植。

6.3 调试工具与效率提升

逻辑分析仪是必备的,几十块钱的8通道24MHz版本就能看串口、I2C、SPI波形。示波器有条件就上,看电源纹波和信号完整性。USB分析仪贵,初学者可以用Wireshark加USBPcap抓包。VSCode加Cortex-Debug可以图形化调试,打断点、看变量、单步执行都很方便。

我个人在实际操作中的体会是,STM32F103虽然老,但资料最全、坑最少、成本最低,非常适合建立嵌入式开发的完整认知。把这块板子玩透了,再上手F4、F7、H7或者国产替代芯片,迁移成本很低。最后分享一个小技巧:遇到问题先搜ST官方社区和GitHub Issues,大部分坑别人已经踩过了,关键词用英文搜命中率更高。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询