使用 rp-hal 的闪烁示例
在上一节中,我们使用了 Embassy。我们保持相同的电路和接线。对于这个示例,我们切换到 rp-hal 以展示这两种方法的样子。如果你想要异步支持,可以选择 Embassy;如果你更喜欢阻塞风格,可以选择 rp-hal。在本书中,我们将主要使用 Embassy。
我们将再次使用 cargo-generate 和相同的模板创建一个新项目。
在你的终端中,输入:
cargo generate --git https://github.com/ImplFerris/pico2-template.git --tag v0.3.1
当它要求你选择硬件抽象层(HAL)时,这次选择 "rp-hal"。
导入
模板已经包含了大部分导入。对于这个示例,我们需要从 embedded-hal 中添加 OutputPin 特性(trait):
#![allow(unused)] fn main() { // 用于输出引脚的嵌入式 HAL 特性 use embedded_hal::digital::OutputPin; }
这个特性提供了我们将用来控制 LED 灯(LED)的 set_high() 和 set_low() 方法。
主要逻辑
如果你将此与 Embassy 版本进行比较,LED 切换的方式没有太大区别。主要区别在于延迟的工作方式。Embassy 使用 async 和 await,这允许程序在不阻塞的情况下暂停,并允许其他任务在后台运行。rp-hal 使用阻塞延迟,这会停止程序直到时间过去。
#![allow(unused)] fn main() { let mut led_pin = pins.gpio13.into_push_pull_output(); loop { led_pin.set_high().unwrap(); timer.delay_ms(200); led_pin.set_low().unwrap(); timer.delay_ms(200); } }
完整代码
#![no_std] #![no_main] use embedded_hal::delay::DelayNs; use hal::block::ImageDef; use rp235x_hal as hal; // 恐慌处理程序(Panic Handler) use panic_probe as _; // Defmt 日志记录 use defmt_rtt as _; // 用于输出引脚的嵌入式 HAL 特性 use embedded_hal::digital::OutputPin; /// 告知引导 ROM(Boot ROM)关于我们的应用程序 #[unsafe(link_section = ".start_block")] #[used] pub static IMAGE_DEF: ImageDef = hal::block::ImageDef::secure_exe(); /// Raspberry Pi Pico 2 开发板上的外部高速晶振为 12 MHz。 /// 如果你的开发板频率不同,请进行调整 const XTAL_FREQ_HZ: u32 = 12_000_000u32; #[hal::entry] fn main() -> ! { // 获取我们的单例对象 let mut pac = hal::pac::Peripherals::take().unwrap(); // 设置看门狗(watchdog)驱动程序 - 时钟设置代码需要它 let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // 配置时钟 // // 默认是生成 125 MHz 的系统时钟 let clocks = hal::clocks::init_clocks_and_plls( XTAL_FREQ_HZ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // 单周期 I/O 块控制我们的通用输入输出(GPIO)引脚 let sio = hal::Sio::new(pac.SIO); // 根据它们在此特定开发板上的功能设置引脚 let pins = hal::gpio::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); let mut timer = hal::Timer::new_timer0(pac.TIMER0, &mut pac.RESETS, &clocks); let mut led_pin = pins.gpio13.into_push_pull_output(); loop { led_pin.set_high().unwrap(); timer.delay_ms(200); led_pin.set_low().unwrap(); timer.delay_ms(200); } } // 用于 `picotool info` 的程序元数据。 // 这不是必需的,但建议保留这些最基本的条目。 #[unsafe(link_section = ".bi_entries")] #[used] pub static PICOTOOL_ENTRIES: [hal::binary_info::EntryAddr; 5] = [ hal::binary_info::rp_cargo_bin_name!(), hal::binary_info::rp_cargo_version!(), hal::binary_info::rp_program_description!(c"your program description"), hal::binary_info::rp_cargo_homepage_url!(), hal::binary_info::rp_program_build_attribute!(), ];
克隆现有项目
你可以克隆我创建的项目并导航到 external-led 文件夹:
git clone https://github.com/ImplFerris/pico2-rp-projects
cd pico2-rp-projects/external-led