ARTICLE DETAIL

资讯详情

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

STM32F103开发板入门实战:从工具链选型到外设驱动全流程拆解

STM32F103开发板入门实战:从工具链选型到外设驱动全流程拆解 1. 拿到板子先别急着点灯STM32F103开发板入门全景拆解STM32F103这块板子大概是国内嵌入式圈子里保有量最大的一块入门开发板了。不管你是电子专业的学生、刚转行做嵌入式的软件工程师还是想给自家小项目加个控制核心的硬件爱好者手里捏着一块F103开发板基本就等于拿到了进入ARM Cortex-M3世界的门票。我前后带过不少人入门也见过太多人板子买回来吃灰——不是学不会而是第一步就走歪了。这篇文章就把STM32F103开发板从开箱到跑通第一个工程的全流程拆开讲顺带把新手最容易踩的坑、工具链怎么选、标准库和HAL库怎么取舍这些事一次说清楚。适合零基础但有一点C语言底子的人也适合之前玩过51单片机、想升级到32位平台的朋友。STM32F103的核心是ARM Cortex-M3内核主频常见72MHz片上Flash从16KB到512KB不等SRAM从6KB到64KB。市面上常见的开发板型号有STM32F103C8T6蓝板/最小系统板、STM32F103ZET6大板引脚多、外设全、STM32F103RCT6等。C8T6便宜、够用适合入门ZET6资源丰富适合做毕业设计或者需要接很多外设的项目。你买的是哪种直接决定了后面能玩多深。提示买板子的时候一定要确认芯片型号和封装C8T6是LQFP48封装ZET6是LQFP144封装两者的引脚数量和可用外设差别很大别买回来发现引脚不够用。2. 工具链怎么选Keil、VS Code还是其他2.1 Keil MDK最省心的选择但别装错版本新手入门我一般直接推荐Keil MDK。原因很简单生态成熟、教程多、调试方便遇到问题搜一下基本都有答案。但Keil有个坑就是版本和芯片包的问题。Keil5和Keil4的工程结构不一样现在主流是Keil5MDK-ARM V5。装完Keil5之后还需要单独安装STM32F1系列的Device Family PackDFP也就是常说的“芯片包”。没有这个包新建工程的时候找不到STM32F103的型号。芯片包的安装方式有两种一种是在Keil里通过Pack Installer在线安装另一种是去官网下载.pack文件双击安装。在线安装有时候会因为网络问题失败建议直接下载离线包。安装完成后在Keil的Project - Manage - Pack Installer里能看到STM32F1系列就说明成功了。还有一个常见问题有人电脑上同时装了Keil C51和Keil MDK想让它俩共存。这个是可以的但要注意安装路径不要覆盖而且注册的时候要分别注册。不过我个人建议如果只是学STM32就别折腾C51了分开装或者干脆用两台环境省得互相干扰。2.2 VS Code 插件适合喜欢折腾的人这两年用VS Code开发STM32的人越来越多。核心思路是用VS Code做编辑器底层调用arm-none-eabi-gcc编译用OpenOCD或者ST-Link Utility烧录。这套方案的好处是免费、跨平台、编辑器体验好坏处是配置麻烦新手容易在环境搭建上卡住。典型的配置流程是安装VS Code装Cortex-Debug插件、STM32 VS Code Extension插件然后配置tasks.json和launch.json。编译工具链用arm-none-eabi-gcc调试用OpenOCD ST-Link。这套配置我配过好几次每次都要花一两个小时调主要是路径和参数容易写错。注意如果你在VS Code里编译成功但烧录不进去大概率是烧录配置里的接口类型或者目标芯片型号写错了。ST-Link的接口有SWD和JTAG两种F103一般用SWD四根线VCC、GND、SWDIO、SWCLK。2.3 标准库 vs HAL库入门阶段怎么选这是新手最纠结的问题之一。STM32的标准库Standard Peripheral Library是ST早期推出的代码直接操作寄存器结构清晰适合理解底层原理。HAL库Hardware Abstraction Layer是后来推的抽象层次更高跨系列移植方便但代码量大、执行效率略低。我的建议是入门阶段用标准库。原因很实际——标准库的代码更接近寄存器操作你写一遍GPIO初始化能大概知道CRL、CRH、ODR这些寄存器是干什么的。HAL库把这些都封装了你调个HAL_GPIO_Init就完事学完一圈下来可能连GPIO的模式寄存器长什么样都不知道。等你把标准库玩熟了再转HAL库或者LL库那时候你已经有底层概念了学起来很快。当然如果你是为了快速做项目、不关心底层直接上HAL库也行STM32CubeMX图形化配置工具能帮你省很多事。但CubeMX生成的代码有时候比较臃肿新手看不太懂。3. 从零新建一个标准库工程手把手操作3.1 工程目录结构怎么搭标准库工程不是新建一个Keil工程就完事了你需要把ST官方提供的库文件组织好。一个典型的工程目录结构是这样的Project/ ├── CMSIS/ # 内核相关文件 │ ├── core_cm3.h │ ├── core_cm3.c │ └── stm32f10x.h ├── FWLIB/ # 外设库文件 │ ├── inc/ # 头文件 │ └── src/ # 源文件 ├── USER/ # 用户代码 │ ├── main.c │ ├── stm32f10x_it.c │ └── stm32f10x_conf.h ├── HARDWARE/ # 硬件驱动 │ ├── led.c │ └── led.h └── OBJ/ # 编译输出这个结构不是固定的但核心思想是内核文件、外设库文件、用户代码、硬件驱动分开存放。这样工程清晰后面加外设的时候不会乱。CMSIS目录下需要放core_cm3.h、core_cm3.c和stm32f10x.h。FWLIB目录下放ST提供的标准外设库比如stm32f10x_gpio.c、stm32f10x_rcc.c、stm32f10x_usart.c等。USER目录下放main.c和中断服务文件。HARDWARE目录下放你自己写的驱动。3.2 Keil工程的关键配置项新建Keil工程后有几个配置必须做对否则编译或者烧录会出问题。第一个是Target选项里的晶振频率。STM32F103外部晶振一般是8MHz经过PLL倍频到72MHz。在Keil的Options for Target - Target里Xtal填8.0MHz。这个值影响的是Keil的软件仿真实际硬件运行靠的是代码里的时钟配置。第二个是Output选项里勾选Create HEX File。如果你用ST-Link Utility或者串口烧录需要HEX文件。用Keil直接下载的话不勾也行。第三个是C/C选项里的Define。标准库工程一般需要定义USE_STDPERIPH_DRIVER和STM32F10X_MD根据芯片容量选择C8T6是中容量用STM32F10X_MDZET6是大容量用STM32F10X_HD。这个宏定义决定了stm32f10x.h里包含哪些外设的头文件。第四个是Debug选项。选ST-Link Debugger然后点Settings确认能识别到芯片。如果识别不到检查接线和驱动。实操心得Keil工程里添加文件组的时候建议按目录分组比如CMSIS组、FWLIB组、USER组、HARDWARE组。这样在左侧工程树里一目了然找文件方便。我见过有人把所有.c文件堆在一个组里几十个文件排下来找个main.c都要翻半天。3.3 时钟配置72MHz是怎么来的STM32F103默认用的是内部8MHz的HSI振荡器但大多数开发板外部焊了8MHz晶振。要让芯片跑在72MHz需要配置PLL。具体流程是使能HSE外部高速时钟等待HSE稳定配置PLL倍频系数为98MHz × 9 72MHz使能PLL切换系统时钟源到PLL。这段代码在标准库里的写法是void RCC_Configuration(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) RESET); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() ! 0x08); }这段代码看起来简单但有几个细节容易出错。一是HSE起振需要时间如果晶振质量不好或者负载电容不匹配可能会卡在while循环里。二是PLL倍频系数不能乱设F103的PLL输出范围是16MHz到72MHz超过72MHz可能不稳定。三是切换系统时钟源之后要确认切换成功否则后面外设的时钟频率全错。如果你发现程序卡在while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) RESET)这一行先检查晶振有没有焊好再检查负载电容是不是匹配。实在不行可以先用HSI跑虽然精度差一点但至少能跑起来。4. GPIO操作从点亮一个LED开始4.1 GPIO的八种模式别只会推挽输出STM32的GPIO有八种模式输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、推挽复用输出、开漏复用输出。新手最常用的是推挽输出用来点LED、驱动数码管。但其他模式什么时候用得心里有数。输入浮空外部信号直接进没有上下拉。适合外部已经有上下拉电阻的场景。输入上拉/下拉芯片内部提供上下拉省外部电阻。按键输入一般用上拉或下拉。模拟输入ADC采集的时候用这时候GPIO不再作为数字口。开漏输出输出高电平时是高阻态需要外部上拉电阻。I2C的SDA和SCL就用开漏复用输出。推挽输出能输出强高低电平驱动LED、继电器等。配置GPIO的步骤是使能GPIO时钟、定义GPIO_InitTypeDef结构体、设置引脚、设置模式、设置速度、调用GPIO_Init。以PA5接LED为例void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, 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(GPIOA, GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_5); // 默认熄灭 }这里有个细节GPIO_Speed设置的是输出驱动电路的响应速度不是输出电平的高低。50MHz适合高速信号2MHz适合低功耗场景。点LED用2MHz就够了但设50MHz也没问题。4.2 按键输入消抖不是可选项按键输入比LED输出麻烦一点因为机械按键有抖动。抖动时间一般在5ms到20ms之间如果不处理按一次键可能会被识别成多次。消抖有两种方式硬件消抖和软件消抖。硬件消抖是在按键两端并联电容软件消抖是检测到按键按下后延时10ms再检测一次。软件消抖的典型代码u8 Key_Scan(void) { if(KEY_PIN 0) { Delay_ms(10); if(KEY_PIN 0) { while(KEY_PIN 0); return 1; } } return 0; }这段代码里while(KEY_PIN 0)是等待按键释放。如果没有这一句按键按住不放的时候会一直被识别为按下。但这一句也有个问题如果按键卡住程序会死在这里。实际项目里一般用状态机或者定时器扫描来替代。注意按键的硬件连接方式决定了检测逻辑。如果按键一端接GPIO、一端接GNDGPIO配置为上拉输入那么按下时读到0松开时读到1。如果按键一端接GPIO、一端接VCCGPIO配置为下拉输入按下时读到1松开时读到0。别搞反了。4.3 LED和按键的电路设计要点开发板上的LED一般有两种接法共阳极和共阴极。共阳极是LED正极接VCC负极接GPIOGPIO输出低电平点亮。共阴极是LED负极接GND正极接GPIOGPIO输出高电平点亮。天祥、普中这些开发板的数码管和LED接法不一样用之前一定要看原理图。限流电阻不能省。LED的压降一般是1.8V到2.2V红色工作电流5mA到10mA就够了。如果GPIO输出3.3V限流电阻用220Ω到1kΩ之间。我见过有人直接把LED接在GPIO和GND之间结果LED烧了GPIO也挂了。STM32的GPIO最大输出电流是25mA但长期跑在极限值对芯片不好。5. 烧录与调试程序下不进去怎么办5.1 ST-Link的接线和驱动ST-Link是ST官方的调试器支持SWD和JTAG两种接口。F103开发板一般用SWD四根线3.3V、GND、SWDIO、SWCLK。有些板子还有RST线接上更稳定。接线的时候注意SWDIO和SWCLK不要接反VCC不要接5V。STM32F103的IO电压是3.3V接5V可能烧芯片。ST-Link的驱动在官网能下载装完之后设备管理器里能看到STLink Debug Interface。如果Keil里识别不到ST-Link先检查驱动再检查USB线。有些USB线只有充电功能没有数据线插上电脑没反应。换一根线试试。5.2 常见烧录失败原因排查烧录失败是新手遇到最多的问题没有之一。我把常见原因整理成一张表现象可能原因排查方法Keil提示No ST-Link detected驱动未装或USB线问题检查设备管理器换USB线提示Cannot access target芯片未供电或接线错误测量3.3V引脚电压检查SWD接线提示Flash Download failed芯片被读保护或Flash算法未选用ST-Link Utility解除读保护检查Flash算法配置烧录成功但程序不跑启动模式错误或时钟配置错误检查BOOT0/BOOT1跳线检查晶振程序跑一会儿就死看门狗未喂或堆栈溢出检查看门狗配置增大堆栈BOOT0和BOOT1的跳线经常被忽略。STM32F103的启动模式由BOOT0和BOOT1决定BOOT00时从主Flash启动BOOT01、BOOT10时从系统存储器启动串口下载BOOT01、BOOT11时从SRAM启动。正常跑程序的时候BOOT0要接GND。还有一个坑有些开发板上的ST-Link是板载的但用的是STM32F103的另一个型号做调试器。这种板载ST-Link有时候需要先给调试器固件升级否则Keil识别不到。升级方法是用ST-Link Utility连接然后Firmware Upgrade。5.3 用串口下载程序没有ST-Link的替代方案如果你手头没有ST-Link可以用USB转TTL模块通过串口下载。STM32F103的串口下载需要把BOOT0接VCC、BOOT1接GND然后复位芯片进入系统存储器启动模式。用FlyMcu或者STM32CubeProgrammer选择串口加载HEX文件点击下载。串口下载的速度比ST-Link慢而且每次下载都要手动切换BOOT0比较麻烦。但作为应急方案是可行的。下载完之后记得把BOOT0接回GND再复位程序才会从Flash启动。实操心得我一般会在板子上焊一个跳线帽或者拨码开关来控制BOOT0这样切换启动模式不用每次都插拔杜邦线。成本几毛钱省事很多。6. 外设入门定时器、串口和中断6.1 定时器不只是延时STM32F103的定时器资源很丰富有高级定时器TIM1、TIM8通用定时器TIM2到TIM5基本定时器TIM6、TIM7。定时器能做延时、PWM输出、输入捕获、编码器接口等。用定时器做精确延时的思路是配置定时器预分频和自动重装载值算出定时周期然后在中断里计数。比如72MHz时钟预分频72-1得到1MHz计数频率自动重装载值1000-1就是1ms中断一次。void TIM3_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Period 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); NVIC_InitStructure.NVIC_IRQChannel TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority 3; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); }中断服务函数里记得清除中断标志位否则会一直进中断。标准库的写法是TIM_ClearITPendingBit(TIM3, TIM_IT_Update)。PWM输出是定时器的另一个常用功能。配置PWM输出需要设置定时器的ARR和CCRARR决定PWM周期CCR决定占空比。比如ARR1000-1CCR500占空比就是50%。PWM可以用来调LED亮度、控制电机速度、驱动舵机。6.2 串口和电脑通信的基本手段串口是调试和通信最常用的外设。STM32F103一般用USART1接PA9TX和PA10RX。配置串口的步骤是使能USART和GPIO时钟、配置GPIO为复用推挽输出TX和浮空输入RX、配置USART参数波特率、数据位、停止位、校验位、使能USART。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_Speed GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; 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); }串口发送数据用USART_SendData接收数据用USART_ReceiveData。接收中断里记得清除标志位。如果要用printf输出调试信息需要重定向fputc函数int fputc(int ch, FILE *f) { while(USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); USART_SendData(USART1, (u8)ch); return ch; }重定向之后在Keil的Options for Target - Target里勾选Use MicroLIB否则printf可能不工作。6.3 中断优先级别让中断打架STM32F103的中断优先级分抢占优先级和响应优先级。抢占优先级高的可以打断抢占优先级低的中断响应优先级只在同时发生时起作用。NVIC的分组方式决定了抢占优先级和响应优先级各占几位。新手常见的问题是串口接收中断和定时器中断同时开结果串口数据丢了。这通常是中断优先级配置不当或者中断服务函数里执行时间太长。中断服务函数应该尽量短把耗时的处理放到主循环里。注意NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)表示2位抢占优先级、2位响应优先级。这个分组在程序里只能设置一次一般在main函数开头调用。多次设置会导致优先级混乱。7. 常见问题速查与避坑指南7.1 编译报错undefined symbol这个错误一般是头文件没包含或者源文件没加到工程里。比如用了GPIO_Init但没包含stm32f10x_gpio.h或者包含了头文件但没把stm32f10x_gpio.c加到工程里。检查方法是在Keil左侧工程树里确认对应的.c文件在不在在C/C选项的Include Paths里确认头文件路径加没加。还有一种情况是宏定义没写对。比如用了STM32F10X_MD但实际芯片是大容量的stm32f10x.h里就不会包含对应的外设定义编译的时候找不到符号。7.2 程序卡在延时函数里delay函数卡死是新手常见问题。如果是用循环实现的软件延时卡死一般是循环条件写错了。如果是用SysTick实现的延时卡死可能是SysTick配置错误或者中断优先级问题。我见过一个典型情况在中断服务函数里调用了delay_ms而delay_ms依赖SysTick中断结果SysTick中断优先级比当前中断低永远进不去死锁。解决办法是不要在中断里用依赖中断的延时函数或者把SysTick优先级设到最高。7.3 串口乱码波特率对不上串口乱码最常见的原因是波特率不匹配。STM32的波特率由USART_BRR寄存器决定计算公式是波特率 fPCLK / (16 × USARTDIV)。fPCLK是USART所在总线的时钟频率。USART1挂在APB2上时钟是72MHzUSART2挂在APB1上时钟是36MHz。如果时钟配置错了算出来的波特率就不对。还有一个原因是晶振频率和代码里配置的不一致。比如板子上焊的是8MHz晶振但代码里按12MHz算波特率就会偏。用示波器或者逻辑分析仪量一下TX引脚的实际波特率能快速定位问题。7.4 程序下载后不运行烧录成功但程序不跑先检查BOOT0跳线。BOOT0接GND是从Flash启动接VCC是从系统存储器启动。如果BOOT0接VCC程序烧到Flash里也不会跑。再检查复位电路。有些开发板的复位按键常闭导致芯片一直处于复位状态。用万用表量一下NRST引脚的电压正常应该是3.3V。还有可能是时钟配置问题。如果程序里配置了HSE但板子上没有晶振程序会卡在等待HSE稳定的循环里。这时候可以改用HSI或者检查晶振电路。7.5 常见问题速查表问题排查方向快速解决Keil找不到芯片型号芯片包未安装安装STM32F1 DFP编译报错找不到头文件Include路径未配置添加CMSIS和FWLIB路径烧录提示Flash超时ST-Link接触不良检查SWD接线降低SWD速度LED不亮GPIO模式或电路问题检查LED极性测量GPIO电平按键不灵敏消抖未处理或上拉未配置加10ms延时配置上拉输入串口收不到数据波特率或接线错误检查TX/RX是否交叉连接定时器不中断中断未使能或标志未清检查NVIC配置和清除标志程序跑飞堆栈溢出或野指针增大堆栈检查数组越界8. 进阶方向学完基础之后往哪走8.1 做几个完整项目练手光看教程不动手学完就忘。我建议学完GPIO、定时器、串口之后至少做三个完整项目一个是按键控制LED加串口输出状态一个是定时器PWM调光加串口调速一个是超声波测距加串口显示距离。这三个项目覆盖了输入、输出、定时、通信做完之后对STM32的基本用法就有感觉了。超声波测距模块HC-SR04很便宜用法也简单Trig引脚给10us高电平Echo引脚会输出高电平高电平持续时间就是距离对应的时间。距离 高电平时间 × 340m/s / 2。用定时器的输入捕获功能测Echo高电平时间精度能到厘米级。8.2 毕业设计选题参考如果你是用STM32做毕业设计选题方向可以往这几个方向靠智能家居控制温湿度采集、继电器控制、WiFi通信、环境监测PM2.5、甲醛、温湿度、电机控制步进电机、伺服电机、PID调速、数据采集ADC多通道、SD卡存储、LCD显示。选题的时候注意工作量。纯STM32的题目工作量可能不够最好加上上位机、手机APP或者云平台。比如STM32采集数据通过ESP8266传到手机APP显示这样工作量就上来了。8.3 从标准库转到HAL库和CubeMX标准库玩熟了之后可以试试STM32CubeMX HAL库。CubeMX图形化配置引脚、时钟、外设生成初始化代码省去手动配置寄存器的麻烦。HAL库的API更统一跨系列移植方便。但HAL库的代码效率比标准库低中断处理也更复杂适合项目开发不太适合学习底层原理。转HAL库的时候重点理解这几个概念句柄Handle、回调函数Callback、阻塞和非阻塞模式。HAL库的UART接收有阻塞、中断、DMA三种模式用熟了之后开发效率确实高。实操心得我一般用CubeMX生成初始化代码然后自己写业务逻辑。CubeMX生成的代码里用户代码要写在/* USER CODE BEGIN/和/USER CODE END */之间这样重新生成代码的时候不会被覆盖。这个习惯能省很多事。8.4 硬件设计入门从开发板到自己画板用开发板做项目最终还是要落到自己画板子上。画STM32最小系统板需要这些东西STM32芯片、晶振电路8MHz主晶振 32.768kHz RTC晶振、复位电路、电源电路3.3V稳压、BOOT跳线、SWD调试接口。画板子用Altium Designer或者KiCad新手建议从KiCad开始免费且功能够用。画板子的时候注意几点晶振尽量靠近芯片负载电容按晶振手册选一般20pF左右电源引脚加去耦电容100nFSWD接口留出VCC、GND、SWDIO、SWCLK四根线。第一次画板子建议把引脚都引出来方便后面扩展。9. 一些零散但重要的经验开发板买回来第一件事不是写代码是看原理图。原理图告诉你LED接在哪个引脚、按键接在哪个引脚、晶振频率是多少、电源怎么供。不看原理图直接写代码等于闭着眼睛开车。Keil的工程模板建议自己整理一份。把CMSIS、FWLIB、USER、HARDWARE这几个目录固定下来以后新建工程直接复制模板改改main.c就能用。我自己的模板用了好几年省了无数新建工程的时间。遇到问题先搜再问。STM32的生态太成熟了你遇到的问题99%别人都遇到过。搜索关键词用英文比如“STM32F103 GPIO not working”、“Keil ST-Link cannot access target”搜出来的结果质量比中文高很多。最后说一个很多人忽略的点学会看数据手册和参考手册。数据手册Datasheet讲的是电气特性和引脚定义参考手册Reference Manual讲的是外设的工作原理和寄存器定义。这两个文档是STM32开发的根本遇到不确定的地方翻手册比在网上搜半天靠谱。我个人在实际操作中的体会是STM32入门最难的不是写代码而是环境搭建和问题排查。代码写错了编译不过至少知道错在哪环境配错了可能连错在哪都不知道。所以新手阶段把工具链配好、把烧录流程跑通、把调试手段用熟比急着写业务代码重要得多。板子买回来了就赶紧动手别让它吃灰。
返回列表