ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

STM32F103开发板从开箱到第一个工程:环境搭建、烧录与点灯全流程

STM32F103开发板从开箱到第一个工程:环境搭建、烧录与点灯全流程 1. 拿到板子先别急着点灯搞清楚你手里这块F103到底能干什么STM32F103这块板子在嵌入式圈子里基本等同于“Hello World”级别的存在。你搜“stm32开发板”能出来一大堆从十几块的最小系统板到几百块的综合实验板都有但核心芯片大概率都是STM32F103C8T6或者ZET6。我手上这块是F103ZET6的板子144个引脚512KB Flash64KB SRAM放在十年前算是中高端配置现在拿来入门刚刚好——外设够多资料够全价格也够便宜。很多人买板子的时候热情高涨快递一到手反而懵了从哪开始先装Keil还是先装驱动USB线插上去电脑没反应怎么办程序编译通过了但烧不进去是什么鬼这些问题我全都踩过所以这篇文章不跟你扯什么“嵌入式系统概述”直接从拆快递那一刻讲起把F103开发板从开箱到跑通第一个工程的全流程拆开揉碎说清楚。你如果是完全零基础连C语言指针都忘得差不多了那也没关系。STM32标准库的代码结构其实比你想的要有规律得多照着模板改改就能跑。如果你之前玩过51单片机那更好很多概念是相通的只是STM32的时钟树和引脚复用会让你一开始有点不适应。不管你是哪种情况这块板子都值得你花时间啃下来——它是你从“玩单片机”到“做嵌入式产品”之间最稳的一座桥。2. 开箱之后先别插电这几样东西你得先确认2.1 板子上的核心器件识别拿到板子第一件事不是找USB线而是把板子翻过来看背面丝印。F103ZET6的封装是LQFP144芯片本体是正方形四边都有引脚第一脚的位置通常用一个小圆点或者缺角标记。这个第一脚很重要后面你接外设、查引脚定义都靠它定位。板子上一般会印“STM32F103ZET6”字样如果只印了“STM32F103”后面没跟具体型号那可能是C8T6或者RCT6Flash和引脚数都不一样你得根据实际型号去查数据手册。除了主控芯片板子上还有几个关键器件你得认识晶振通常8MHz用于主时钟32.768kHz用于RTC、稳压芯片AMS1117-3.3最常见把5V转成3.3V给MCU供电、复位电路一个按键加电容电阻、BOOT跳线帽决定芯片从Flash启动还是从系统存储器启动。这些不用你焊但出了问题你得知道去哪找原因。2.2 必备配件清单板子通常不配齐所有线材你得自己准备几样东西USB转串口模块CH340或者CP2102都行用来下载程序和看串口打印。有些板子板载了CH340那就省事了一根USB线搞定供电和通信。ST-Link V2调试器这是烧录和在线调试的核心工具比串口下载强太多支持断点、单步、查看寄存器。山寨版十几块钱能用但偶尔会抽风。杜邦线若干公对母、母对母各来一排后面接传感器、接逻辑分析仪都要用。面包板入门阶段别急着焊电路面包板插拔方便试错成本低。注意买ST-Link的时候认准“V2”版本别买成V3或者山寨到连固件都刷不进去的。V2虽然老但兼容性最好Keil和STM32CubeProgrammer都认。2.3 开发环境选型Keil、IAR还是VS Code这个问题争论很多我直接说结论入门阶段用Keil MDK。原因很简单STM32标准库和HAL库的官方例程都是Keil工程你打开就能编译不用折腾环境配置。IAR虽然编译效率高但界面和操作逻辑对新手不友好。VS Code加PlatformIO或者STM32CubeCLT确实很香但那是你跑通第一个工程之后再去折腾的事。Keil MDK的安装有两个坑一是芯片包Device Family Pack要单独装装完Keil本体之后要去官网下载STM32F1系列的DFP包双击安装二是License问题MDK-Lite版本有32KB代码限制F103的工程稍微加点功能就超了所以要么用社区版要么老老实实搞个正版License。我试过用Keil5同时装C51和STM32的包结果两个编译器打架后来干脆分开装在不同目录省心。3. 从零搭建第一个工程寄存器、标准库还是HAL库3.1 三种开发方式的取舍STM32的开发方式大致分三派寄存器操作、标准库、HAL库。我刚开始学的时候网上教程一半讲寄存器一半讲标准库搞得我很分裂。后来自己把三种都跑了一遍才明白各自的适用场景。寄存器操作最底层你得对着参考手册一个位一个位地配比如要开GPIOA的时钟得写RCC-APB2ENR | 12。这种方式能让你彻底理解芯片怎么工作但开发效率极低一个简单的串口初始化能写几十行。标准库是ST官方早年推出的把寄存器操作封装成函数比如GPIO_Init()可读性好资料也多但ST已经停止维护了。HAL库是现在ST主推的配合STM32CubeMX可以图形化配置引脚和时钟生成代码框架跨系列移植方便但代码体积大执行效率比标准库低一些。我的建议是先花一周时间用标准库跑通GPIO、串口、定时器理解基本流程然后转到HAL库加CubeMX。这样你既知道底层发生了什么又能享受现代工具链的便利。直接上HAL库不是不行但遇到问题容易抓瞎因为你不知道CubeMX帮你生成了什么。3.2 新建标准库工程的完整步骤假设你用的是Keil MDK新建一个F103标准库工程的流程如下创建工程目录在硬盘上建一个文件夹比如F103_Project里面再建User、Library、Output三个子文件夹。拷贝库文件从ST官网下载STM32F10x_StdPeriph_Lib_V3.5.0把Libraries目录下的CMSIS和STM32F10x_StdPeriph_Driver拷贝到你的Library文件夹。Keil新建工程选择芯片型号STM32F103ZET6弹出“Manage Run-Time Environment”时直接关掉我们手动添加文件。添加文件分组在Keil里建Startup、CMSIS、StdPeriph_Driver、User四个组分别把启动文件startup_stm32f10x_hd.s、system_stm32f10x.c、外设驱动.c文件、你的main.c加进去。配置头文件路径在Options for Target的C/C选项卡里把Library和User目录下的头文件路径都加进去。添加宏定义在Define框里填USE_STDPERIPH_DRIVER, STM32F10X_HD前者告诉编译器用标准库后者告诉它芯片是大容量型号。设置下载器在Debug选项卡选ST-LinkUtilities里勾选Use Debug Driver然后点Settings确认能识别到芯片。这一套流程走下来第一次可能要花半小时但之后你新建工程就是复制粘贴改改名字的事。我建议你把配置好的空工程存一份当模板以后直接复制省得每次都从头来。3.3 时钟配置别让芯片跑在错误的频率上F103的时钟树是新手最容易翻车的地方。默认情况下芯片上电后用的是内部8MHz RC振荡器HSI经过PLL倍频后系统时钟是72MHz。但如果你外接了8MHz晶振HSE就需要在system_stm32f10x.c里把SYSCLK_FREQ_72MHz的宏打开否则芯片还是跑HSI串口波特率会不准定时器时间也会偏。我遇到过一个问题串口打印出来全是乱码查了半天以为是波特率设错了后来发现是晶振没起振。用示波器一量HSE引脚上根本没有波形。原因是板子上的晶振负载电容不匹配换了两个22pF的电容就好了。所以如果你发现程序跑起来但时序不对先确认时钟源。4. 烧录不进去先查这五个地方4.1 常见烧录失败原因速查表现象可能原因排查方法Keil提示“No Cortex-M Device found”ST-Link驱动没装好或线接错设备管理器看有没有ST-Link检查SWDIO/SWCLK接线能识别芯片但下载报错“Flash Download failed”Flash算法没选对Options→Utilities→Settings里选STM32F10x High-density Flash下载成功但程序不跑BOOT跳线帽位置不对BOOT0接GNDBOOT1接GND确保从Flash启动程序跑一次就死看门狗没喂或中断向量表偏移检查是否开了IWDG检查VECT_TAB_OFFSET串口无输出波特率、引脚、时钟源不匹配确认USART引脚复用配置确认系统时钟频率4.2 ST-Link连接不上的排查思路ST-Link连不上芯片最常见的原因是SWD引脚被复用了。F103的PA13和PA14默认就是SWDIO和SWCLK但如果你在代码里把这两个引脚配成了普通GPIO或者复用成了其他功能下次烧录就连不上了。解决办法是按住复位键点下载等Keil开始连接的时候松开复位这样芯片在复位后还没来得及执行你的代码SWD引脚还是默认功能。还有一种情况是芯片被读保护了。如果你之前烧过程序并且开了读保护ST-Link会拒绝连接。这时候需要用STM32CubeProgrammer或者ST-Link Utility来解除保护但注意解除保护会擦除整个Flash。实操心得我习惯在每次烧录前把BOOT0接GNDBOOT1也接GND这样芯片永远从Flash启动不会跑飞。如果你板子上有跳线帽直接短接就行。4.3 用串口下载的备用方案如果ST-Link实在搞不定可以用USB转串口模块通过系统存储器启动来下载。把BOOT0接3.3VBOOT1接GND复位后芯片进入Bootloader模式然后用FlyMcu或者STM32CubeProgrammer的串口模式下载。下载完再把BOOT0接回GND复位运行。这种方式速度慢但胜在简单不需要额外调试器。5. 第一个工程用GPIO点亮LED并串口打印5.1 硬件连接确认大多数F103开发板板载了至少两个LED通常接在PB5和PE5上低电平点亮。你先用万用表蜂鸣档测一下LED正极是不是通过限流电阻接到了GPIO负极接地。如果是高电平点亮那代码里就要反过来写。我见过有的板子LED接在PA8上还带了个跳线帽不插跳线就不亮这种设计就很坑。5.2 标准库代码实现#include stm32f10x.h #include delay.h int main(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); GPIO_Init(GPIOE, GPIO_InitStructure); while(1) { GPIO_ResetBits(GPIOB, GPIO_Pin_5); GPIO_SetBits(GPIOE, GPIO_Pin_5); Delay_ms(500); GPIO_SetBits(GPIOB, GPIO_Pin_5); GPIO_ResetBits(GPIOE, GPIO_Pin_5); Delay_ms(500); } }这段代码的逻辑很简单开GPIOB和GPIOE的时钟配置PB5和PE5为推挽输出然后在主循环里交替翻转两个引脚。Delay_ms函数需要你自己实现可以用SysTick定时器来做也可以用简单的循环延时。标准库没有提供现成的延时函数这是新手容易卡住的地方。5.3 串口打印调试信息点灯只是确认芯片在跑真正调试还得靠串口。F103的USART1接在PA9TX和PA10RX上配置步骤如下void USART1_Init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, GPIO_InitStructure); USART_InitStructure.USART_BaudRate bound; USART_InitStructure.USART_WordLength USART_WordLength_8b; USART_InitStructure.USART_StopBits USART_StopBits_1; USART_InitStructure.USART_Parity USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, USART_InitStructure); USART_Cmd(USART1, ENABLE); }配置好之后用printf重定向到串口就能在电脑的串口助手里看到打印信息了。重定向的代码网上很多核心就是重写fputc函数把字符一个个发给USART1。注意串口助手的波特率、数据位、停止位、校验位必须和代码里完全一致否则就是一堆乱码。我习惯用115200-8-N-1这个组合最通用。6. 进阶方向从点灯到做项目还差哪些技能6.1 定时器与中断点灯和串口只是热身真正让STM32发挥威力的是定时器和中断。F103有多个通用定时器TIM2~TIM5和高级定时器TIM1、TIM8可以用来做PWM输出、输入捕获、编码器接口。比如你想做个超声波测距就需要用定时器捕获回波的高电平时间想控制舵机就需要用PWM输出不同占空比。中断配置的流程是开时钟、配NVIC优先级、配外设中断使能、写中断服务函数。新手容易犯的错是忘了清中断标志位导致程序一直进中断出不来。还有优先级分组没设对导致高优先级中断被低优先级阻塞。6.2 常用外设与传感器F103的片上外设很丰富ADC、DAC、SPI、I2C、CAN、USB。入门阶段建议按这个顺序学GPIO→串口→定时器→ADC→I2C→SPI。每学一个外设就配一个对应的传感器做实验。比如学I2C的时候接个DS3231时钟模块学SPI的时候接个OLED屏幕学ADC的时候接个光敏电阻。我个人的经验是不要贪多。有人一上来就想做“基于STM32的智能家居系统”结果连I2C时序都没搞明白最后项目烂尾。先把一个外设吃透再叠加下一个这样每步都有正反馈。6.3 从标准库过渡到HAL库标准库跑通几个工程之后你会发现新建工程很麻烦而且ST的固件库已经不更新了。这时候可以开始用STM32CubeMX图形化配置引脚、时钟、外设一键生成HAL库工程。CubeMX最大的好处是可视化你点一下引脚就知道它支持哪些复用功能时钟树也是图形化的不用自己算分频系数。但HAL库的抽象层次更高有时候你调一个函数半天没反应得进去看它到底操作了哪些寄存器。所以我的建议是用标准库理解原理用HAL库提高效率。两者不是对立的而是不同阶段的工具。7. 常见问题与排查技巧实录7.1 程序编译通过但烧录后没反应这个问题我遇到过不下十次原因五花八门。最常见的是启动文件选错了。F103ZET6是大容量型号启动文件要用startup_stm32f10x_hd.s如果你用了md.s或者ld.s中断向量表就对不上程序一跑就飞。其次是宏定义没加STM32F10X_HD和USE_STDPERIPH_DRIVER缺一不可。还有就是晶振没起振导致系统时钟不对延时函数全乱套。排查的时候先用ST-Link Utility连上芯片看看Flash里有没有你的程序。如果有说明下载成功了问题在运行阶段如果没有说明下载就没成功回去查下载配置。7.2 串口打印乱码串口乱码九成是波特率不匹配。但波特率不匹配的原因可能有好几种一是系统时钟频率不对比如你以为是72MHz实际跑的是8MHz二是USART的分频系数算错了标准库的USART_Init会自动算但如果你手动改了BRR寄存器就可能出错三是串口助手的设置和代码不一致。我一般用示波器量一下TX引脚上的波形算一下最小脉宽反推波特率。比如115200波特率下一个位的时间是8.68微秒示波器上应该能看到这个宽度的脉冲。如果脉宽差很多那就是时钟源的问题。7.3 中断进不去或反复进中断进不去先查NVIC使能和外设中断使能是不是都开了。F103的中断要过两道关外设自己的中断使能位和NVIC的中断使能位。少开一个都进不去。反复进中断通常是中断标志没清或者中断触发条件一直满足。比如按键中断没做消抖按键抖动就会触发多次中断。实操心得调试中断的时候在中断服务函数里翻转一个GPIO用示波器看波形比用串口打印靠谱得多。串口打印本身就会引入延迟有时候会掩盖问题。7.4 ST-Link能识别但下载报错这种情况多半是Flash算法选错了。F103ZET6是512KB Flash属于大容量产品在Keil的Utilities→Settings→Flash Download里要选STM32F10x High-density Flash。如果你选了Medium-density地址范围对不上下载就会报错。另外读保护也会导致下载失败需要用STM32CubeProgrammer解除保护但数据会全丢。8. 学习路线与资源推荐8.1 分阶段学习计划我给自己带新人的建议是四周入门计划第一周装环境、跑通点灯和串口理解GPIO和时钟配置。第二周学定时器和中断做PWM呼吸灯和按键中断计数。第三周学ADC和I2C接光敏电阻和OLED屏幕做个小仪表。第四周综合项目比如超声波测距或者温湿度采集把数据通过串口发到电脑。这个节奏不算快但每一步都踩实了。很多人急于求成第一周就想做USB通信结果连基本的GPIO都没搞明白后面越学越乱。8.2 资料获取与社区ST官网的参考手册Reference Manual和数据手册Datasheet是必看的虽然厚但遇到问题查一下比问人快。标准库的例程在STM32F10x_StdPeriph_Lib的Project目录下每个外设都有对应的例子直接拿来改就行。社区方面国内的电子论坛和开源社区有很多F103的项目分享搜“STM32F103 项目”能出来一堆毕业设计和DIY作品参考价值很高。注意看例程的时候不要只复制代码要对着参考手册看每个寄存器的含义。比如GPIO_Init函数里配置了CRL和CRH寄存器你打开手册看看这两个寄存器的位定义就明白为什么引脚配置要那样写了。8.3 从F103到更高级的芯片F103学完之后如果你要做更复杂的项目比如带网络、带屏幕、带操作系统的可以考虑升级到F4系列或者H7系列。F4的主频更高168MHz浮点运算能力强适合做信号处理H7是双核性能更强但开发难度也更大。不过F103打下的基础是通用的GPIO、中断、定时器、串口这些概念在所有STM32系列里都一样换芯片主要是重新熟悉时钟树和外设差异。我个人的体会是F103是一块“教学芯片”它的外设足够全资料足够多价格足够低非常适合用来建立嵌入式开发的完整认知。你在这块板子上踩过的每一个坑以后换任何芯片都会遇到类似的。所以别嫌它老把它玩透了后面的事就顺了。最后分享一个小技巧每次调通一个外设就把工程打包存一份命名带上日期和功能比如F103_UART_20250101。以后新建工程直接复制最近的模板改改就能用省得每次都从头配置。这个习惯我坚持了好几年帮我省了至少几百个小时的重复劳动。
返回列表