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