簡體   English   中英

STM32使用TIMer中斷循環

[英]STM32 Using TIMer to break loop

所以我初始化了一個計時器,我想計數100

stm32工作的主要部分。

#include "stm32l0xx.h"

#define SYSCLK_FREQ 131072

void timer_tick(uint16_t n_ms);

int main(void)
{
    TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us   
    TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
    TIM6->EGR = TIM_EGR_UG; //generate update
    TIM6->SR=0; //clear update - after few instructions
...
}

我第一次在那兒使用計時器,它在main之后立即聲明

void delay(uint16_t n_ms)
{
    //upcounting timer - 16bit
    TIM6->CNT = 65535-n_ms;
    TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
    while(!(TIM6->SR & TIM_SR_UIF)); //wait
    TIM6->SR = 0;   
}

比使用同一計時器的Iam(因為我只有無法中斷的TIM3和僅用於延遲功能的TIM6)

void timer_tick(uint16_t n_ms)
{
    //upcounting timer - 16bit
    TIM6->CNT = 65535-n_ms;
    TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
    TIM6->ARR = n_ms-1; // Auto reload value 
    TIM6->CCR1 = n_ms; // Start PWM duty for channel 3 
    //TIM6->CCR2 = n_ms; // Start PWM duty for channel 4 
    TIM6->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1;  // PWM mode on channel 1 & 2 
    TIM6->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E; // Enable compare on channel 1 & 2 
    TIM6->DIER = TIM_DIER_UIE; // Enable TIM6 interrupt
    TIM6->SR = 0;   
}

在這里進行間斷。 Iam調用該函數以將時鍾開始計數到100(Iam賦予其權利),而不是只能實現100 ms的中斷實現開關-在其停止工作並中斷循環之后。

void USART1_IRQHandler(void)
{
    static enum {00, 01, 02, 03, CRC} next_frame = 00; // frame construction

    if(!sending_flag) //half-duplex
    {
        if(USART1->ISR&USART_ISR_FE) //frame error check&clear
            USART1->ICR = USART_ICR_FECF;
        else
        timer_tick(100);
        do {
            switch(next_frame)
            {
                case 00:{ DOSTUFF; next_frame=01; break; } //starting marker
                case 01:{ DOSTUFF; next_frame=02; break; } 
                case 02:{ DOSTUFF; next_frame=03; break; } 
                case 03:{ DOSTUFF; next_frame=CRC; break; } 
                case CRC:{ TIM6->SR = ~TIM_SR_CC2IF; break; } // clear flag
                default: break; 
            }   
        } while (!(TIM6->SR&TIM_SR_CC2IF)); //TIM_SR_UIF
    }

    if(USART1->ISR & USART_ISR_TC)
    {
        USART1->ICR = USART_ICR_TCCF;
        GPIOA->BSRR = GPIO_BSRR_BR_11 | GPIO_BSRR_BR_12;
        sending_flag=0;
    }
}

我確實不了解有關計時器的STM 文檔 設置該TIM6->CCR1 = n_ms; // Start PWM duty for channel 3 TIM6->CCR1 = n_ms; // Start PWM duty for channel 3 Iam的TIM6->CCR1 = n_ms; // Start PWM duty for channel 3假設在定時器達到TIM6->ARR = n_ms-1; // Auto reload value之后, TIM6->SR&TIM_SR_CC2IF處應該有一個標志TIM6->ARR = n_ms-1; // Auto reload value TIM6->ARR = n_ms-1; // Auto reload value添加完do while循環后,我的STM停止響應,並且Iam無法調試它。


  • 櫃台設置正確嗎?
  • 我可以使用聲明的計時器兩次並像我一樣調用它嗎?

櫃台設置正確嗎?

並不是的。 計時器配置中存在很多問題,讓我們嘗試找出其中的一些問題:

#define SYSCLK_FREQ 131072
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
  1. 定時器連接到一些APB總線(1或2),也可以划分。 如果您設置新的APB分頻器值,您的計時器將不再按預期工作。
  2. 時鍾頻率= 131072 獨立於單位,除以1000不會達到100us的期限。

    void delay(uint16_t n_ms) { //upcounting timer - 16bit TIM6->CNT = 65535-n_ms; TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode while(!(TIM6->SR & TIM_SR_UIF)); //wait TIM6->SR = 0; }

這不是您使用計時器的方式。 如果要測量一些時間,只需將ARR設置為正確的值並啟動計數器。

您的timer_tick(uint16_t n_ms)完全錯誤。 計數器從0遞增到ARR值,然后停止(如果設置了一種脈沖模式)。 首先,設置所有定時器配置寄存器,然后啟動計數器。 如果啟動計數器,然后修改ARR,CCRX或其他寄存器,則可以100%確定定時器將下降。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM