繁体   English   中英

STM32L0定时器TIM22是否以意外方式导致中断?

[英]STM32L0 Timer TIM22 cause interrupt in unpredictive way?

每当我启用计时器时,它都会立即激活中断。 无论我如何尝试对其进行预缩放。 只有ARR似乎可以工作,但16位0.5Mhz的时钟给我带来了约160ms的机动性。

#define SYSCLK_FREQ 524288

void timer_init(uint16_t detonation_delay_ms);

int main(void){
RCC->APB2ENR = RCC_APB2ENR_TIM22EN;
TIM22->PSC = (SYSCLK_FREQ/1000)-1;
NVIC_EnableIRQ(TIM22_IRQn); 
NVIC_SetPriority(TIM22_IRQn,4);
}

/* calling function */
timer_init(65535);
/* calling function */

void timer_init(uint16_t detonation_delay_ms){
TIM22->CR1 &= ~TIM_CR1_CEN;
TIM22->SR=0;                                
TIM22->ARR = detonation_delay_ms;                   
TIM22->CR1 |= TIM_CR1_CEN;
TIM22->SR = 0;
}

void TIM22_IRQHandler(void){
    TIM22->CR1 &= ~TIM_CR1_CEN;
    TIM22->SR=0; 

        GPIOB->BSRR = GPIO_BSRR_BS_7;
}

我希望调用函数可以使计时器计时直到毫秒内被调用的值。 但是无论我如何设置,它最终都没有定标计时器,并且在调用它后不会立即中断。

正确的方法吗?

    TIM22->DIER = TIM_DIER_UIE;
    TIM22->ARR = 65535-detonation_delay_ms;
    TIM22->EGR = TIM_EGR_UG;
    TIM22->CR1 |= TIM_CR1_OPM | TIM_CR1_CEN;
    TIM22->SR=0;
  1. 不要延迟中断

  2. 您启用计时器,然后设置错误的ARR-首先设置ARR和预分频器,然后使用EGR寄存器生成UG事件,然后启用计时器。

奇迹般有效。 仅仅因为我在这里得到了帮助,才会为将来的关注者提供帮助。

使中断工作于定时器的方法是“手动”生成一次中断。 这样做是可行的,因为您可以通过单个“ if”控制中断期间发生的事情。

    /* TIMER Enable */
    RCC->APB2ENR = RCC_APB2ENR_TIM22EN;

我对上面的声明有疑问,不知道为什么,但是在声明了更多模块之后它不起作用。 不得不把它放在更高的位置。 手册没有说为什么会发生。

    /* Configure TIM22 interrupt */ 
    TIM22->PSC = (SYSCLK_FREQ/1000)-1;      /* Prescaler TIMERA 22 */
    TIM22->DIER = TIM_DIER_UIE;
    TIM22->CNT = 0;
    TIM22->EGR = TIM_EGR_UG;

    NVIC_EnableIRQ(TIM22_IRQn);             /* Zalaczenie przerwania od TIMER'a */
    NVIC_SetPriority(TIM22_IRQn,4);     /* Ustawienie priorytetu przerwania od TIMER'a */

预分频比是1ms,所以我将524288的核心速度除了。 然后启用中断,将计数器复位以确保其从0开始,然后手动生成中断。 而且它只执行一次中断“循环”,但是只有一个“ if”和变量,我可以控制它的作用。

所以我要做的就是调用一个设置时钟并在另一个函数中启用计数的函数enable = 1; timer_init(MS);

然后是函数调用

void timer_init(uint16_t ms)
{
    TIM22->CNT = 65535-ms;
    TIM22->CR1 |= TIM_CR1_CEN;                          
}

void TIM22_IRQHandler(void)
/* Up-Counter milisec */
{
    if(TIM22->CR1 & TIM_CR1_CEN) {TIM22->CR1 &= ~TIM_CR1_CEN;}
    if(TIM22->SR & TIM_SR_UIF) {
        if(enable == 1){
            GPIOB->BSRR = GPIO_BSRR_BS_7;
        }
    }       
    TIM22->SR=0;
}

和中断。 非常感谢您与寄存器玩得开心!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM