代碼地址:https://github.com/hysonglet/py32f030-hal
在單片機(jī)的學(xué)習(xí)中,點(diǎn)燈是開(kāi)發(fā)者的一個(gè)入門儀式,點(diǎn)亮一個(gè) led 燈,將會(huì)帶你進(jìn)入新世界的大門,讓你感受軟件如何控制硬件。
硬件
在 Py32_Rust_dev_V1.1
開(kāi)發(fā)版中,LED 的相關(guān)原理圖如下:
從圖中可以看出,開(kāi)發(fā)版有 2 個(gè)可以通過(guò) GPIO 引腳控制的 LED,且這兩個(gè)引腳與串口下載的電路復(fù)用。因此在點(diǎn)燈的同時(shí)可能會(huì)影響串口的正常工作,理論上是不能同時(shí)使用。
Rust 的庫(kù)接口已經(jīng)保證 PA10
和 PA11
引腳只能在一種場(chǎng)合安全被使用,因此在本篇使用 LED GPOIO 控制亮滅的實(shí)驗(yàn)中,請(qǐng)不要去使用其他非常手段來(lái)做串口的引腳,當(dāng)然鼓勵(lì)去嘗試一起使用, 甚至嘗試修改代碼把同一引腳創(chuàng)建多個(gè) Output
對(duì)象,去感受 Rust 的安全特性。本篇僅分享如何使用 GPIO 控制 LED 閃爍。
在原理圖圖中有以下信息在編程中會(huì)用到:
- RX LED:PA9
- TX LED:PA10
- 當(dāng)引腳為 低電平時(shí),LED 亮,反之則滅
測(cè)試代碼: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 {
// 翻轉(zhuǎn)led
let _ = led.toggle();
cortex_m::asm::delay(10_000_000);
}
}
編譯&運(yùn)行
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;
? 引用這個(gè) trait后,Output
實(shí)例將能在該代碼范圍使用ToggleableOutputPin
的函數(shù),當(dāng)然Output
已經(jīng)在文件src/gpio/mod.rs
中實(shí)現(xiàn)了ToggleableOutputPin
, 因此 Output 具備了ToggleableOutputPin
trait 的能力, 如果不引用ToggleableOutputPin
, 則Outout
的toggle
接口將被隱藏不能使用。 - 為什么沒(méi)有開(kāi)啟 GPIOA 外設(shè)的時(shí)鐘地方?因?yàn)樵?nbsp;
p.GPIOA.split();
中,驅(qū)動(dòng)幫我們偷偷開(kāi)啟了外設(shè)時(shí)鐘,因此上層應(yīng)用開(kāi)發(fā)者可以無(wú)感使用。 cortex_m::asm::delay(10_000_000);
定時(shí)準(zhǔn)嗎?通常與cpu 的頻率有關(guān),參數(shù)為 tick 數(shù)。- use 的調(diào)用順序有關(guān)系嗎?沒(méi)關(guān)系,只要調(diào)用了,編譯會(huì)自動(dòng)識(shí)別的。