|
| 1 | +#![no_main] |
| 2 | +#![no_std] |
| 3 | + |
| 4 | +use defmt_rtt as _; |
| 5 | +use panic_probe as _; |
| 6 | +use stm32f4xx_hal::{ |
| 7 | + pac, |
| 8 | + pac::{TIM2, TIM5}, |
| 9 | + prelude::*, |
| 10 | + timer::{CaptureChannel, CaptureHzManager, CapturePolarity, Event, Flag, PwmChannel, Timer}, |
| 11 | +}; |
| 12 | + |
| 13 | +use rtic::app; |
| 14 | + |
| 15 | +#[app(device = pac, dispatchers = [USART1], peripherals = true)] |
| 16 | +mod app { |
| 17 | + use super::*; |
| 18 | + |
| 19 | + #[shared] |
| 20 | + struct Shared {} |
| 21 | + |
| 22 | + #[local] |
| 23 | + struct Local { |
| 24 | + tim5: CaptureHzManager<TIM5>, |
| 25 | + ch1: CaptureChannel<TIM5, 0>, |
| 26 | + } |
| 27 | + |
| 28 | + #[init] |
| 29 | + fn init(ctx: init::Context) -> (Shared, Local) { |
| 30 | + let dp = ctx.device; |
| 31 | + let rcc = dp.RCC.constrain(); |
| 32 | + let clocks = rcc.cfgr.sysclk(48.MHz()).freeze(); |
| 33 | + let gpioa = dp.GPIOA.split(); |
| 34 | + |
| 35 | + // Configuration of TIM2 in PWM mode |
| 36 | + let timer = Timer::new(dp.TIM2, &clocks); |
| 37 | + let (_, (ch1, ..)) = timer.pwm_hz(893.Hz()); |
| 38 | + let mut tim_2: PwmChannel<TIM2, 0> = ch1.with(gpioa.pa5); |
| 39 | + tim_2.set_duty(50); |
| 40 | + tim_2.enable(); |
| 41 | + |
| 42 | + // It is necessary to connect pins PA0 and PA5 through a resistor of 1 kΩ - 10 kΩ |
| 43 | + |
| 44 | + // Configuration of TIM5 in input capture mode |
| 45 | + let (mut tim5, (ch1, ..)) = Timer::new(dp.TIM5, &clocks).capture_hz(48.MHz()); |
| 46 | + let mut ch1 = ch1.with(gpioa.pa0); |
| 47 | + tim5.listen(Event::C1); |
| 48 | + |
| 49 | + ch1.set_polarity(CapturePolarity::ActiveHigh); |
| 50 | + ch1.enable(); |
| 51 | + |
| 52 | + defmt::info!("Start"); |
| 53 | + |
| 54 | + (Shared {}, Local { tim5, ch1 }) |
| 55 | + } |
| 56 | + |
| 57 | + #[task(binds = TIM5, local = [tim5, ch1, prev_capture: u32 = 0], priority = 3)] |
| 58 | + fn tim5_interrupt(cx: tim5_interrupt::Context) { |
| 59 | + if cx.local.tim5.flags().contains(Flag::C1) { |
| 60 | + let timer_clock = cx.local.tim5.get_timer_clock(); |
| 61 | + let max_auto_reload = cx.local.tim5.get_max_auto_reload(); |
| 62 | + let current_capture = cx.local.ch1.get_capture(); |
| 63 | + |
| 64 | + let delta = if current_capture >= *cx.local.prev_capture { |
| 65 | + current_capture - *cx.local.prev_capture |
| 66 | + } else { |
| 67 | + (max_auto_reload - *cx.local.prev_capture) + current_capture |
| 68 | + }; |
| 69 | + |
| 70 | + let freq = timer_clock as f32 / delta as f32; |
| 71 | + |
| 72 | + defmt::info!("Freq: {} Hz", freq); // Output = Freq: 893.00665 Hz |
| 73 | + |
| 74 | + *cx.local.prev_capture = current_capture; |
| 75 | + cx.local.tim5.clear_flags(Flag::C1); |
| 76 | + } |
| 77 | + } |
| 78 | +} |
0 commit comments