嵌入式Rust获取流逝时间:stm32f1xx-hal Timer初始化报错求助
嵌入式Rust实现类似Instant::now()的计时功能问题
我正在用嵌入式Rust开发程序,需要实现类似标准库Instant::now()获取某个时刻后流逝时间的功能。由于嵌入式环境无std库,使用stm32f103c8t6芯片及stm32f1xx-hal库,尝试通过Timer模块和embedded-time crate实现,但初始化计数器时出现E0599错误,提示找不到Timer::new方法。
标准库实现示例
use std::time::{Duration, Instant}; use std::thread::sleep; fn main() { let now = Instant::now(); // 休眠2秒 sleep(Duration::new(2, 0)); // 输出'2' println!("{}", now.elapsed().as_secs()); }
我尝试的代码
let mut counter = Timer::new(dp.TIM2, &clocks).counter_us(); counter.start(1_000_000_u32.micros()).unwrap();
let mut timer = Timer::syst(cp.SYST, &clocks); let mut counter = Timer::counter_us(timer);
错误信息
error[E0599]: no function or associated item named `new` found for struct `Timer` in the current scope --> src/main.rs:87:30 | 87 | let mut counter = Timer::new(dp.TIM2, &clocks).counter_us(); | ^^^ function or associated item not found in `Timer<_>`
导入的模块
use panic_halt as _; use cortex_m_rt::entry; use embedded_hal::digital::v2::OutputPin; use stm32f1xx_hal as hal; use hal::{pac, TIM2, timer::Timer, delay::Delay, prelude::*}; use rtt_target::{rprintln, rtt_init_print};
解决方案
stm32f1xx-hal库中,Timer结构体并没有new关联函数,正确的初始化方式是通过外设实例的into_timer方法结合时钟配置来创建Timer,再转为计数器:
1. 通用定时器(TIM2)初始化示例
// 从dp.TIM2创建Timer实例 let mut timer = dp.TIM2.into_timer(&clocks); // 将Timer转为微秒精度的计数器 let mut counter = timer.counter_us(); // 启动计数器,设置最大自动重载值实现自由运行(避免频繁溢出) counter.start(0xFFFF_FFFF_u32.micros()).unwrap();
2. 封装类似Instant的功能
可以基于上述计数器封装一个模拟标准库Instant的结构体,实现now()和elapsed()方法:
use embedded_time::duration::Microseconds; struct Instant { start: u32, counter: &'static mut hal::timer::CounterUs<TIM2>, } impl Instant { // 获取当前时刻 fn now(counter: &'static mut hal::timer::CounterUs<TIM2>) -> Self { Instant { start: counter.now(), counter, } } // 计算从当前实例创建到现在的流逝时间 fn elapsed(&self) -> Microseconds<u32> { let current = self.counter.now(); // 处理计数器溢出的情况 if current >= self.start { Microseconds(current - self.start) } else { Microseconds(0xFFFF_FFFF_u32 - self.start + current + 1) } } }
说明
- 不同版本的stm32f1xx-hal库API可能存在差异,上述代码基于较新的版本编写;
- 若使用SysTick实现,可直接利用
hal::delay::Delay的底层计数器,但通用定时器的灵活性更高,适合长时间计时。
内容的提问来源于stack exchange,提问作者Hardware
相关产品推荐
相关产品推荐

