1. GPIO输出控制LED闪烁
任务说明
本案例目标是在嵌入式Rust开发中,使用HAL(硬件抽象层)的GPIO输出功能,编写程序点亮开发板上的板载LED并保持常亮。以STM32F103系列蓝色药丸(Blue Pill)开发板为例,其板载LED连接在PC13引脚(低电平点亮)。你需要完成从创建工程到烧录验证的完整闭环。
硬件连接与引脚定义
Blue Pill板载LED的阳极通过限流电阻接3.3V,阴极接PC13引脚。因此向PC13输出低电平(false)时LED点亮,输出高电平(true)时熄灭。
工程配置
创建新工程并配置依赖。使用cargo new led_blink --bin创建二进制工程,然后在Cargo.toml中添加依赖:
[dependencies]
embedded-hal = "0.2.7"
nb = "1.1.0"
cortex-m = "0.7.7"
cortex-m-rt = "0.7.3"
panic-halt = "0.2.0"
stm32f1xx-hal = { version = "0.10.0", features = ["rt", "stm32f103"] }
[[bin]]
name = "led_blink"
path = "src/main.rs"
[profile.release]
opt-level = "s"
同时需要.cargo/config.toml指定目标与烧录器:
[build]
target = "thumbv7m-none-eabi"
[target.thumbv7m-none-eabi]
runner = "probe-run --chip STM32F103C8"
代码实现
在src/main.rs中编写完整程序。核心逻辑是:获取GPIO端口C的句柄,将PC13配置为推挽输出,然后持续输出低电平。
#![no_std]
#![no_main]
use panic_halt as _;
use stm32f1xx_hal::{
prelude::*,
pac,
gpio::GpioExt,
};
#[cortex_m_rt::entry]
fn main() -> ! {
// 获取外设访问权限
let dp = pac::Peripherals::take().unwrap();
let mut rcc = dp.RCC.constrain();
// 初始化GPIOC端口
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
// 将PC13配置为推挽输出,初始状态为高电平(LED熄灭)
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
led.set_high();
// 持续输出低电平,点亮LED
loop {
led.set_low(); // PC13 = 0 → LED点亮
}
}
编译与烧录
程序不依赖任何外部库,仅使用HAL提供的GPIO抽象。编译命令如下:
# 安装目标与工具(首次使用)
rustup target add thumbv7m-none-eabi
cargo install probe-run
# 编译
cargo build --release
# 烧录并运行(通过ST-Link连接)
cargo run --release
如果使用其他烧录器(如OpenOCD + ST-Link),可改用:
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c "program target/thumbv7m-none-eabi/release/led_blink verify reset exit"
验证方法
完成烧录后,观察开发板上的LED状态。判定标准:
- 程序烧录无错误,芯片正常启动;
- 板载LED(PC13)保持常亮,不闪烁、不熄灭;
- 使用万用表测量PC13引脚电压,应为低电平(接近0V)。
若LED不亮,检查以下可能原因:
- 烧录器连接是否正确,程序是否真正写入;
- 代码中
set_low()是否在循环内持续执行; - 开发板是否为Blue Pill标准版本(部分克隆板LED接法不同)。
满足上述条件即表示案例验证通过。本案例实现了GPIO数字输出的最小闭环:引脚配置→电平控制→硬件响应。