前言
如果你是从这个专栏第一篇文章一路看过来的,那恭喜你,咱们终于走到"结业"这一步了。
说实话,当我写完专栏里最后一篇笔记时,我坐在电脑前愣了一会儿——原来江科大那个几十小时的入门教程,我真的一点一点啃完了。从最开始连GPIO_Init函数都要对着视频敲,到现在能独立配置一个带中断、DMA、多外设联动的小模块,这段路说长不长,说短也不短。
但这篇不是来煽情的。我想做的,是把这个专栏里散落的知识点串成一张网,顺便把我这一路上踩过的坑、有过的困惑、突然"开窍"的瞬间,原原本本地分享给你。如果你也正在学STM32,或者刚刷完江科大的视频感觉"好像懂了又好像没懂",那这篇文章应该能给你一点方向。
二、专栏内容回顾:我们都学了啥?
STM32学习专栏:点击跳转
这个专栏跟着江科大的视频节奏,基本上把STM32F103最核心、最常用的外设都覆盖到了。为了方便大家按需复习,我把专栏文章按学习顺序整理了一下,你可以直接点链接跳转到对应文章:
| 知识点 | 核心内容 | 专栏文章链接 |
|---|---|---|
| GPIO | 8种工作模式、寄存器/库函数操作、流水灯/按键实验 | 👉 点击跳转 |
| EXTI外部中断 | NVIC配置、中断优先级、EXTI线映射 | 👉 点击跳转 |
| TIM定时器 | 基本定时、通用定时器、时基单元配置 | 👉 点击跳转 |
| PWM输出 | PWM原理、CCR/ARR关系、舵机/电机控制 | 👉点击跳转 |
| TIM输入捕获 | 测频率、测脉宽、主从触发模式 | 👉 点击跳转 |
| ADC模数转换 | 单/多通道、规则组/注入组、扫描/连续模式 | 👉 点击跳转 |
| DMA直接存储器访问 | 存储器↔外设搬运、DMA中断、减轻CPU负担 | 👉 点击跳转 |
| USART串口通信 | 波特率配置、收发数据、printf重定向 | 👉点击跳转 |
| I2C通信 | 起始/停止信号、应答位、MPU6050/OLED实战 | 👉 点击跳转 |
| SPI通信 | 全双工/半双工、W25Q64/W25Q128 Flash读写 | 👉 点击跳转 |
| RTC实时时钟 | 后备区域、BKP寄存器、秒中断/闹钟 | 👉点击跳转 |
| WDG看门狗 | 独立看门狗IWDG、窗口看门狗WWDG | 👉 点击跳转 |
⚠️版本提示:以上所有内容均基于STM32F103C8T6 + 标准库3.5.0编写。如果你使用的是HAL库或STM32CubeMX自动生成代码,配置方式和函数接口会有较大差异,建议先理解标准库底层原理后再迁移到HAL库,会轻松很多。
三、我的理解:这些知识点到底是怎么串起来的?
刷完视频、写完专栏之后,我尝试用一个"项目思维"重新梳理了一遍这些外设。我的理解是:STM32的学习,本质上是在学习"如何让CPU高效地跟外部世界打交道"。
咱们一步一步来看:
第一步:点亮一个LED(GPIO)
这是最基础的"打交道"方式——CPU直接控制引脚电平高低。但GPIO不仅仅是"输出高/低电平",8种工作模式的存在,是为了应对不同的"对话场景":推挽输出能稳定驱动LED,开漏输出能玩I2C总线,浮空输入能检测按键,上拉输入能省一个电阻……选错模式,硬件就罢工,这是我对GPIO最深的体会。
第二步:让LED闪得有规律(TIM定时器)
手动延时Delay()太蠢了,CPU被死死卡住啥也干不了。定时器的出现,就是为了让"时间控制"这件事从CPU手里解放出来——定时器自己数自己的,数够了发个中断通知CPU一声。我的理解是:定时器是STM32的"心脏节拍器",PWM、输入捕获、甚至后面ADC的定时采样,都要靠它来打底。
第三步:按键按下就闪(EXTI外部中断)
轮询检测按键太浪费CPU资源了,中断的思想就是:没事别找我,有事我喊你。但这里有个大坑——NVIC中断优先级。我一开始以为"优先级数字越小越优先"就完事了,直到我在一个项目里同时开了定时器中断和串口中断,发现高优先级中断能打断低优先级的,而同级中断不能嵌套,这才真正理解了"抢占优先级"和"响应优先级"的区别。
第四步:LED亮度可调(PWM)
PWM不是新的外设,它是定时器的一个功能。这个知识点让我第一次感觉到"外设之间是有联系的"——PWM的本质,就是定时器在不停地翻转IO口。理解了这一点,再看舵机控制、电机调速,就不会觉得是什么新东西了。
第五步:采集传感器数据(ADC)
外部世界是模拟的,CPU只认数字。ADC就是翻译官。但翻译官干活慢,如果让CPU守着它一个字一个字地读,太浪费了。所以DMA登场——DMA是"数据搬运工",ADC采完一批数据,DMA直接搬到内存数组里,CPU该干嘛干嘛,等DMA搬完了发个中断通知一声就行。这个"ADC+DMA"的组合拳,是我觉得标准库里最优雅的设计之一。
第六步:跟电脑/其他芯片说话(USART/I2C/SPI)
这三个通信协议,解决的是"远距离/多设备/高速率"的通信需求。我的理解是:
USART:一对一,长距离,异步,适合跟电脑调试、蓝牙模块对话;
I2C:一对多,两根线,有应答机制,适合接OLED、MPU6050这种慢速设备;
SPI:一对一/一对多,四根线,全双工高速,适合Flash、TFT屏这种大数据量场景。
选错通信协议,就像你跟一个只说英语的人讲中文——硬件连对了,数据也对不上。
四、个人理解 & 学习心得 ⭐
📝以下是我自己的真实学习感受,供参考。
4.1 "看懂"和"会做"之间,差了一个"手熟"
本身也是第一次接触单片机,直接听了江科大的stm32,江科大的视频我第一遍刷的时候,感觉"这都是什么嘛,根本看不懂"。当我关掉视频,自己从头写一个定时器中断程序的时候,光是TIM_TimeBaseInitTypeDef结构体里那几个参数就卡了半小时——预分频系数到底填多少?计数模式选向上还是向下?时钟分频因子是干嘛的?看视频的时候,你的大脑会自动帮你"脑补"那些你没真正理解的细节。只有亲手敲一遍、编译报错一遍、调试器里单步跟一遍,那些模糊的概念才会变清晰。所以我的建议是:每看完一个外设的视频,立刻关掉视频,凭记忆把代码写一遍,写不出来再回去看。
4.2 不要急着背代码,要理解"为什么这样配"
我一开始学的时候,特别喜欢把江科大的代码原封不动抄下来,甚至想把那些初始化函数背下来。后来发现完全没必要——STM32的库函数就是"填空题",你只要理解每个外设的工作原理,知道结构体里每个成员是控制什么的,配起来就是水到渠成。
理解了"为什么",代码自然就写出来了;只背了"是什么",换个芯片就抓瞎。
4.3 调试能力比编码能力更重要
这个专栏写下来找bug的过程,其实是对STM32工作原理的二次学习。
印象最深的一次,是我配ADC多通道扫描+DMA传输,代码逻辑完全没问题,但读出来的数据始终是乱的。最后发现是因为DMA的传输长度设成了"半字(16位)",但我的数组是32位整型,数据对齐出了问题。这种坑,你不亲手踩一遍,看视频是永远学不会的。
所以,别怕报错。报错是STM32在教你做人,也是在教你做工程师。
五、踩坑记录 🕳️
以下是我整个专栏学习过程中,印象最深的几个坑。有些坑是江科大视频里提过的,有些是我自己额外踩的,整理出来给大家避雷:
| 踩坑现象 | 原因分析 | 解决办法 | 涉及外设 |
|---|---|---|---|
| 程序下载后没反应,板子"假死" | Boot0引脚悬空或接高,芯片进入了系统存储器启动模式 | Boot0接GND,确保从主闪存启动 | 通用 |
| 某个外设初始化完,功能就是不对 | 99%的概率是没开这个外设的时钟 | 检查RCC_APB2PeriphClockCmd/RCC_APB1PeriphClockCmd有没有使能对应外设 | 通用 |
| 定时器中断死活进不去 | NVIC优先级分组没配,或者TIM_ITConfig没开启对应中断源 | 确认NVIC_PriorityGroupConfig()和TIM_ITConfig()都正确调用 | TIM |
| 串口打印乱码/收不到数据 | 波特率计算错误(晶振用错了)、USART时钟没开、TX/RX引脚复用没配 | 确认晶振是8MHz,检查GPIO_PinRemapConfig和AFIO时钟 | USART |
| ADC多通道扫描结果错位 | 通道转换顺序和数组索引没对应上,或者采样时间太短信号没稳定 | 检查ADC_RegularChannelConfig的Rank参数,适当延长采样周期 | ADC |
| DMA传输完数据不对 | 数据宽度(Byte/HalfWord/Word)和数组类型不匹配 | 确保DMA_InitStructure.DMA_PeripheralDataSize与数组类型一致 | DMA |
| I2C通信时序混乱,设备无应答 | 软件模拟I2C时延时不够,或者硬件I2C的时钟配置有问题 | 检查上拉电阻(4.7KΩ),软件模拟时适当增加延时 | I2C |
| 看门狗复位导致程序"莫名其妙重启" | 独立看门狗一旦开启就必须定时喂狗,否则超时就复位 | 在main循环里加入IWDG_ReloadCounter(),注意中断里喂狗可能被打断 | WDG |
⚠️ 以上踩坑记录基于STM32F103C8T6 + 标准库3.5.0 + Keil5环境。如果你使用的是HAL库、STM32CubeMX或其他型号芯片(如F4系列、G0系列),部分寄存器名称和配置函数会有差异,请以对应参考手册和库函数手册为准。
七、给正在学STM32的你:下一步该怎么走?
刷完视频、写完专栏,其实只是STM32学习的第一阶段。接下来该怎么走?结合我自己的规划和踩坑经验,给大家几个建议:
7.1 去B站找个小项目,把知识点"串"起来
这是最重要的一步。专栏里的知识点是一颗颗珠子,项目是穿珠子的线。没有项目,珠子永远是散的。
推荐几个适合练手、且B站有完整教程的小项目:
温湿度监测+OLED显示(DHT11 + I2C OLED,覆盖GPIO、I2C、定时器)
蓝牙遥控LED/舵机(HC-05 + PWM,覆盖USART、GPIO、TIM)
简易示波器(ADC+DMA+TFT屏,覆盖高速数据采集和显示)
智能小车(红外循迹/超声波避障,覆盖GPIO、PWM、EXTI、定时器综合应用)
我的建议是:第一个项目别选太复杂的。能把"温湿度+OLED+串口打印"这三个外设整合到一个项目里跑通,就已经很厉害了,我找的是一个智能小车项目。
7.2 尝试"脱离视频",自己看参考手册
江科大的视频是"喂饭",参考手册是"食谱"。当你对一个外设有了基本理解之后,试着去翻一翻《STM32F10xxx参考手册》对应章节。一开始肯定看不懂,但看多了你会发现:库函数本质上就是参考手册里寄存器操作的C语言封装。能看懂参考手册,你就真正"自由"了。
7.3 考虑向HAL库/CubeMX迁移
标准库的优点是"透明",缺点是"繁琐"。当你用标准库把底层原理理解透彻之后,HAL库和CubeMX就是提效工具——它们能帮你自动生成初始化代码,让你把精力集中在业务逻辑上。但注意:不要一上来就用CubeMX,否则你根本不知道它生成的代码在干什么,出了问题也调不了。
学习这件事,真的就是"看一遍会忘,做一遍会懂,教一遍才会"。希望这篇博客能帮助到和我一样正在入门STM32的小伙伴,也欢迎大家把做项目过程中遇到的问题分享出来,咱们一起踩坑一起进步!
我们的STM32入门专栏就更新到这里了,我以后还会更新关于嵌入式的更多学习笔记,欢迎关注,我们一起学习更多嵌入式知识。
如果本文对你有帮助,欢迎点赞 👍 收藏 ⭐ !有任何问题欢迎在评论区交流,一起学习进步!
💬互动时间:你目前学到哪个外设了?或者你已经做完什么项目了?欢迎在评论区分享你的学习进度和踩坑经历,这个评论区就当成咱们STM32学习互助小组吧!