Microcontroller Peripherals
Configure GPIO, timers, SPI/I2C, and PWM on typical Cortex-M boards.
Busca en todas las páginas de la documentación
Configure GPIO, timers, SPI/I2C, and PWM on typical Cortex-M boards.
let mut led = gpioa.pa5.into_push_pull_output();
led.set_high().ok();
led.set_low().ok();When to reach for this: Any firmware that talks to LEDs, sensors, displays, or motors through MCU peripherals.
use cortex_m::asm::delay;
use stm32f4xx_hal as hal;
use hal::{pac, prelude::*};
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze();
let gpioa = dp.GPIOA.split();
let mut led = gpioa.pa5.into_push_pull_output();
let i2c = hal::i2c::I2c::new(
dp.I2C1,
gpioa.pa9.into_alternate_open_drain(),
gpioa.pa10.into_alternate_open_drain(),
400.kHz(),
&clocks,
);
loop {
led.set_high().unwrap();
delay(clocks.sysclk().raw() / 8);
led.set_low().unwrap();
delay(clocks.sysclk().raw() / 8);
let _ = i2c.write(0x48, &[0x00]);
}
}What this demonstrates:
| Peripheral | Typical use |
|---|---|
| GPIO | Digital I/O, chip selects |
| Timer | Delays, PWM, input capture |
| SPI | Flash, displays, RF modules |
| I2C | Sensors, EEPROM |
| USART | GPS, modems, debug serial |
| ADC | Analog sensors |
let mut pwm = timer.pwm_hz(pin, 1.kHz(), &clocks);
let mut channel = pwm.ch1;
channel.set_duty(percent);
channel.enable();let mut spi = Spi::new(dp.SPI1, (sck, miso, mosi), MODE_0, 8.MHz(), &clocks);
let mut buffer = [0u8; 4];
spi.transfer(&mut buffer, &[0x9f, 0, 0, 0]).ok();| Alternative | Use When | Don't Use When |
|---|---|---|
bitbang GPIO | Missing hardware peripheral | High-speed SPI needed |
| DMA + SPI | Large transfers | Tiny register reads |
| RTIC software PWM | No hardware PWM pins | Precise frequency required |
Open drain for I2C and shared buses. Push-pull for LEDs and fast GPIO.
Peripherals require pins set to AF mode via HAL into_alternate_* methods.
Wrong PLL settings make baud rates lie. Verify with logic analyzer.
Scan bus with write probes or use sensor default from datasheet.
defmt-rtt or serialport bridge preferred over println! in firmware.
Set sample time based on source impedance. Average readings for noise.
Pet watchdog in main loop or dedicated task. Reset on hang.
Stop peripherals and clocks between samples. Wake on interrupt or RTC.
One pin, one function. Planner spreadsheet prevents impossible routing.
Application code uses HAL. PAC only for missing HAL coverage or ISR register tweaks.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026