You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在avr-hal中为不同TimerPWM引脚统一实现Blinks trait

要适配Pin<PwmOutput<Timer0Pwm>, PD6>和Pin<PwmOutput<Timer2Pwm>, PD3>这类不同Timer与引脚组合的PWM输出引脚,你可以通过关联类型+约束embedded_hal标准PwmPin trait实现通用的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);
}

针对所有满足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类型实现,无需引入Dynamic trait,保留了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:22:21