STM32使用TIMer打破循环

时间:2018-08-08 09:10:33

标签: c stm32

所以我已经初始化了一个计时器,我想将其计数为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的documentation关于计时器的信息。 假设TIM6->CCR1 = n_ms; // Start PWM duty for channel 3的行设置为TIM6->SR&TIM_SR_CC2IF,假设计时器到达TIM6->ARR = n_ms-1; // Auto reload valuedo while处应有一个标志 添加此<Inserted>循环后,我的STM停止响应,并且Iam无法对其进行调试。


  • 柜台设置正确吗?
  • 我可以两次使用声明的计时器并像我一样调用它吗?

1 个答案:

答案 0 :(得分:0)

  

计数器设置正确吗?

不是。计时器配置中有很多问题,让我们找出其中的一些问题:

#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%确定该计时器将下降。