首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32使用TIMer中断循环

STM32使用TIMer中断循环
EN

Stack Overflow用户
提问于 2018-08-08 09:10:32
回答 1查看 1.6K关注 0票数 0

所以我初始化了一个计时器,我想数到100

stm32工作的主要部分。

代码语言:javascript
复制
#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之后声明的。

代码语言:javascript
复制
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;   
}

而不是使用相同的计时器(因为我只有TIM3,不能插入,TIM6只用于延迟函数)

代码语言:javascript
复制
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;   
}

在这里处理插曲。我正在调用这个函数来启动时钟计数到100 (Iam向右移动),而不是实现只能工作100 ms的开关--在它必须停止工作并中断循环之后。

代码语言:javascript
复制
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;
    }
}

我不知道我的文档关于计时器的事。如果这行设置类似于TIM6->CCR1 = n_ms; // Start PWM duty for channel 3,那么假设计时器到达TIM6->ARR = n_ms-1; // Auto reload value后在TIM6->SR&TIM_SR_CC2IF上有一个标志,在添加了这个do while循环后,我的STM停止响应,而Iam无法调试它。

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

回答 1

Stack Overflow用户

发布于 2018-08-08 10:07:16

柜台设置好了吗?

不怎么有意思。在计时器配置中有很多问题,让我们尝试找出其中的一些:

代码语言:javascript
复制
#define SYSCLK_FREQ 131072
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
  1. 定时器连接到一些APB总线(1或2),这些总线也可以被分割。如果您设置了新的APB除法器值,则您的计时器将不再像预期的那样工作。
  2. 时钟频率= 131072?独立于单位,你不会达到100 it期除以1000。 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%确定,计时器将下降。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51742789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档