Rust定时器库fugit-timer的使用,fugit-timer提供精确的时间管理和定时任务调度功能

Rust定时器库fugit-timer的使用

fugit-timer是一个基于fugit库Duration和Instance的倒计时定时器抽象库,提供精确的时间管理和定时任务调度功能。

安装

在项目目录中运行以下Cargo命令:

cargo add fugit-timer

或者在Cargo.toml中添加:

fugit-timer = "0.1.3"

最低支持的Rust版本(MSRV)

该crate保证可以在稳定版Rust 1.57及以上版本编译。它可能在旧版本上也能编译,但在任何新的补丁发布中都可能改变。

完整示例代码

use fugit::{ExtU32, MicrosDurationU32};
use fugit_timer::Timer;

// 假设我们有一个硬件定时器实现
struct HardwareTimer;

// 实现Timer trait
impl Timer<MicrosDurationU32> for HardwareTimer {
    type Error = ();

    fn now(&mut self) -> MicrosDurationU32 {
        // 返回当前时间
        MicrosDurationU32::micros(0)
    }

    fn start(&mut self, duration: MicrosDurationU32) -> Result<(), Self::Error> {
        // 启动定时器,设置duration时间后到期
        Ok(())
    }

    fn wait(&mut self) -> nb::Result<(), Self::Error> {
        // 非阻塞等待定时器到期
        Ok(())
    }

    fn cancel(&mut self) -> Result<(), Self::Error> {
        // 取消定时器
        Ok(())
    }
}

fn main() {
    let mut timer = HardwareTimer;
    
    // 设置1秒的定时器
    timer.start(1.secs()).unwrap();
    
    // 等待定时器到期
    while timer.wait().is_err() {
        // 可以做其他工作
    }
    
    println!("定时器已到期");
}

特性

  • 使用fugit库的Duration和Instance类型
  • 提供精确的定时功能
  • 适用于嵌入式开发
  • 支持no_std环境

许可证

该库采用以下任一许可证:

  • Apache License, Version 2.0
  • MIT license

贡献

除非您明确声明,否则根据Apache-2.0许可证,您有意提交的任何贡献将按上述方式双重许可,无需任何附加条款或条件。

完整示例demo

以下是一个更完整的fugit-timer使用示例,展示了如何在实际嵌入式环境中使用:

use fugit::{ExtU32, MicrosDurationU32};
use fugit_timer::Timer;
use cortex_m::peripheral::SYST;
use cortex_m_rt::entry;

// 系统定时器(SysTick)实现
struct SysTickTimer(SYST);

impl Timer<MicrosDurationU32> for SysTickTimer {
    type Error = ();

    fn now(&mut self) -> MicrosDurationU32 {
        // 获取当前系统时间(微秒)
        let ticks = self.0.cvr.read();
        MicrosDurationU32::micros(ticks as u32)
    }

    fn start(&mut self, duration: MicrosDurationU32) -> Result<(), Self::Error> {
        // 设置SysTick定时器
        self.0.set_reload(duration.ticks());
        self.0.clear_current();
        self.0.enable_counter();
        Ok(())
    }

    fn wait(&mut self) -> nb::Result<(), Self::Error> {
        // 检查定时器是否到期
        if self.0.has_wrapped() {
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }

    fn cancel(&mut self) -> Result<(), Self::Error> {
        // 禁用定时器
        self.0.disable_counter();
        Ok(())
    }
}

#[entry]
fn main() -> ! {
    let mut cp = cortex_m::Peripherals::take().unwrap();
    
    // 配置系统定时器(SysTick)
    cp.SYST.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
    
    // 创建定时器实例
    let mut timer = SysTickTimer(cp.SYST);
    
    loop {
        // 设置500毫秒的定时器
        timer.start(500.millis()).unwrap();
        
        // 等待定时器到期
        while timer.wait().is_err() {
            // 在这里可以执行其他任务
            // 例如:读取传感器数据或处理通信
        }
        
        // 定时器到期后执行的任务
        println!("定时任务执行 - 500毫秒已到");
        
        // 取消定时器(可选)
        timer.cancel().unwrap();
    }
}

这个示例展示了:

  1. 如何为Cortex-M的SysTick定时器实现Timer trait
  2. 如何在嵌入式环境中使用fugit-timer
  3. 定时器的启动、等待和取消操作
  4. 在等待定时器时可以执行其他任务的非阻塞方式

1 回复

根据您的要求,我将整理fugit-timer的完整使用示例。以下是基于您提供内容的完整示例代码:

完整LED闪烁示例

// 引入必要的库
use fugit_timer::{Timer, TimerExt};
use fugit::{ExtU32, MillisecondsDurationU32};
use nb::block;

// 模拟硬件定时器实现
struct HardwareTimer {
    current_time: MillisecondsDurationU32,
}

impl Timer<MillisecondsDurationU32> for HardwareTimer {
    fn now(&mut self) -> MillisecondsDurationU32 {
        self.current_time
    }
    
    fn start(&mut self, duration: MillisecondsDurationU32) -> Result<(), ()> {
        self.current_time = self.current_time + duration;
        Ok(())
    }
    
    fn cancel(&mut self) -> Result<(), ()> {
        Ok(())
    }
    
    fn wait(&mut self) -> nb::Result<(), ()> {
        Ok(().into())
    }
}

fn main() {
    // 初始化定时器,从0开始计时
    let mut timer = HardwareTimer {
        current_time: MillisecondsDurationU32::millis(0),
    };
    
    let mut led_state = false;
    
    // 以1Hz频率闪烁LED
    loop {
        // 调用blink_led函数
        blink_led(&mut timer, &mut led_state, 500.millis());
        
        // 打印当前LED状态
        println!("LED state: {}", led_state);
    }
}

// LED闪烁函数
fn blink_led<T: Timer<MillisecondsDurationU32>>(
    timer: &mut T,
    led: &mut bool,
    interval: MillisecondsDurationU32,
) {
    // 启动定时器
    timer.start(interval).unwrap();
    // 等待定时器完成
    block!(timer.wait()).unwrap();
    // 切换LED状态
    *led = !*led;
}

完整按钮去抖动示例

use fugit_timer::Timer;
use fugit::{ExtU32, MillisecondsDurationU32};

// 按钮结构体
struct Button {
    pressed: bool,
    last_state: bool,
    debounce_timer: Option<MillisecondsDurationU32>,
}

impl Button {
    fn new() -> Self {
        Self {
            pressed: false,
            last_state: false,
            debounce_timer: None,
        }
    }
    
    // 更新按钮状态
    fn update<T: Timer<MillisecondsDurationU32>>(
        &mut self,
        current_state: bool,
        timer: &mut T,
        now: MillisecondsDurationU32,
    ) -> bool {
        if current_state != self.last_state {
            // 状态变化时设置去抖动定时器
            self.debounce_timer = Some(now + 50.millis());
        }
        
        self.last_state = current_state;
        
        if let Some(debounce_time) = self.debounce_timer {
            if now >= debounce_time {
                self.pressed = current_state;
                self.debounce_timer = None;
                return true; // 返回true表示按钮状态已稳定
            }
        }
        
        false
    }
}

fn main() {
    // 使用之前定义的HardwareTimer
    let mut timer = HardwareTimer {
        current_time: MillisecondsDurationU32::millis(0),
    };
    
    let mut button = Button::new();
    let mut current_button_state = false;
    
    // 模拟按钮状态变化
    for i in 0..10 {
        // 每100ms改变一次按钮状态
        timer.start(100.millis()).unwrap();
        block!(timer.wait()).unwrap();
        
        current_button_state = !current_button_state;
        
        let now = timer.now();
        if button.update(current_button_state, &mut timer, now) {
            println!("Button state stabilized: {}", button.pressed);
        }
    }
}

这些完整示例展示了如何在实践中使用fugit-timer库来实现LED闪烁和按钮去抖动功能,基于您提供的代码片段进行了扩展和完善。

回到顶部