高級(jí)定時(shí)器
PY32F030 的內(nèi)部有一個(gè)高級(jí)定時(shí)器TIM1,是一個(gè)16位可編程的定時(shí)器,可用于多種場(chǎng)合,如基礎(chǔ)定時(shí)功能,輸入脈沖測(cè)量,輸出PWM。TIM1的主要特性如下:
- 16bit 可配置的向下、向上、上下重載模式
- 16位的分頻器,支持1~65535的分頻
- 4 個(gè)獨(dú)立的通道,可用于
- 輸入脈沖捕獲
- 輸出比較
- PWM
- 單脈沖輸出
- 支持互補(bǔ)輸出的死區(qū)配置
- 外部信號(hào)控制定時(shí)器或定時(shí)器級(jí)聯(lián)控制
- DMA 操作
- 中斷事件
- 更新事件
- 觸發(fā)事件
- 輸入捕獲事件
- 輸出比較
- 剎車輸入
- 支持正交編碼與霍爾傳感器電路
在驅(qū)動(dòng)包py32f030-hal
中,目前已實(shí)現(xiàn)常用的定時(shí)、PWM輸出、中斷等功能,擴(kuò)展其他功能也非常簡(jiǎn)單。以下將提供裸機(jī)環(huán)境操作定時(shí)器和多任務(wù)系統(tǒng)中配置定時(shí)器輸出PWM的例程。示例1: 定時(shí):
examples/advanced_timer_block.rs
#![no_std] #![no_main] use embedded_hal::digital::v2::ToggleableOutputPin; use hal::gpio::{Output, PinIoType, PinSpeed}; use hal::mode::Blocking; use hal::timer::advanced_timer::AnyTimer; use py32f030_hal as hal; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] fn main() -> ! { defmt::info!("timer counter examples start..."); let p = hal::init(Default::default()); let gpioa = p.GPIOA.split(); let timer = AnyTimer::<_, Blocking>::new(p.TIM1).unwrap(); letmut counter = timer.as_counter(); letmut led = Output::new(gpioa.PA0, PinIoType::PullUp, PinSpeed::Low); letmut cnt = 0; loop { let _ = led.toggle(); // 延時(shí) 1s counter.delay_us_blocking(1_000_000); defmt::info!("{}", cnt); cnt += 1; } }
#![no_std] #![no_main] use embedded_hal::digital::v2::ToggleableOutputPin; use hal::gpio::{Output, PinIoType, PinSpeed}; use hal::mode::Blocking; use hal::timer::advanced_timer::AnyTimer; use py32f030_hal as hal; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] fn main() -> ! { defmt::info!("timer counter examples start..."); let p = hal::init(Default::default()); let gpioa = p.GPIOA.split(); let timer = AnyTimer::<_, Blocking>::new(p.TIM1).unwrap(); letmut counter = timer.as_counter(); letmut led = Output::new(gpioa.PA0, PinIoType::PullUp, PinSpeed::Low); letmut cnt = 0; loop { let _ = led.toggle(); // 延時(shí) 1s counter.delay_us_blocking(1_000_000); defmt::info!("{}", cnt); cnt += 1; } }
運(yùn)行:
cargo r --example advanced_timer_block
示例2: examples/advanced_timer_block_2.rs
#![no_std] #![no_main] use embedded_hal::timer::CountDown; use fugit::ExtU32; use hal::mode::Blocking; use hal::timer::advanced_timer::AnyTimer; use py32f030_hal as hal; use {defmt_rtt as _, panic_probe as _}; #[cortex_m_rt::entry] fn main() -> ! { defmt::info!("timer counter examples start..."); let p = hal::init(Default::default()); let timer = AnyTimer::<_, Blocking>::new(p.TIM1).unwrap(); letmut counter = timer.as_counter(); letmut cnt = 0; loop { // 延時(shí) 5s defmt::info!("repeat...{} ", cnt); counter.start(5u32.secs()); let _ = counter.wait(); cnt += 1; } }
運(yùn)行:
cargo r --example advanced_timer_block_2
示例3:PWM輸出:
examples/embassy_pwm.rs
配置輸出 PWM 波形
運(yùn)行:#![no_std] #![no_main] use hal::timer::advanced_timer::{AnyTimer, ChannelConfig, ChannelOutputConfig}; use py32f030_hal::gpio::gpioa::PA0; use py32f030_hal::{selfas hal, mode::Blocking, timer::advanced_timer::Channel}; use embassy_executor::Spawner; use embassy_time::Timer; use embedded_hal::Pwm; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] asyncfn run() { loop { Timer::after_secs(2).await; defmt::info!("task run"); } } #[embassy_executor::main] asyncfn main(_spawner: Spawner) { defmt::info!("time1 start..."); let p = hal::init(Default::default()); let gpioa = p.GPIOA.split(); _spawner.spawn(run()).unwrap(); let timer: AnyTimer<_, Blocking> = AnyTimer::new(p.TIM1).unwrap(); letmut pwm = timer.as_pwm(); let channel_1_pin = gpioa.PA3; pwm.set_channel_1_pin::<_, PA0>(Some(channel_1_pin), None); // 配置定時(shí)器 pwm.config( /* 配置通道1 */ Some(ChannelConfig::default().ch(ChannelOutputConfig::default())), None, None, None, ); // 計(jì)數(shù)頻率為1M pwm.set_frequency(1_000_000); // 設(shè)置計(jì)數(shù)周期為1000,則波形的頻率為 1000_000/1000 = 1K pwm.set_period(1000u16 - 1); let max_duty = pwm.get_max_duty(); // 33%的占空比 pwm.set_duty(Channel::CH1, max_duty / 3); // 使能通道 pwm.enable(Channel::CH1); // 開始計(jì)數(shù)器 pwm.start(); loop { Timer::after_secs(1).await; } }
cargo r --example embassy_pwm?