2、STM32基础回顾:掌握STM32的GPIO、定时器、中断、PWM、串口等核心外设的基本编程方法

在构建避障机器人之前,我们必须先夯实STM32微控制器的基础编程能力。避障机器人的核心逻辑——读取超声波/ToF传感器数据、控制电机转速、处理紧急刹车信号——全部依赖于对GPIO、定时器、中断、PWM和串口这五大外设的熟练运用。本章将系统回顾这些外设的工作原理、寄存器操作与HAL库编程方法,并特别针对避障场景中的“传感器触发-数据采集-电机响应”链路进行针对性讲解。请务必在开发板上同步练习,因为后续章节的所有算法都将构建在这些基础代码之上。

STM32避障机器人核心外设链路图 STM32F103/F407 ARM Cortex-M3/M4 72MHz~168MHz GPIO输入 超声波Trig/Echo ToF I2C中断 外部中断EXTI 紧急避障信号 碰撞检测 定时器输入捕获 超声波Echo脉宽 ToF测距触发 PWM输出 电机速度控制 舵机转向控制 GPIO输出 电机方向控制 LED状态指示 串口UART 调试日志输出 上位机通信 数据流:传感器信号 → 定时器/中断采集 → 算法决策 → PWM/GPIO执行 SWD调试

上图展示了避障机器人中STM32核心外设的工程链路。左侧为输入类外设(GPIO、EXTI、定时器捕获),右侧为输出类外设(PWM、GPIO、UART),中央为MCU决策核心。在实际项目中,这些外设并非孤立工作,而是通过中断服务函数和定时器时基形成紧密的协同关系。例如,超声波测距需要GPIO输出触发脉冲,定时器捕获回波脉宽,计算出的距离再通过串口输出调试信息,最终由PWM调整电机转速。理解这条链路是掌握本章内容的关键。

2.1 核心原理:五大外设的工作机制与避障角色

STM32的外设编程本质是“配置寄存器-使能时钟-初始化结构体-调用HAL库函数”的流程。在避障机器人中,每个外设承担明确职责:GPIO负责数字信号的输入输出,如超声波模块的Trig引脚(输出10μs高电平触发)和Echo引脚(输入回波电平);定时器提供时基和输入捕获功能,用于测量Echo高电平持续时间(即声波往返时间);中断(EXTI)用于紧急事件响应,如碰撞开关触发时立即停车;PWM通过调节占空比控制直流电机转速或舵机角度;串口(UART)则用于向PC端发送距离数据和调试信息。

外设避障机器人中的角色关键参数典型引脚
GPIO传感器触发、方向控制推挽输出/上拉输入PA0-PA15, PB0-PB15
定时器超声波脉宽测量、系统时基预分频器、自动重载值TIM2-TIM5(通用)
EXTI中断碰撞检测、紧急停车上升沿/下降沿触发PA0(EXTI0)
PWM电机调速、舵机控制频率20kHz,占空比0-100%PA8(TIM1_CH1)
UART调试信息输出、上位机通信115200-8-N-1PA9(TX), PA10(RX)

2.2 操作流程:从CubeMX配置到HAL库编程

推荐使用STM32CubeMX进行图形化初始化配置,再在Keil/STM32CubeIDE中编写业务逻辑。标准流程如下:

  1. 时钟树配置:将系统时钟设置为最高频率(如F103为72MHz),确保定时器时基准确。
  2. GPIO配置:将Trig引脚设为推挽输出,Echo引脚设为上拉输入;电机方向引脚设为推挽输出。
  3. 定时器配置:选择通用定时器(如TIM3),设置预分频器(PSC=71)和自动重载值(ARR=65535),使计数频率为1MHz,实现微秒级测量。
  4. PWM配置:选择TIM1的CH1通道,设置PWM频率为20kHz(PSC=3, ARR=899),初始占空比为0%。
  5. 串口配置:设置波特率115200,数据位8,停止位1,无校验。
  6. 中断配置:使能EXTI线0(对应PA0),选择上升沿和下降沿触发。

完成配置后,CubeMX会生成初始化代码。在main.c中,我们只需调用HAL库函数即可实现功能。例如,超声波触发代码为:

// 触发超声波模块
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);
delay_us(10);  // 延时10微秒
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);

2.3 案例拆解:超声波测距的完整外设协同

我们以HC-SR04超声波模块为例,演示GPIO、定时器、中断和串口的综合应用。硬件连接:Trig→PA0,Echo→PA1,VCC→5V,GND→GND。目标:每100ms测量一次距离,并通过串口输出。

关键实现步骤:

  1. 初始化PA0为推挽输出,PA1为上拉输入。
  2. 配置TIM3为输入捕获模式,通道1映射到PA1,预分频器设为71(1MHz计数频率)。
  3. 在while循环中:拉高Trig 10μs→拉低→等待Echo上升沿→记录捕获值→等待下降沿→计算脉宽。
  4. 距离计算公式:distance_cm = (pulse_width_us * 0.034) / 2。
  5. 通过串口发送:printf("Distance: %.1f cm\r\n", distance_cm);

实际测试中,我们发现当障碍物距离小于10cm时,Echo信号可能因反射衰减而丢失。解决方案是设置定时器捕获超时(如50ms),若超时则判定为“无有效回波”。此外,连续测量间隔应大于60ms,避免超声波余振干扰。

工程经验:在避障机器人中,超声波测距频率不宜过高。建议控制在10-20Hz(即50-100ms间隔),既能保证实时性,又能避免多传感器串扰。若使用多个超声波模块,应错开触发时间。

2.4 常见误区与总结复盘

初学者在STM32外设编程中常犯以下错误:

  • 忘记使能GPIO时钟:在HAL库中,__HAL_RCC_GPIOA_CLK_ENABLE()必须首先执行,否则寄存器写入无效。
  • 中断优先级配置不当:避障机器人的碰撞中断应设为最高优先级(抢占优先级0),确保紧急停车不被其他中断打断。
  • PWM频率选择错误:电机驱动频率应大于15kHz以避免 audible noise,但过高(>50kHz)会增加MOS管开关损耗。
  • 串口发送阻塞:使用HAL_UART_Transmit时,若未检查状态标志,可能导致程序卡死。建议使用中断或DMA方式发送调试数据。
  • 定时器溢出未处理:当测量脉宽超过定时器最大计数值时,应启用更新中断并记录溢出次数。

总结复盘:本章的核心是建立“外设服务于系统”的思维。GPIO是数字世界的“手”,定时器是“时钟”,中断是“警报器”,PWM是“调速器”,串口是“眼睛”。在后续章节中,我们将基于这些基础外设构建完整的避障算法。建议读者在开发板上完成以下练习:使用按键触发LED翻转(GPIO+EXTI)、输出可调占空比的PWM驱动LED亮度变化、通过串口回显超声波测距数据。这些练习将直接为第4章的“风险分级决策”打下基础。

风险提示:在连接电机驱动板时,务必确认STM32的GPIO输出电压(3.3V)与驱动板逻辑电平兼容。若驱动板需要5V逻辑,需加电平转换电路,否则可能损坏MCU引脚。