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

时间:2019-07-05 13:22:44

标签: c timer interrupt stm32

每次我启用计时器时,它都会立即激活中断。无论我如何尝试对其进行预缩放。只有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;

2 个答案:

答案 0 :(得分:3)

  1. 请勿延迟中断

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

答案 1 :(得分:0)

像魅力一样工作。仅仅因为我在这里得到了帮助,才会为将来的有兴趣的人提供帮助。

使中断工作于定时器的方法是“手动”生成一次中断。这样做是可行的,因为您可以通过单个“ 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;
}

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