第1章:单片机基础与开发环境搭建
各位同学,咱们今天聊聊单片机。说实话,我做了十几年嵌入式开发,单片机这东西就像老朋友一样熟悉。你想想看,从智能家电到工业控制,从无人机到医疗器械,到处都有它的影子。这一章,我们就以STM32为例,把单片机的基础知识和开发环境搭建讲透。
1.1 单片机内部结构:内核、存储器、外设
单片机说白了就是一个微型计算机。它把CPU、内存、各种外设接口都集成在一个芯片里。我刚开始学的时候,总觉得这东西很神秘,后来拆了几颗芯片,看了内部框图,才恍然大悟——原来就这么回事。
1.1.1 内核(Core)
STM32的内核基于ARM Cortex-M系列。以最常见的STM32F103为例,它用的是Cortex-M3内核。这个内核的特点我总结一下:
- 32位RISC架构:一次能处理32位数据,效率高
- 三级流水线:取指、译码、执行,流水线操作
- Thumb-2指令集:16位和32位指令混编,代码密度高
- 嵌套向量中断控制器(NVIC):支持最多240个中断,优先级可配置
核心提示:我在项目中遇到过一个问题——中断响应太慢。后来发现是NVIC优先级配置没弄对。记住,高优先级中断可以打断低优先级,但同优先级不能互相打断。这个坑我踩过,你们别重蹈覆辙。
1.1.2 存储器(Memory)
STM32的存储器分为三块:Flash、SRAM、系统存储器。我画个图给你们看:
嗯,这里要注意:Flash的擦写次数有限,一般10万次左右。我有个同事在调试时频繁下载程序,结果把Flash写坏了。所以调试阶段尽量用RAM运行,或者用仿真器在线调试。
1.1.3 外设(Peripherals)
STM32的外设非常丰富。我个人习惯把它们分成三类:
| 外设类别 | 典型外设 | 用途 |
|---|---|---|
| 通信接口 | USART、SPI、I2C、CAN、USB | 与其他设备交换数据 |
| 模拟外设 | ADC、DAC、比较器 | 处理模拟信号 |
| 定时/控制 | 定时器、PWM、看门狗 | 产生时序、控制电机 |
个人经验:选型时别贪多。我见过有人选了个外设超多的芯片,结果大部分引脚都悬空。够用就好,省钱省空间。
1.2 单片机开发流程
开发一个单片机项目,流程其实挺固定的。我把它总结成6步:
- 需求分析:搞清楚要做什么,输入输出是什么
- 芯片选型:根据需求选合适的STM32型号
- 硬件设计:画原理图、PCB,打样焊接
- 软件开发:写代码、调试、烧录
- 系统联调:软硬件一起跑,找bug
- 测试验证:功能测试、可靠性测试
你想想看,这6步里哪步最容易出问题?我个人觉得是第4步——软件开发。硬件问题往往一眼就能看出来,软件bug有时候藏得很深。我曾经花了一周时间找一个定时器配置错误,最后发现是预分频系数算错了。嗯,从那以后我写代码都先画流程图。
1.3 开发环境安装与配置
开发STM32,主流工具有两个:Keil MDK和STM32CubeIDE。我两个都用过,说说我的感受。
1.3.1 Keil MDK安装
Keil是老牌工具,稳定可靠。安装步骤:
- 去ARM官网下载MDK-ARM安装包
- 运行安装程序,一路Next
- 安装完成后,打开Pack Installer
- 搜索你的芯片型号(比如STM32F103C8)并安装对应的Pack
注意:Keil的License需要购买,但可以申请评估版(32KB代码限制)。如果你只是学学,评估版够用了。我当年就是拿评估版入的门。
1.3.2 STM32CubeIDE安装
STM32CubeIDE是ST官方出的免费IDE,基于Eclipse。我个人更推荐新手用这个,因为:
- 完全免费,没有代码限制
- 集成了CubeMX,图形化配置外设
- 自带编译器,不用额外装
安装很简单:去ST官网下载安装包,双击安装,选好安装路径,等几分钟就好了。我第一次用的时候,发现它自动识别了我的ST-Link调试器,省了不少事。
1.4 第一个单片机工程:点亮LED
好了,理论说完了,咱们动手。点亮LED是嵌入式界的"Hello World"。我带你走一遍流程。
1.4.1 硬件连接
假设我们用STM32F103C8T6最小系统板,LED接在PC13引脚(很多开发板板载LED就是这个引脚)。电路很简单:
- LED正极接PC13
- LED负极串联一个220Ω电阻到GND
1.4.2 代码实现
在STM32CubeIDE中新建工程,选好芯片型号。然后写代码:
#include "stm32f1xx_hal.h"
void LED_Init(void)
{
__HAL_RCC_GPIOC_CLK_ENABLE(); // 使能GPIOC时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
int main(void)
{
HAL_Init();
LED_Init();
while(1)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 点亮
HAL_Delay(500); // 延时500ms
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 熄灭
HAL_Delay(500);
}
}
关键点:记得使能时钟!STM32的外设时钟默认是关闭的。我刚开始学的时候,忘了开时钟,折腾了半天LED就是不亮。后来查手册才发现这个坑。
1.4.3 编译下载
代码写好后,点击编译按钮(锤子图标)。如果没报错,就连接ST-Link,点击下载按钮。下载成功后,你会看到LED开始闪烁。
我第一次点亮LED的时候,心里那个激动啊。虽然只是个小灯,但意味着你真正开始控制硬件了。这种感觉,嗯,很奇妙。
调试技巧:如果LED不亮,先检查硬件连接,再用万用表测引脚电压。PC13输出低电平时,电压应该是0V左右;输出高电平时,应该是3.3V。如果电压正常但灯不亮,那就是电路问题。
好了,这一章的内容就到这里。单片机开发其实不难,关键是多动手。下一章我们会深入GPIO的细节,到时候再聊。