Embassy实战:Rust嵌入式异步开发指南

发布于:2025-07-24 ⋅ 阅读:(15) ⋅ 点赞:(0)

嵌入式异步框架 Embassy 实例

以下是关于嵌入式异步框架 Embassy 的实用示例,涵盖常见外设操作、多任务协作和硬件交互场景。示例基于STM32和Raspberry Pi Pico等平台,使用Rust语言编写。

GPIO 控制

use embassy_stm32::gpio::{Input, Output, Pull, Speed};
use embassy_stm32::peripherals::PA5;

// 配置GPIO输出
async fn blink_led(pin: PA5) {
    let mut led = Output::new(pin, Speed::Low);
    loop {
        led.set_high();
        embassy_time::Timer::after_secs(1).await;
        led.set_low();
        embassy_time::Timer::after_secs(1).await;
    }
}

中断处理

use embassy_stm32::exti::ExtiInput;
use embassy_stm32::gpio::Input;

// 配置外部中断
async fn button_interrupt(pin: impl Peripheral<P = impl InputPin>) {
    let button = Input::new(pin, Pull::Up);
    let mut exti = ExtiInput::new(button, EXTI0);
    loop {
        exti.wait_for_falling_edge().await;
        defmt::println!("Button pressed!");
    }
}

串口通信

use embassy_stm32::usart::{Uart, Config};
use embassy_stm32::peripherals::USART1;

// 异步串口回显
async fn uart_echo(usart: USART1, tx: impl Pin, rx: impl Pin) {
    let mut uart = Uart::new(usart, tx, rx, Config::default());
    let mut buf = [0; 8];
    loop {
        uart.read(&mut buf).await.unwrap();
        uart.write(&buf).await.unwrap();
    }
}

定时器PWM输出

use embassy_stm32::pwm::Pwm;
use embassy_stm32::time::hz;

// 配置PWM输出
async fn pwm_control(tim: impl Peripheral<P = impl PwmPin>) {
    let mut pwm = Pwm::new(tim, hz(1000));
    pwm.set_max_duty(1000);
    loop {
        for duty in 0..=1000 {
            pwm.set_duty(duty);
            embassy_time::Timer::after_millis(10).await;
        }
    }
}

SPI 数据传输

use embassy_stm32::spi::Spi;
use embassy_stm32::peripherals::SPI1;

// SPI读取传感器数据
async fn read_spi_sensor(spi: SPI1, sck: impl Pin, mosi: impl Pin, miso: impl Pin) {
    let mut spi = Spi::new(spi, sck, mosi, miso, Config::default());
    let mut buf = [0; 2];
    loop {
        spi.transfer(&mut buf).await.unwrap();
        defmt::println!("Sensor value: {}", buf[0] as u16 | ((buf[1] as u16) << 8));
        embassy_time::Timer::after_secs(1).await;
    }
}

I2C 设备访问

use embassy_stm32::i2c::I2c;
use embassy_stm32::peripherals::I2C1;

// I2C读取温湿度传感器
async fn read_i2c_sensor(i2c: I2C1, sda: impl Pin, scl: impl Pin) {
    let mut i2c = I2c::new(i2c, scl, sda, Config::default());
    let mut buf = [0; 4];
    loop {
        i2c.write_read(0x40, &[0xE3], &mut buf).await.unwrap();
        defmt::println!("Temperature: {}", f32::from_be_bytes(buf));
        embassy_time::Timer::after_secs(2).await;
    }
}

多任务协作

use embassy_executor::Spawner;

// 启动并发任务
#[embassy_executor::main]
async fn main(spawner: Spawner) {
    spawner.spawn(blink_led()).unwrap();
    spawner.spawn(button_interrupt()).unwrap();
    spawner.spawn(uart_echo()).unwrap();
}

看门狗配置

use embassy_stm32::wdg::IndependentWatchdog;

// 初始化独立看门狗
async fn init_watchdog() {
    let mut wdt = IndependentWatchdog::new(IWDG, 2_000_000);
    wdt.start();
    loop {
        wdt.pet();
        embassy_time::Timer::after_secs(1).await;
    }
}

DMA 数据传输

use embassy_stm32::dma::NoDma;
use embassy_stm32::usart::UartTx;

// 使用DMA的串口发送
async fn dma_uart_send(usart: USART1, tx: impl Pin, dma: impl Peripheral) {
    let mut uart = UartTx::new(usart, tx, NoDma, Config::default());
    let data = b"Hello DMA!\r\n";
    loop {
        uart.write(&data).await.unwrap();
        embassy_time::Timer::after_secs(1).await;
    }
}

ADC 采样

use embassy_stm32::adc::Adc;
use embassy_stm32::peripherals::ADC1;

// 多通道ADC采样
async fn read_adc(adc: ADC1, pin1: impl Pin, pin2: impl Pin) {
    let mut adc = Adc::new(adc, &mut Delay);
    let mut ch1 = adc.enable_pin(pin1);
    let mut ch2 = adc.enable_pin(pin2);
    loop {
        let v1 = adc.read(&mut ch1).await.unwrap();
        let v2 = adc.read(&mut ch2).await.unwrap();
        defmt::println!("ADC1: {}, ADC2: {}", v1, v2);
        embassy_time::Timer::after_millis(500).await;
    }
}

定时器编码器模式

use embassy_stm32::timer::Encoder;

// 读取编码器值
async fn read_encoder(tim: impl TimerWithEncoder) {
    let mut enc = Encoder::new(tim);
    loop {
        let count = enc.read_count();
        defmt::println!("Encoder: {}", count);
        embassy_time::Timer::after_millis(100).await;
    }
}

USB CDC 虚拟串口

use embassy_stm32::usb::Driver;
use embassy_usb::class::cdc_acm;

// USB串口回显
async fn usb_cdc_echo(driver: Driver<'static>) {
    let mut usb = embassy_usb::Builder::new(driver);
    let mut class = cdc_acm::Builder::new().build(&mut usb);
    usb.build().await;
    let mut buf = [0; 64];
    loop {
        let n = class.read(&mut buf).await.unwrap();
        class.write(&buf[..n]).await.unwrap()

网站公告

今日签到

点亮在社区的每一天
去签到