如何在avr-hal中为不同TimerPWM引脚统一实现Blinks trait
通用
Blinks trait实现方案 要适配Pin<PwmOutput<Timer0Pwm>, PD6>和Pin<PwmOutput<Timer2Pwm>, PD3>这类不同Timer与引脚组合的PWM输出引脚,你可以通过关联类型+约束embedded_hal标准PwmPin trait实现通用的Blinks trait,避免重复编写实现代码。
步骤1:定义带关联类型的Blinks trait
先定义包含关联类型的trait,让关联类型满足embedded_hal::PwmPin约束,并指定占空比类型为u8(匹配avr-hal的PWM引脚特性):
use embedded_hal::PwmPin; pub trait Blinks { type Pwm: PwmPin<Duty = u8>; fn blink(&mut self, on_duty: u8, off_duty: u8, delay_ms: u16); }
步骤2:为Pin<PwmOutput<TC>, P>实现通用Blinks
针对所有满足PwmOutput约束的引脚类型,实现Blinks trait——avr-hal中Pin<PwmOutput<TC>, P>会自动实现PwmPin<Duty=u8>,因此可以直接利用这一特性:
use arduino_hal::port::Pin; use arduino_hal::pwm::PwmOutput; impl<TC, P> Blinks for Pin<PwmOutput<TC>, P> where Pin<PwmOutput<TC>, P>: PwmPin<Duty = u8>, { type Pwm = Self; fn blink(&mut self, on_duty: u8, off_duty: u8, delay_ms: u16) { // 设置亮态占空比 self.set_duty(on_duty); // 延时 arduino_hal::delay_ms(delay_ms); // 设置灭态占空比(传入0即可完全熄灭) self.set_duty(off_duty); arduino_hal::delay_ms(delay_ms); } }
关键说明
- 不要依赖内部私有trait(比如
_embedded_hal_Pwm),改用公开的embedded_hal::PwmPin——这是跨HAL的标准接口,avr-hal所有PWM引脚都实现了它。 - 泛型约束
Pin<PwmOutput<TC>, P>: PwmPin<Duty = u8>会自动匹配所有avr-hal支持的TimerPWM+引脚组合,包括你用到的Timer0Pwm/PD6和Timer2Pwm/PD3。 - 直接针对具体
Pin类型实现,无需引入Dynamictrait,保留了set_duty的直接调用能力。
测试使用示例
在代码中可以直接调用通用的blink方法:
let dp = arduino_hal::Peripherals::take().unwrap(); let pins = arduino_hal::pins!(dp); let mut led_red = pins.d6.into_output().into_pwm(&mut dp.TCCR0A); let mut led_blue = pins.d3.into_output().into_pwm(&mut dp.TCCR2A); // 通用调用blink方法 led_red.blink(255, 0, 500); led_blue.blink(200, 0, 300);
内容的提问来源于stack exchange,提问作者sebsch
相关产品推荐
相关产品推荐

