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);      // 清除中断标志位
    }
}

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值