第2章:嵌入式系统基础——STM32微控制器介绍、开发环境搭建与GPIO/定时器
各位同学,欢迎来到嵌入式系统基础这一章。说实话,植保作业路径优化这件事,光有算法是不够的——你得让算法在硬件上跑起来。而STM32,就是我这些年做农业嵌入式项目最常用的平台。没有之一。
2.1 STM32微控制器:为什么选它?
STM32是意法半导体推出的32位ARM Cortex-M系列微控制器。你想想看,一个植保无人机或者农业机器人,需要同时处理GPS数据、控制电机、读取传感器、还要跑路径规划算法——8位单片机根本扛不住。STM32刚好填补了这个空白。
我个人习惯把STM32分成几个系列:
| 系列 | 内核 | 典型应用场景 | 我常用的型号 |
|---|---|---|---|
| F1系列 | Cortex-M3 | 基础控制、传感器采集 | STM32F103C8T6 |
| F4系列 | Cortex-M4 | 带DSP、浮点运算,适合路径计算 | STM32F407VGT6 |
| F7/H7系列 | Cortex-M7 | 高性能、多任务、实时性要求高 | STM32H743 |
| G0/G4系列 | Cortex-M0+/M4 | 低功耗、性价比高 | STM32G070 |
我在项目中遇到过一个问题:用F103做植保机器人的路径规划,结果算一个B样条曲线要卡顿好几秒。后来换成F407,带硬件浮点单元,速度直接提升了5倍。所以选型这事,别省。
核心要点:STM32的优势在于——丰富的外设(GPIO、定时器、ADC、DMA、CAN、I2C、SPI)、成熟的生态(HAL库、LL库、FreeRTOS)、以及极高的性价比。一块F103开发板才几十块钱,但能干的事远超你的想象。
2.2 开发环境搭建:Keil + CubeMX
搭建开发环境,说白了就是三件事:装软件、配工具、跑通第一个程序。我建议你按这个顺序来。
2.2.1 安装Keil MDK
Keil MDK是ARM公司出的IDE,专门用来开发STM32。去官网下载MDK-ARM版本,安装时注意勾选上对应的器件包(Device Family Pack)。
嗯,这里要注意:Keil的License需要购买,但你可以先用评估版(限制代码大小)。我个人建议学生党先用评估版,等真正做项目了再买正版。
2.2.2 安装STM32CubeMX
CubeMX是ST官方出的图形化配置工具。你可以在里面选芯片型号、配置时钟树、设置GPIO、定时器、串口等外设,然后自动生成初始化代码。
我曾经犯过一个低级错误:手动配置时钟树,结果把系统时钟配错了,芯片直接跑不起来。后来老老实实用CubeMX生成,再也没出过问题。所以我的建议是——能用工具生成的,别手写。
2.2.3 第一个工程:点亮LED
咱们来写一个最简单的程序——点亮板子上的LED。这就像学编程的"Hello World"。
步骤是这样的:
- 打开CubeMX,选择芯片型号(比如STM32F103C8)
- 在Pinout视图中,找到PC13引脚(这是LED对应的引脚)
- 设置为GPIO_Output
- 配置时钟:HSE 8MHz,系统时钟72MHz
- 生成代码(选择MDK-ARM)
- 在Keil中打开工程,在main.c里写代码
// main.c 中的主循环
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500); // 延时500ms
}
}
编译、下载、运行。如果LED以1秒的频率闪烁,恭喜你,环境搭建成功了。
小技巧:下载程序时如果提示找不到芯片,检查一下Boot0引脚是否接地。我刚开始学的时候,这个问题卡了我一整天。
2.3 GPIO:控制一切的基础
GPIO,全称General Purpose Input Output,通用输入输出口。说白了,就是芯片的"手脚"——你可以让它输出高电平或低电平,也可以读取外部信号是高还是低。
在STM32中,GPIO有8种工作模式。但咱们做植保机器人,常用的就这几种:
- 推挽输出(Push-Pull):驱动LED、继电器、电机使能信号
- 开漏输出(Open-Drain):I2C总线、电平转换
- 浮空输入(Floating):读取按键、传感器数字信号
- 上拉/下拉输入:防止引脚悬空,读取稳定的电平
我记得有一次做植保机器人的避障传感器,用的是红外对管。传感器输出信号不稳定,老是误触发。后来发现是GPIO没配置内部上拉,引脚悬空了。加上上拉电阻后,问题解决。
避坑指南:我曾经在项目中直接把5V信号接到3.3V的STM32引脚上,结果烧了一个IO口。STM32的GPIO耐压是3.3V,绝对不能直接接5V!需要用电平转换芯片或者分压电阻。
2.4 定时器:精准控制时间的利器
定时器,是嵌入式系统里最常用的外设之一。没有定时器,你连一个精确的延时都做不了。
STM32的定时器分三类:
- 基本定时器(TIM6/TIM7):只能计时,没有外部引脚
- 通用定时器(TIM2-TIM5):有输入捕获、输出比较、PWM等功能
- 高级定时器(TIM1/TIM8):功能最全,支持互补PWM、刹车输入等
在植保作业中,定时器最常见的用途有两个:
第一,产生PWM波控制电机。比如控制无刷电调或者舵机,就是靠改变PWM的占空比来实现的。
// 配置TIM2输出PWM,频率50Hz,占空比可调
void MX_TIM2_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 72 - 1; // 72MHz / 72 = 1MHz
htim2.Init.Period = 20000 - 1; // 1MHz / 20000 = 50Hz
HAL_TIM_PWM_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1500; // 1.5ms 脉宽(舵机中位)
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}
第二,做定时中断。比如每10ms采集一次GPS数据,每100ms更新一次路径点。这些周期性任务,用定时器中断最合适。
// 定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
// 每10ms执行一次
Read_GPS_Data();
Update_Path_Point();
}
}
你想想看,如果没有定时器,你只能用HAL_Delay()来延时。但Delay是阻塞的,CPU啥也干不了。用定时器中断,CPU可以一边处理其他任务,一边等定时器"叫醒"它。
核心要点:定时器的精髓在于——不占用CPU资源,精准触发。在植保机器人这种需要同时处理多个任务的场景下,定时器是必不可少的。
2.5 本章小结
这一章我们讲了STM32的基本概念、开发环境的搭建、GPIO的使用、以及定时器的配置。说实话,这些东西看起来零散,但它们是嵌入式开发的"基本功"。就像盖房子,地基打不好,后面再漂亮的算法也跑不起来。
下一章,我们会开始讲传感器数据采集——GPS、IMU、超声波这些植保机器人常用的传感器,怎么跟STM32对接。到时候你会发现,有了GPIO和定时器的基础,一切都顺理成章。
好,今天就到这里。有问题随时交流。
公众号:蓝海资料掘金营,微信deep3321