【发布时间】:2021-03-29 11:43:32
【问题描述】:
我正在尝试在STM32F303 Discovery 板上以单脉冲模式 (OPM) 设置和使用 TIM2 外设。
我遇到的问题是计时器在启用后立即完成。
此时我没有使用interrupt,我只是轮询TIM2_SR(状态寄存器)UIF 位以确定计时器是否已完成。
这只会在我第一次启用计时器时发生,如果我再次使用计时器,它会正常工作(不会立即完成)。
我尝试在启用定时器之前重置TIM2_CNT 寄存器,但结果是一样的。
use cortex_m_rt::entry;
use stm32f3xx_hal::pac;
#[entry]
fn main( ) -> ! {
let p = pac::Peripherals::take( ).unwrap( );
p.RCC.apb1enr.modify( | _, w | w.tim2en( ).set_bit( ) );
p.TIM2.cr1.write( | w | w
.urs( ).set_bit( )
.opm( ).set_bit( )
.cen( ).clear_bit( ) );
// I've tried resetting the CNT register at this point
// in the application but the result was the same.
// Set the prescaler based on an 8MHz clock.
p.TIM2.psc.write( | w | w.psc( ).bits( 7999 ) );
// Here I initialize an LED (GPIOE). I've removed this code to
// keep the example as clean as possible.
let delay = | duration | {
p.TIM2.arr.write( | w | w.arr( ).bits( duration ) );
// I've also tried resetting the CNT register here
// but the result was the same.
p.TIM2.cr1.modify( | _, w | w.cen( ).set_bit( ) );
while p.TIM2.sr.read( ).uif( ).bit_is_clear( ) { }
p.TIM2.sr.write( | w | w.uif( ).clear_bit( ) );
};
// Enable LED.
// This call instantly returns.
delay( 3999 );
// Disable LED.
loop { }
}
上面的示例使 LED 闪烁,几乎没有延迟。
如果我改为使用无限循环,则计时器会在初始调用 delay 后按预期工作。
loop {
// Enable LED.
// The first call in the first loop iteration
// returns instantly.
delay( 3999 );
// Disable LED.
// This call, and every call here after correctly
// returns after 4 seconds.
delay( 3999 );
}
我在应用程序运行时检查了寄存器,一切似乎都设置正确。
-
TIM2_CNT寄存器在启用定时器之前读取0x0000_0000 -
TIM2_SR寄存器中的UIF位在启用定时器之前未设置 -
TIM2_PSC寄存器读取正确的预分频器7999 -
TIM2_ARR寄存器包含正确的自动重载值3999 -
TIM_CR1寄存器中的OPM位设置正确
在另一个论坛上阅读了类似问题后,该答案中建议启用TIM2_CR1 寄存器中的URS 位,这会导致更新中断/DMA 请求仅在计数器上溢/下溢时发出。这当然行不通。
我感觉在某个地方需要重置/设置 bit,以便在我第一次启用它时让计时器按预期运行。
【问题讨论】: