代碼地址:https://github.com/hysonglet/py32f030-hal
在單片機的學習中,點燈是開發者的一個入門儀式,點亮一個 led 燈,將會帶你進入新世界的大門,讓你感受軟件如何控制硬件。
硬件
在 Py32_Rust_dev_V1.1
開發版中,LED 的相關原理圖如下:
從圖中可以看出,開發版有 2 個可以通過 GPIO 引腳控制的 LED,且這兩個引腳與串口下載的電路復用。因此在點燈的同時可能會影響串口的正常工作,理論上是不能同時使用。
Rust 的庫接口已經保證 PA10
和 PA11
引腳只能在一種場合安全被使用,因此在本篇使用 LED GPOIO 控制亮滅的實驗中,請不要去使用其他非常手段來做串口的引腳,當然鼓勵去嘗試一起使用, 甚至嘗試修改代碼把同一引腳創建多個 Output
對象,去感受 Rust 的安全特性。本篇僅分享如何使用 GPIO 控制 LED 閃爍。
在原理圖圖中有以下信息在編程中會用到:
- RX LED:PA9
- TX LED:PA10
- 當引腳為 低電平時,LED 亮,反之則滅
測試代碼:examples/blinky.rs
#![no_std]
#![no_main]
use embedded_hal::digital::v2::ToggleableOutputPin;
use hal::gpio::{Output, PinIoType, PinSpeed};
use py32f030_hal as hal;
use {defmt_rtt as _, panic_probe as _};
#[cortex_m_rt::entry]
fn main() -> ! {
let p = hal::init(Default::default());
defmt::info!("Led blinky testing...");
let gpioa = p.GPIOA.split();
let mut led = Output::new(gpioa.PA10, PinIoType::PullDown, PinSpeed::Low);
loop {
// 翻轉led
let _ = led.toggle();
cortex_m::asm::delay(10_000_000);
}
}
編譯&運行
cargo r --example blinky
效果
? py32f030-hal git:(main) ? cargo r --example blinky
warning: unused manifest key: dependencies.embedded-io-async.option
Compiling py32f030_hal v0.1.0 (/Users/hunter/mywork/py32/py32f030-hal)
Finished `dev` profile [optimized + debuginfo] target(s) in 0.48s
Running `probe-rs run --chip PY32F030x8 target/thumbv6m-none-eabi/debug/examples/blinky`
Erasing ? [00:00:00] [######################################################################################################################] 12.00 KiB/12.00 KiB @ 57.31 KiB/s (eta 0s )
Programming ? [00:00:04] [#######################################################################################################################] 10.62 KiB/10.62 KiB @ 2.53 KiB/s (eta 0s ) Finished in 4.483s
INFO Led blinky testing...
└─ blinky::__cortex_m_rt_main @ examples/blinky.rs:14
你可能好奇的地方
- 為什么添加
use embedded_hal::digital::v2::ToggleableOutputPin;
? 引用這個 trait后,Output
實例將能在該代碼范圍使用ToggleableOutputPin
的函數,當然Output
已經在文件src/gpio/mod.rs
中實現了ToggleableOutputPin
, 因此 Output 具備了ToggleableOutputPin
trait 的能力, 如果不引用ToggleableOutputPin
, 則Outout
的toggle
接口將被隱藏不能使用。 - 為什么沒有開啟 GPIOA 外設的時鐘地方?因為在
p.GPIOA.split();
中,驅動幫我們偷偷開啟了外設時鐘,因此上層應用開發者可以無感使用。 cortex_m::asm::delay(10_000_000);
定時準嗎?通常與cpu 的頻率有關,參數為 tick 數。- use 的調用順序有關系嗎?沒關系,只要調用了,編譯會自動識別的。