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();
}
}
这个示例展示了:
- 如何为Cortex-M的SysTick定时器实现Timer trait
- 如何在嵌入式环境中使用fugit-timer
- 定时器的启动、等待和取消操作
- 在等待定时器时可以执行其他任务的非阻塞方式
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闪烁和按钮去抖动功能,基于您提供的代码片段进行了扩展和完善。