| 
 | 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