当前位置:   article > 正文

STM32定时器#定时时间的计算#

STM32定时器#定时时间的计算#

一、原理

(1)STM32的通用定时器是一个通过可编程预分频器(Prescaler/PSC)驱动的16位自动重装主计数器(Counter Period/ARR)构成。可以对内部时钟或触发源以及外部时钟或触发源进行计数。
(2)通用定时器的基本工作原理:
首先,定时器时钟信号送入16位可编程预分频器,该预分频器系数为0~65535之间的任意数值。预分频器溢出后,会向16位的主计数器发出一个脉冲信号。
预分频器,本质上是一个加法计数器,预分频系数实际上就是加技术的溢出值。
(3)定时器发生中断时间的计算方法:
定时时间 =(Prescaler + 1)×(Counter Period + 1)× 1 / 定时器时钟频率

例:
时钟信号1KHz,Prescaler = 9,Counter Period = 999,定时时间=?

时钟信号是1KHz,时间就是1/1KHz = 1ms

经过预分频器,1*(9+1) = 10ms,即10ms 主计数器的计数加一,

主计数器要计数999+1个,所以总定时时间=10ms*1000 = 10S

二、定时时间的计算
PSC 和 ARR 都是16位的寄存器,所以取值都是从 0~65535,在此基础上,加 1 之后才是实际的分频值和计数值。

计数器计数频率:CK_CNT = CK_PSC / (PSC+1)

计一个数的时间 :t = 1 / CK_CNT

计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR+1)

定时周期:T = 1 / CK_CNT_OV

三、时基初始化结构体详解
typedef struct
{
    uint16_t TIM_Prescaler;            // 预分频值
    uint16_t TIM_CounterMode;          // 计数模式,基本定时器只能向上计数
    uint32_t TIM_period;             // 自动重装载值
    uint16_t TIM_ClockDivison;         // 外部输入时钟分频因子,基本定时器没有
    uint8_t TIM_RepetitionCounter;    // 重复计数器,基本定时器没有,高级定时器专用
} TIM_TimeBaseInitTypeDef;
虽然时基初始化结构体有 5 个成员,但对于基本定时器只需设置其中两个就可以。

四、举例
在这里我们以基本定时器 TIM6 为例,实现定时 1s 。

配置定时器相关内容
void Timer_Config(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    // 开启定时器时钟, 即内部时钟 CK_INT=72M
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

    // 自动重装载寄存器的值 (计数值)
    TIM_TimeBaseStructure.TIM_Period = 10000 - 1;

    // 预分频数为 7200-1,则驱动计数器的时钟 CK_CNT = CK_INT / 7200 = 10KHz
    TIM_TimeBaseStructure.TIM_Prescaler= 7200 - 1;

    // 时钟分频因子 ,基本定时器没有,不用管
    //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

    // 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
    //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

    // 重复计数器的值,基本定时器没有,不用管
    //TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

    // 初始化定时器时基单元
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

    // 清除计数器中断标志位
    TIM_ClearFlag(TIM6, TIM_FLAG_Update);

    // 使能定时器中断
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

    // 使能定时器
    TIM_Cmd(TIM6, ENABLE);
}


配置 NVIC
void Timer_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);           // 配置 NVIC 为优先级组 1

    NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;           // 选择对应的中断号
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);
}

编写中断服务程序
void TIM6_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)    // 检测中断标志位
    {
        // 处理中断事件...
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update);      // 清除中断标志位
    }
}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/683585
推荐阅读
相关标签
  

闽ICP备14008679号