资讯详情

资讯详情

STM32F103开发板入门实战:从开箱到独立项目的完整指南

STM32 开发板到手之后第一件事往往不是急着写代码而是先把“板子能不能跑起来”这件事确认清楚。我见过太多人板子买回来插上电脑灯不亮、串口不识别、Keil 报一堆错折腾两天热情就没了。STM32F103 这块板子算是嵌入式入门的经典款资料多、价格低、外设全但它的坑也不少尤其是对刚接触 ARM 架构、从 51 单片机转过来的人。这篇内容我打算把 STM32F103 开发板从开箱到跑通第一个工程、再到能自己写点小项目的完整路径讲清楚包括工具链怎么选、工程怎么建、常见问题怎么排查以及后面可以往哪些方向深入。不管你是电子专业的学生、想转嵌入式的程序员还是单纯想玩玩硬件只要跟着这条线走基本能少走很多弯路。1. 拿到板子之后先别写代码把这几件事确认了1.1 开发板到手后的物理检查与供电确认STM32F103 开发板市面上版本很多常见的有最小系统板、带外设的综合板、以及各种“学习板”。不管哪种拿到手第一件事是看板子上的丝印和跳线帽。很多板子出厂时跳线帽的位置是随机的尤其是 BOOT0 和 BOOT1 这两个引脚它们决定了芯片从哪里启动。BOOT0 接高电平、BOOT1 接低电平是串口下载模式两个都接低才是从 Flash 启动正常运行。我遇到过有人板子买回来一直跑不起来最后发现是 BOOT0 被跳到了 3.3V芯片一直在等串口下载根本不执行程序。供电方面STM32F103 的工作电压是 2.0V 到 3.6V典型值 3.3V。大部分开发板支持 USB 供电和外部电源供电两种方式。用 USB 供电时要注意有些便宜板子的 USB 口只做数据通信供电能力不足插上之后芯片能识别但跑起来会复位。判断方法很简单用万用表量一下 3.3V 稳压芯片的输出如果低于 3.2V换一个供电能力强的 USB 口或者用外部 5V 电源。另外板子上的电源指示灯亮不代表电压一定正常最好还是量一下。还有一个容易被忽略的点STM32F103 的每个电源引脚旁边都应该有去耦电容通常是 100nF。有些低成本板子为了省成本会省略或者用劣质的导致芯片在高频运行时不稳定。如果你发现程序跑着跑着就死机排除代码问题之后可以看看板子上电源引脚附近有没有足够的电容。没有的话自己焊一个 100nF 的贴片电容上去问题往往就解决了。1.2 芯片型号识别与数据手册的对应关系STM32F103 只是一个系列名具体型号有很多比如 STM32F103C8T6、STM32F103RCT6、STM32F103ZET6 等等。型号里的字母和数字是有含义的C 代表 48 引脚R 代表 64 引脚Z 代表 144 引脚8 代表 64KB FlashC 代表 256KB FlashE 代表 512KB FlashT 代表 LQFP 封装6 代表工业级温度范围。你拿到板子之后先看清楚芯片上激光刻的型号然后去下载对应的数据手册和参考手册。这里有个关键点STM32F103 的参考手册Reference Manual是通用的但数据手册Datasheet是按具体型号分的。参考手册讲的是外设怎么用、寄存器怎么配数据手册讲的是这个具体型号有多少引脚、多少 Flash、电气参数是什么。很多人只看参考手册结果配置引脚的时候发现某个功能在这个型号上没有就是因为没看数据手册。我建议把这两份文档都下载下来放在手边随时查。另外STM32F103 的固件库有标准外设库Standard Peripheral Library和 HAL 库两种。标准库更接近寄存器操作代码效率高适合学习底层原理HAL 库抽象程度高跨系列移植方便适合快速开发。对于刚入门的人来说我建议先用标准库因为它的代码结构清晰能让你看清楚每个外设是怎么配置的。等你熟悉了之后再转 HAL 库或者 LL 库都可以。1.3 调试器与下载方式的选型逻辑STM32F103 支持多种下载方式串口下载通过 BOOT0 进入系统存储器、SWD 下载通过 SWDIO 和 SWCLK 两根线、JTAG 下载需要更多引脚。串口下载最简单只需要一个 USB 转 TTL 模块但每次下载都要手动切换 BOOT0 跳线而且不能在线调试。SWD 下载需要 ST-Link 或者 J-Link 调试器但支持在线仿真、断点调试、查看寄存器是实际开发中最常用的方式。如果你买的开发板板载了 ST-Link那直接插 USB 就能用。如果没有建议单独买一个 ST-Link V2价格不贵大概十几块钱但能省很多事。J-Link 更强大但价格也更高而且市面上有很多山寨版本固件容易掉。对于 STM32F103 来说ST-Link 完全够用。连接的时候注意SWDIO 对应 PA13SWCLK 对应 PA14GND 必须共地3.3V 可以不接如果板子自己供电的话。注意有些开发板的 SWD 接口顺序不是标准的连接之前一定要看板子的原理图或者丝印接反了可能烧调试器。我个人的习惯是板子到手之后先用串口下载一个最简单的 LED 闪烁程序确认芯片能跑、时钟配置正确、GPIO 能输出。然后再接 ST-Link测试在线调试功能。这样分步验证出了问题也容易定位。2. 开发环境搭建Keil、VSCode 还是 STM32CubeIDE2.1 Keil MDK 的安装与芯片包配置Keil MDK 是国内 STM32 开发最常用的 IDE资料多、教程全、社区活跃。安装 Keil MDK 本身不复杂但有几个坑要注意。首先Keil MDK 和 Keil C51 是可以共存的但安装顺序有讲究先装 C51再装 MDK这样两个环境都能正常使用。如果先装了 MDK 再装 C51可能会覆盖一些公共文件导致 MDK 的编译器出问题。安装完 Keil MDK 之后还需要安装 STM32F1 系列的芯片包Device Family Pack。这个包包含了芯片的启动文件、外设寄存器定义、Flash 算法等。没有它Keil 里选不到 STM32F103 的型号编译也会报错。芯片包可以从 Keil 官网下载也可以从 ST 官网下载。安装的时候注意版本太老的版本可能不支持新的芯片型号太新的版本可能和你的 Keil 版本不兼容。一般来说选比 Keil 版本稍晚一点发布的芯片包比较稳妥。还有一个常见问题Keil 的编译器版本。Keil MDK 5.x 默认使用 ARM Compiler 5AC5但有些新版本的芯片包可能要求 ARM Compiler 6AC6。如果你编译的时候报“compiler version not supported”之类的错误需要在 Keil 的 Options for Target - Target 里切换编译器版本。AC5 和 AC6 的语法有些差异尤其是内联汇编和某些宏定义切换之后可能需要改代码。2.2 VSCode 插件方案的适用场景与配置要点VSCode 本身不是 IDE但通过安装插件可以变成强大的嵌入式开发环境。常用的插件组合是Cortex-Debug用于调试、STM32 VS Code ExtensionST 官方插件、以及 Keil Assistant用于调用 Keil 的编译工具链。这种方案的好处是编辑体验好、代码补全强、界面现代适合已经熟悉 VSCode 的开发者。配置 VSCode 开发 STM32 的关键是 launch.json 和 tasks.json 这两个文件。launch.json 告诉调试器怎么连接目标板、用什么调试器、加载什么符号文件tasks.json 告诉 VSCode 怎么编译工程。如果你用 Keil 的编译工具链需要在 tasks.json 里调用 Keil 的命令行工具 UV4.exe。如果你用 arm-none-eabi-gcc那就要自己写 Makefile 或者用 CMake。这里有个坑VSCode 的 Cortex-Debug 插件默认使用 GDB 调试但 ST-Link 的 GDB Server 有时候会和 Keil 的 ST-Link 驱动冲突。解决办法是安装 ST-Link 的独立驱动或者在调试配置里指定使用 OpenOCD。OpenOCD 是一个开源的调试工具支持多种调试器和目标芯片配置起来稍微复杂一点但稳定性更好。提示如果你刚开始学 STM32不建议一上来就用 VSCode 方案。先把 Keil 或者 STM32CubeIDE 用熟理解编译、下载、调试的流程之后再折腾 VSCode 会轻松很多。2.3 STM32CubeIDE 与 CubeMX 的配合使用STM32CubeIDE 是 ST 官方推出的免费 IDE基于 Eclipse 和 GCC 工具链。它最大的优势是集成了 CubeMX可以通过图形化界面配置引脚、时钟、外设然后自动生成初始化代码。对于新手来说这能大大降低入门门槛因为你不需要手动查寄存器手册就能把外设配起来。CubeMX 的使用逻辑是先选芯片型号然后配置时钟树比如 HSE 用 8MHz 晶振PLL 倍频到 72MHz再配置外设比如 USART1 异步模式、GPIO 输出模式最后生成代码。生成的代码里初始化部分都在 main.c 的 SystemClock_Config 和 MX_xxx_Init 函数里你只需要在 while(1) 循环里写自己的逻辑就行。不过 CubeMX 生成的代码有个特点它把初始化代码和用户代码分开了用户代码要写在 /* USER CODE BEGIN/ 和 /USER CODE END */ 之间否则重新生成代码的时候会被覆盖。这个机制一开始可能会让人觉得别扭但习惯了之后其实很方便因为你可以随时回到 CubeMX 改配置重新生成代码而不会丢失自己写的逻辑。STM32CubeIDE 还集成了调试功能支持 ST-Link 和 J-Link可以直接在 IDE 里打断点、看变量、看寄存器。对于不想折腾环境的人来说这是一个比较省心的选择。缺点是 Eclipse 的界面相对笨重代码补全不如 VSCode 流畅而且生成的代码体积比标准库大一些。3. 第一个工程从点亮 LED 到串口输出3.1 新建工程时的时钟配置与启动文件选择新建 STM32F103 工程的时候有几个关键选择会影响后续开发。首先是启动文件的选择Keil 里通常有 startup_stm32f10x_hd.s、startup_stm32f10x_md.s、startup_stm32f10x_ld.s 等几个版本分别对应大容量、中容量、小容量产品。STM32F103C8T6 属于中容量Flash 是 64KB应该选 md 版本。选错了启动文件编译可能通过但运行会出问题因为中断向量表的偏移和堆栈大小不一样。时钟配置是另一个重点。STM32F103 最高可以跑到 72MHz但默认的内部时钟HSI只有 8MHz。要跑到 72MHz需要配置 PLLHSE外部晶振通常是 8MHz经过 9 倍频得到 72MHz然后作为系统时钟。同时还要配置 AHB、APB1、APB2 的分频系数。APB1 最高 36MHzAPB2 最高 72MHz如果超频了外设可能工作不正常。比如 USART1 挂在 APB2 上如果 APB2 是 72MHz那波特率计算就是 72MHz 除以分频系数如果 APB2 配错了串口输出的就是乱码。用标准库配置时钟的典型代码是这样的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); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); }这段代码的逻辑是先开 HSE等它稳定然后配置 PLL 为 HSE 的 9 倍频再开 PLL等它锁定最后把系统时钟切到 PLL并配置各总线的分频。每一步都有等待标志位的循环这是必须的因为时钟切换需要时间不等稳定就切会导致芯片跑飞。3.2 GPIO 初始化的标准流程与常见错误点亮 LED 的本质是控制 GPIO 输出高低电平。STM32F103 的 GPIO 有 8 种模式输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、开漏复用、推挽复用。控制 LED 一般用推挽输出因为推挽输出的驱动能力强能直接驱动 LED。GPIO 初始化的标准流程是先开 GPIO 的时钟比如 PA 口挂在 APB2 上要调用 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)然后定义 GPIO_InitTypeDef 结构体设置引脚、速度、模式最后调用 GPIO_Init 函数。这里最常见的错误是忘记开时钟结果 GPIO 配置不生效LED 死活不亮。我刚开始学的时候也犯过这个错查了半天代码没发现问题最后才发现是时钟没开。另一个常见错误是引脚号写错。STM32 的引脚号是 GPIO_Pin_0 到 GPIO_Pin_15对应 PA0 到 PA15。如果你要控制 PA5就写 GPIO_Pin_5。但有些人会写成 GPIO_Pin_5 对应的物理引脚是第 5 脚这是不对的。PA5 在 LQFP48 封装里可能是第 15 脚或者别的具体要看数据手册的引脚定义表。LED 的接法也有讲究。如果 LED 是阳极接 3.3V、阴极接 GPIO那 GPIO 输出低电平的时候 LED 亮这叫灌电流接法如果 LED 是阳极接 GPIO、阴极接地那 GPIO 输出高电平的时候 LED 亮这叫拉电流接法。STM32 的 GPIO 灌电流能力比拉电流强所以灌电流接法更常见。写代码的时候要注意逻辑电平别搞反了。3.3 串口通信的波特率计算与重定向 printf串口是嵌入式开发中最重要的调试手段。STM32F103 有 3 个 USART 和 2 个 UART其中 USART1 挂在 APB2 上USART2 和 USART3 挂在 APB1 上。配置串口的时候波特率、数据位、停止位、校验位都要设置。最常用的是 115200-8-N-1即波特率 1152008 位数据位无校验1 位停止位。波特率的计算是波特率 fPCLK / (16 * USARTDIV)其中 fPCLK 是串口所在总线的时钟频率。比如 USART1 挂在 APB2 上APB2 是 72MHz要得到 115200 的波特率USARTDIV 72000000 / (16 * 115200) 39.0625。标准库的 USART_Init 函数会自动计算这个值你只需要填 115200 就行。但如果你改了系统时钟忘了改波特率串口输出的就是乱码。重定向 printf 是调试中非常实用的技巧。标准库的 printf 默认输出到控制台在嵌入式里没有控制台需要重定向到串口。方法是重写 fputc 函数int fputc(int ch, FILE *f) { while(USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); USART_SendData(USART1, (uint8_t)ch); return ch; }然后在 Keil 的 Options for Target - Target 里勾选“Use MicroLIB”。MicroLIB 是 ARM 提供的精简版 C 库支持 printf 重定向而且代码体积小。如果不勾选 MicroLIB就需要自己实现 _sys_write 等底层函数比较麻烦。注意重定向 printf 之后串口发送是阻塞的如果串口被占用或者波特率不对程序会卡在 while 循环里。调试的时候如果发现程序跑着跑着不动了先检查串口是不是卡住了。4. 那些年我们一起踩过的 STM32 坑4.1 下载失败与芯片被锁的排查链路STM32 下载失败是最常见的问题之一表现是 Keil 或者 ST-Link Utility 提示“No target connected”或者“Flash download failed”。排查的时候按这个顺序来先检查硬件连接SWDIO、SWCLK、GND 是否接好目标板是否供电然后检查调试器驱动是否安装设备管理器里有没有识别到 ST-Link再检查 Keil 里的调试配置是否选对了调试器型号和接口SWD 还是 JTAG最后检查芯片是否被读保护或者写保护了。芯片被锁的情况通常是因为程序里禁用了 SWD 引脚或者设置了读保护。STM32F103 的 SWD 引脚是 PA13 和 PA14如果程序里把这两个引脚配置成了普通 GPIO 或者复用功能SWD 就连不上了。解决办法是把 BOOT0 接高电平让芯片进入系统存储器启动模式然后用 ST-Link Utility 连接解除读保护再重新下载程序。如果读保护也解不了可能需要用串口下载或者擦除整个 Flash。还有一种情况是芯片进入了低功耗模式SWD 也连不上。这时候可以尝试在连接设置里把“Connect under reset”打开让调试器在芯片复位的时候连接。或者手动按住复位键点击下载然后松开复位键利用这个时间窗口连接。4.2 中断不响应与优先级配置的陷阱中断是 STM32 的核心功能之一但配置起来容易出问题。最常见的是中断不响应原因可能有几个中断使能没开、NVIC 配置不对、中断服务函数名写错、优先级分组没设置。STM32F103 的中断优先级分为抢占优先级和响应优先级通过 NVIC_PriorityGroupConfig 函数设置分组。分组决定了抢占优先级和响应优先级各占几位。如果分组设置不对可能导致高优先级中断被低优先级中断阻塞。中断服务函数的名字必须和启动文件里的向量表一致。比如 USART1 的中断服务函数是 USART1_IRQHandler如果你写成 USART1_IRQhandler小写 h编译器不会报错但中断触发的时候会跳到默认的无限循环里程序就死了。这个错误很隐蔽因为编译能通过下载也能成功就是中断不工作。还有一个坑是中断标志位没清除。STM32 的中断标志位需要在中断服务函数里手动清除否则中断会一直触发程序卡在中断里出不来。比如串口接收中断收到数据之后要调用 USART_ClearITPendingBit 清除标志位。如果忘了清主循环就永远执行不到。4.3 延时函数卡死与时钟树的关系延时函数卡死是新手经常遇到的问题。很多人用 SysTick 做延时配置的时候没注意时钟源。SysTick 的时钟源可以是 HCLK 的 1/8 或者 HCLK 本身。如果系统时钟是 72MHzSysTick 用 HCLK/8那计数频率就是 9MHz。如果延时函数里按 72MHz 算延时就会差 8 倍。更严重的是如果时钟配置失败HCLK 不是预期的频率SysTick 的计数就不对延时可能变得极长看起来就像卡死了。还有一种情况是延时函数里用了 while 循环等待标志位但标志位永远不置位。比如等待 HSE 就绪的 while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) RESET)如果外部晶振没起振这个循环就出不来了。外部晶振不起振的原因可能是晶振坏了、负载电容不匹配、或者焊接不良。可以用示波器量一下晶振引脚看有没有波形。没有波形的话先换晶振再检查电容。提示调试的时候可以在延时循环里加一个超时计数超过一定次数就退出并返回错误码。这样即使时钟有问题程序也不会完全卡死方便定位问题。4.4 串口乱码与波特率误差的定量分析串口乱码的原因通常是波特率不匹配。除了前面说的时钟配置错误还有一个容易被忽略的因素波特率误差。STM32 的 USART 波特率是通过分频得到的分频系数是整数加小数实际波特率和理论波特率之间会有误差。如果误差超过 2%通信就可能出错。以 72MHz 时钟、115200 波特率为例USARTDIV 72000000 / (16 * 115200) 39.0625。标准库会把 39.0625 拆成整数部分 39 和小数部分 0.0625小数部分乘以 16 得到 1所以 BRR 寄存器的值是 39 * 16 1 625。实际波特率 72000000 / (16 * 39.0625) 115200误差为 0。但如果时钟是 72MHz、波特率是 9600USARTDIV 72000000 / (16 * 9600) 468.75BRR 468 * 16 12 7500实际波特率 72000000 / (16 * 468.75) 9600误差也是 0。但如果时钟是 72MHz、波特率是 921600USARTDIV 72000000 / (16 * 921600) 4.8828125BRR 4 * 16 14 78实际波特率 72000000 / (16 * 4.875) 923076误差约 0.16%还在可接受范围内。但如果时钟不是 72MHz比如用了内部 HSI 的 8MHz那波特率误差就会大很多。所以串口通信一定要用外部晶振而且时钟配置要准确。如果实在要用内部时钟建议把波特率降低比如用 9600 或者 4800误差会小一些。5. 从跑通例程到独立做项目中间还差什么5.1 外设驱动开发的通用套路跑通 LED 和串口之后下一步是学其他外设定时器、ADC、SPI、I2C、CAN 等。每个外设的配置流程其实都差不多开时钟、配 GPIO、配外设参数、使能外设、写中断服务函数如果需要。以定时器为例配置流程是开 TIM 时钟、配 GPIO如果是 PWM 输出、配时基结构体预分频、自动重装载值、计数模式、配输出比较结构体PWM 模式、占空比、使能定时器、使能输出比较通道。学外设的时候我建议先看参考手册里对应章节的功能描述理解这个外设能做什么、有哪些模式、寄存器怎么配。然后看标准库的例程理解代码是怎么实现的。最后自己改参数观察现象变化。比如定时器 PWM改预分频值看频率变化改比较值看占空比变化。这样学下来比单纯抄代码理解得深得多。5.2 用模块化思维组织工程代码刚开始写代码的时候很多人把所有代码都堆在 main.c 里几百行还能忍上千行就乱了。正确的做法是按功能模块拆分文件比如 led.c/led.h、uart.c/uart.h、timer.c/timer.h。每个模块对外提供初始化函数和操作函数内部实现细节放在 .c 文件里.h 文件只放函数声明和宏定义。模块化还有一个好处是方便复用。比如你写了一个串口驱动下一个项目直接把这个 .c 和 .h 文件拷过去就能用只需要改一下引脚定义和波特率。我自己的习惯是建一个“驱动库”文件夹把常用的 LED、串口、定时器、按键、OLED 等驱动都放进去新项目直接拿来用省很多时间。头文件里要用条件编译防止重复包含#ifndef __LED_H #define __LED_H #include stm32f10x.h void LED_Init(void); void LED_On(void); void LED_Off(void); void LED_Toggle(void); #endif这个宏定义的名字要和文件名对应比如 led.h 就用 __LED_H避免不同头文件之间冲突。5.3 调试手段的进阶SWO、逻辑分析仪与 RTT除了串口打印还有一些更高级的调试手段。SWOSerial Wire Output是 SWD 接口的一个引脚可以输出调试信息速度比串口快而且不占用串口资源。配置 SWO 需要在 Keil 里打开 ITM 功能然后在代码里用 ITM_SendChar 输出。不过 SWO 需要调试器支持ST-Link V2 支持但有些山寨版可能不支持。逻辑分析仪是分析时序问题的利器。比如 I2C 通信失败用逻辑分析仪抓一下 SCL 和 SDA 的波形就能看出是起始条件不对、地址不对、还是 ACK 没收到。市面上几十块钱的 8 通道逻辑分析仪配合 PulseView 软件足够分析大部分低速数字信号。SPI、I2C、UART 的时序都能抓。RTTReal Time Transfer是 SEGGER 公司推出的一种调试技术通过 J-Link 调试器在目标板和电脑之间传输数据速度比串口快很多而且不需要占用串口。如果你用的是 J-Link可以试试 RTT配合 RTT Viewer 软件打印调试信息非常方便。不过 ST-Link 不支持 RTT所以用 ST-Link 的话还是老老实实用串口吧。5.4 可以拿来练手的几个小项目方向学完基础外设之后最好的巩固方式是自己做几个小项目。第一个推荐的是“按键控制 LED”看似简单但涉及 GPIO 输入、消抖、状态机能学到不少东西。第二个是“串口命令行”通过串口发送指令控制 LED 或者读取传感器数据涉及串口接收中断、缓冲区管理、字符串解析。第三个是“定时器 PWM 调光”用 PWM 控制 LED 亮度涉及定时器配置、占空比计算。第四个是“OLED 显示”用 I2C 或 SPI 驱动 OLED 屏幕显示文字和图形涉及通信协议、字库取模、图形绘制。如果这些都能独立做出来那基本可以尝试更复杂的项目了比如“超声波测距”定时器输入捕获、“步进电机控制”定时器 PWM 方向控制、“CAN 通信”CAN 外设配置 报文收发、“USB 设备”USB 外设 描述符配置。每个项目都会遇到新的问题解决这些问题的过程就是成长的过程。提示做项目的时候养成写文档的习惯把遇到的问题、解决方法、关键代码都记下来。过一段时间回头看你会发现这些记录比任何教程都有价值。6. 关于学习节奏和心态的一点个人体会STM32 的学习曲线不算陡但也不平。前两周可能会觉得很多东西不理解寄存器、时钟树、中断优先级一堆概念堆在一起。这很正常我当初也是这么过来的。我的建议是不要试图一次搞懂所有东西先跑通例程看到现象再回头理解原理。比如时钟树一开始不用完全搞懂知道 HSE 倍频到 72MHz 就行等遇到串口乱码或者定时器不准的时候再深入看时钟树的分频关系理解会更深。另外不要只盯着 STM32F103。这颗芯片虽然经典但确实有点老了。学完 F103 之后可以看看 STM32F4 或者 STM32G0它们的外设更丰富、性能更强、价格也不贵。HAL 库的跨系列兼容性这时候就体现出来了F103 上写的 HAL 代码移植到 F4 上可能只需要改几个宏定义。如果对无线通信感兴趣可以看看 ESP32 系列它集成了 Wi-Fi 和蓝牙和 STM32 配合使用能做出很多有意思的东西。最后说一句嵌入式开发是一个需要动手的领域看十遍教程不如自己焊一块板子、写一遍代码。板子买回来了就赶紧插上电从点亮第一个 LED 开始。遇到问题不要怕每一个坑都是经验踩过的坑越多后面走的路越顺。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →