别再把 STM32F103C8T6 当成嵌入式入门的终点了
简历里一写单片机项目,十个人里有八个是 STM32F103C8T6。
再往下问,还是点灯、串口、中断、PWM、OLED、DS18B20、超声波、循迹小车那一套。
这套东西能不能学?当然能学。
问题不在于你学了 F103C8T6,而在于很多人学完之后,以为自己已经“会 STM32 了”,然后就停住了。
真到了面试里,面试官想看的不是你会不会点灯,而是你有没有从“会调用 HAL”走到“理解 MCU 系统”。
说得直接一点,STM32F103C8T6 可以当起点,但绝对不能当终点。
先说结论:F103 适合入门,但不适合长期停留
STM32F103C8T6 的价值主要有三个:
- 资料多,环境成熟,适合快速上手
- 外设典型,能把 GPIO、UART、SPI、I2C、TIM、中断这些基础外设串起来
- 成本低,适合做入门练手板
但它的问题也很明显:
- 项目同质化严重,简历辨识度很低
- 很多人只会“照着例程改”,没有形成系统理解
- 它覆盖不了现在很多面试更关注的内容,比如
RTOS、DMA、Cache、MPU、多总线架构、复杂驱动调试 - 只停留在 F1,容易形成一种错觉:嵌入式就是配外设、调串口、写 while(1)
如果你只是想完成一门课设,F103 足够。
如果你想找工作,尤其是想往嵌入式开发、驱动开发、底层软件、MCU 软件工程这个方向走,只会 F103 明显不够。
嵌入式大厂面试题,基础八股文资料合集整理:
https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk
面试官真正想看什么
很多同学觉得自己学的是 STM32,结果面试官一问就暴露出问题。
因为面试官真正关注的,从来不是“你点没点亮过 LED”,而是下面这些能力。
1. 你对 MCU 的理解是不是停留在“外设调用”
比如他会顺着问:
- 启动文件做了什么
- 中断向量表是什么
main函数之前程序做了什么- 堆和栈怎么分配
volatile为什么要加- 中断里为什么不建议做太重的事
- DMA 和中断各适合什么场景
这些问题和“点灯”没有直接关系,但都和“你到底懂不懂单片机软件”有关系。
2. 你有没有接触真实一点的工程问题
比如:
- 串口丢包怎么定位
- I2C 挂死总线怎么办
- SPI 从机时序错了怎么抓
- 定时器抖动怎么分析
- FreeRTOS 任务切换开销和优先级反转怎么理解
- DMA 缓冲区为什么有时读不到最新数据
- 为什么 H7 上做 DMA 要关注 D-Cache 一致性
这些问题,才是面试官判断你有没有工程感的关键。
3. 你是不是只会“背库函数”
很多人一问 STM32,就是:
HAL_GPIO_WritePinHAL_UART_TransmitHAL_Delay
但只会这些,说明你只是会用接口。
面试官更想看的是你知不知道这些接口背后在操作什么:
- GPIO 模式怎么映射到寄存器
- 波特率怎么计算
- NVIC 优先级分组怎么影响中断响应
- 定时器预分频和自动重装值怎么决定输出周期
- DMA 的搬运单位、地址自增、循环模式分别有什么意义
这才是“会用”和“会做”之间的区别。
只学 F103 的人,通常卡在哪一层
第一层:能跑例程
这个阶段的特征很明显:
- 会用 CubeMX
- 会生成工程
- 会点灯
- 会串口打印
- 会接几个模块
- 会照着博客改代码
这个阶段不能说没用,但它只是“能入门”,离“能面试”差得还很远。
第二层:能写一些完整小项目
比如:
- 温湿度采集
- 智能小车
- 简单数据上传
- 多传感器采集显示
- PWM 控制电机
- ADC 采样加滤波
到这一层,已经比只会点灯好很多了。
但问题是,如果这些项目的实现方式还是“模块拼接”,没有调试过程、没有架构思考、没有异常处理,那面试含金量还是有限。
第三层:开始理解系统
到了这一层,关注点就变了。
你不再只关心“功能有没有实现”,而开始关心:
- 为什么这样初始化
- 为什么这个中断优先级这么配
- 为什么 DMA 比轮询更合适
- 为什么数据偶发错误
- 为什么这个变量必须加
volatile - 为什么任务切换后延迟不稳定
- 为什么这块内存不适合给 DMA 用
这时候你才算真正进入嵌入式开发的门。
如果不想只停在 F103,后面该学什么
不是说必须一步跳到特别难,而是要把学习路线往“工程化”推进。
1. 把外设从“会用”学到“会分析”
还是那些基础外设,但要求变了。
你不能只知道怎么初始化,还得知道原理、关键寄存器、常见问题。
比如串口,至少要能说清:
- 异步通信基本格式
- 波特率误差影响
- 中断接收和 DMA 接收的区别
- 空闲中断在不定长接收里的作用
- 为什么串口打印多了会卡系统
比如定时器,至少要能说清:
- 预分频和计数周期关系
- 输入捕获和输出比较区别
- PWM 频率和占空比怎么来的
- 定时器中断为什么会抖动
这些都是典型八股,但也是最容易从项目里延展开的内容。
2. 学 RTOS,而不是一直裸机 super loop
如果你的项目还一直停留在:
while(1)
{
key_scan();
oled_refresh();
uart_send();
sensor_read();
}
那说明你还没真正碰到任务调度问题。
RTOS 不只是“多任务更高级”,它更重要的意义是让你开始理解:
- 任务切换
- 优先级调度
- 临界区
- 信号量
- 互斥锁
- 队列
- 事件组
- 软件定时器
这些东西一旦进入面试,就比“我做过一个温湿度采集系统”更有区分度。
面试里常见的八股包括:
- 任务和线程的区别
- 互斥锁和信号量的区别
- 什么是优先级反转,怎么解决
- FreeRTOS 的堆有哪几种实现方式
- 中断里为什么不能随便调用阻塞 API
- 任务栈过小会出现什么问题
这些内容,已经开始接近“公司真正会问”的范围了。
3. 学 DMA、总线、内存,而不是只学外设现象
很多人学 STM32,只学到了“外设层”。
再往上一点,其实是“数据怎么流动”。
比如:
- ADC 采样结果怎么高效搬到内存
- UART 连续接收怎么避免 CPU 一直进中断
- SPI 大数据量传输为什么更适合 DMA
- 不同内存区域为什么访问速度不一样
- 为什么某些内存能给 DMA 用,某些不适合
如果你开始接触 F4、H7、RT1052 这类平台,就会明显感受到:
嵌入式不是“点灯 + 外设”,而是“CPU、总线、内存、外设、实时性”的综合系统。
这也是为什么很多人一上 H7 就懵。
以前在 F103 上没碰到过 Cache、MPU、AXI SRAM、DTCM,现在一来全是坑。
4. 学调试,而不是只学“代码能跑”
真正能拉开差距的,往往不是你写了多少代码,而是你会不会查问题。
比如这些场景:
- 串口乱码,是时钟问题、波特率问题,还是接地问题
- I2C 没响应,是上拉不对、地址错了,还是总线被拉死
- 程序 HardFault,是栈溢出、野指针,还是非法访问
- DMA 数据错乱,是配置问题,还是 Cache 一致性问题
- 中断不进,是 NVIC 没开、标志位没清,还是向量表有问题
会调试,才说明你接近工程。
只会跟着教程敲,通常一脱离现成例程就走不动。
嵌入式八股不是没用,问题是你别只会背
很多人排斥八股,觉得八股没意义。
实际上,八股本身不是问题,问题在于你背了但不会用。
真正有效的八股,应该满足两个条件:
- 你能解释原理
- 你能结合项目说出场景
举几个最常见的例子。
1. volatile 是什么,为什么要用
标准回答一般是:
volatile 用来告诉编译器,这个变量的值可能在程序控制流之外被改变,因此每次使用都要重新从内存读取,不能随意优化。
但如果你只背这句话,意义不大。
更好的回答应该能接上场景:
- 中断里修改、主循环里读取的变量要加
volatile - 硬件寄存器映射变量通常要加
volatile - 多任务共享变量在特定场景也要注意编译器优化问题
再进一步,面试官可能会追问:
volatile能保证原子性吗volatile能代替锁吗
答案当然是不能。
它解决的是“可见性和优化问题”,不解决“竞态和互斥问题”。
2. 中断和轮询有什么区别
标准回答:
- 轮询是 CPU 主动不断检查事件状态
- 中断是事件发生后通知 CPU 响应
但面试里不会停在这里。
更重要的是继续往下说:
- 轮询实现简单,但浪费 CPU
- 中断实时性更好,但频繁中断会增加系统开销
- 高速数据流场景下,单靠中断可能也不够,这时更适合 DMA
这就把“八股”接到了“工程选择”。
3. DMA 的作用是什么
很多人的回答只有一句:DMA 可以减少 CPU 干预。
这句话对,但太浅。
更完整一点应该是:
- DMA 可以在外设和内存、内存和内存之间搬运数据
- CPU 不必逐字节参与,提高效率
- 特别适合大批量、重复性、高速数据搬运场景
- 常见于 UART、SPI、ADC、DAC、SDIO、摄像头接口等
再往下还可以继续:
- DMA 和中断怎么配合
- 循环模式适合什么场景
- 双缓冲有什么意义
- H7 上 DMA 为什么还要考虑 Cache 一致性
这就不是死背了,而是能展开。
4. 堆和栈的区别
这是非常经典的八股。
如果你只答“栈由系统分配,堆由程序员申请释放”,那只是及格线。
更像样一点应该包括:
- 栈通常用于函数调用现场、局部变量、返回地址保存
- 分配释放速度快,由编译器和运行时自动管理
- 空间通常较小,容易栈溢出
- 堆用于动态内存分配,生命周期更灵活
- 容易产生碎片,嵌入式里很多场景会谨慎使用
如果面试再深入一点,还可能继续问:
- FreeRTOS 任务栈和系统栈有什么关系
- 为什么有些嵌入式项目尽量少用
malloc - 内存碎片会带来什么问题
5. 为什么中断里不建议做复杂操作
这个问题也非常常见。
一个完整回答应该包括:
- 中断执行期间会打断正常任务流
- 中断里做太多事会拉长响应时间
- 可能影响更高优先级中断的及时响应
- 会导致系统实时性变差
- 某些阻塞操作在中断里根本不适合执行
工程里更常见的做法是:
- 中断里只做快速处理
- 设置标志位、读寄存器、搬少量关键数据
- 复杂逻辑放到主循环或任务中处理
这就是“八股 + 实战”的结合。
如果你现在还在学 F103,怎么把它学出价值
不是说你现在学 F103 就晚了。
关键在于你怎么学。
第一,不要只做功能,开始记录问题
你做串口接收,不要只写“实现了串口收发”。
要写清楚:
- 一开始遇到过什么问题
- 为什么会丢数据
- 后来为什么改成中断或 DMA
- 缓冲区怎么设计
- 如何判断一帧数据结束
这些才是项目里最值钱的内容。
第二,不要只会 HAL,要知道底层发生了什么
至少对你常用的外设,要能说出:
- 关键寄存器做什么
- 初始化本质在配什么
- 中断标志怎么来的
- 数据是怎么搬运的
你不一定非得全手写寄存器,但不能只会点图形界面。
第三,尽快往更完整的平台过渡
可以继续往这些方向走:
STM32F4:学更完整的定时器、DMA、性能差异STM32H7:学 Cache、MPU、复杂内存架构FreeRTOS:学任务调度和资源管理- Linux 驱动基础:学设备树、字符设备、总线模型
- 常见协议栈:学 CAN、Modbus、TCP/IP、USB 基础
这样你在简历上写出来,就不再是“标准模板化 STM32 项目”了。
面试官视角下,什么样的 STM32 项目更有含金量
真正有区分度的项目,通常有下面几个特征:
- 不只是外设堆砌,而是有明确系统设计
- 有实时性要求,涉及中断、DMA、任务调度
- 有问题定位和优化过程
- 能解释架构选择,而不是“教程里就是这么写的”
- 能从项目里自然延伸出八股问题
比如下面两种描述,含金量差别就很大。
第一种:
- 使用 STM32F103 实现温湿度采集,并通过串口上传上位机显示
第二种:
- 基于 STM32 实现传感器采集与串口通信模块,采用定时器驱动周期采样,串口接收使用中断/环形缓冲区处理不定长数据,针对主循环阻塞导致的数据丢失问题进行了通信链路重构,并分析了轮询、中断、DMA 三种方案的适用边界
后者不一定项目更难,但表达出来就明显更像做过事的人。
最后说一句实在话
STM32F103C8T6 当然可以学。
但如果你学来学去,永远都停在点灯、串口、OLED、小车、传感器拼接,那你很容易在面试里被归类成“做过一点单片机实验”。
真正能拉开差距的,不是你板子换了多少块,而是你有没有从“会做实验”走到“理解系统”,有没有从“会调库函数”走到“能解释原理、能定位问题、能回答追问”。
F103 可以是起点。
但如果你想找工作,尤其是想让自己的嵌入式能力在面试里真正站得住,最好别把它当终点。
高频面试题
volatile的作用是什么,能保证线程安全吗- 中断和轮询的区别是什么
- 为什么中断里不建议做复杂操作
- DMA 的工作原理是什么
- DMA 和中断分别适用于什么场景
- 串口接收为什么常用中断或 DMA
- 环形缓冲区有什么作用
- 堆和栈的区别是什么
static的作用有哪些- STM32 启动流程是怎样的
- 中断向量表是什么
- NVIC 的作用是什么
- 定时器预分频和自动重装值怎么计算
- PWM 的频率和占空比怎么确定
- I2C 为什么要上拉
- SPI 的四种模式怎么理解
- FreeRTOS 中任务、队列、信号量分别是什么
- 什么是优先级反转,怎么解决
- H7 上为什么 DMA 要考虑 D-Cache 一致性
- MPU 的作用是什么,为什么 DMA 缓冲区常配置成 Non-Cacheable

