江协科STM32 6-1定时器中断详解与代码剖析

江协科STM32 6-1定时器中断 代码详讲

引言:STM32主要是通过库函数来配置寄存器,所以了解库函数是很重要的事情,此博客主要讲以下两点:1.如何查看并且运用库函数,2.定时器中断代码中Timer.c、代码详讲。

一. 查看运用库函数

  1. 查看库函数变量以及用法:

    假设我们要查看RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);此句函数是如何使用的,它有什么变量,我们只需要1.选中此句函数。2.点击黄色方框“Go To Defination …”

当我们点击此选项之后,就会跳转到此函数对应库中的声明此函数的部分(分为俩部分1.注释部分、2.函数声明部分)如果之后我们想查找定义的变量,只需要选中那个变量并且再按ctrl+f快捷键,就可以找到此变量的定义或者是它出现在哪个函数当中。

  1. 注释部分:

建议下载一个能在线翻译的词典,使用起来稍微方便一点。up使用的有道词典只需要选中文字之后就可以翻译出来了。

由翻译结果可以知道,此函数是开启APB1的外设时钟的,并且可以在args中选择我们要使用的组合,然后使之使能即可。

  1. 函数声明部分

二. Timer.c代码详讲

  1. 代码部分:
#include "stm32f10x.h"                  // Device header

extern uint16_t Num;
void Timer_Init(void){
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

    TIM_InternalClockConfig(TIM2);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period=10000-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM2,ENABLE);
}

void TIM2_IRQHandler(void){
    if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){

        Num++;
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }

}

因为此部分的代码和之前5-2中螺旋计数器的代码类似,所以只挑我认为的重点讲,其他部分代码配置的部分如果有不懂的部分请跳转:江协科STM32 5-2旋转编码器计次 代码详讲-CSDN博客

  1. 详讲部分
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启TIM2的外设时钟

    TIM_InternalClockConfig(TIM2);//配置TIM2中的外设时钟

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义一个结构体来配置寄存器
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟划分,一共有3个选项,在此代码中选择第一个,不分频
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//调整计数器模式为向上计数模式
    TIM_TimeBaseInitStructure.TIM_Period=10000-1;//指定要加载到活动的周期值,在下一次更新事件时自动重新加载寄存器
    TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;//指定用于划分TIM时钟的预分频器值。
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//指定重复计数的值
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIM2的中断挂起位,更新中断,到指定位溢出时会触发中断
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//启用TIM2的中断

重点:

  1. 预分频值以及自动重载值的计算

    公式:

其中:

  • FCK_CNT​:定时器的输入时钟频率(即 CK_INT,通常为系统主频或APB总线时钟为72MHz)。

  • PSC:预分频值(TIM_Prescaler),范围 0x0000 ~ 0xFFFF(即 0~65535)。

  • ARR:自动重载值(TIM_Period),范围 0x0000 ~ 0xFFFF(即 0~65535)。

  • 所以将已知的值带入得:

  • 预分频后时钟:720072MHz​=10kHz

  • 每次计数时间:10kHz1​=0.1ms

  • 总定时时间:10000×0.1ms=1000ms=1秒

  • 按照我理解的就是分频就是确定每次计数的时间,自动重载就是确定次数。

    扩展:

    1. STM32定时器(TIM)的时钟分频因子:

      作用:配置定时器的 时钟分频(CKD),用于调整数字滤波器和死区时间的采样时钟频率。不改变定时器实际计数频率(CK_CNT),仅影响抗噪声能力。

      宏定义 值(二进制) 分频系数 适用场景
      TIM_CKD_DIV1 0x0000 1 高精度场景(如高速PWM)
      TIM_CKD_DIV2 0x0100 2 平衡精度与抗噪性(如电机控制)
      TIM_CKD_DIV4 0x0200 4 高噪声环境(如开关电源)
    2. 计数器模式定义

    3. TIM_CounterMode_Up:计数器向上计数模式(从0递增到自动重装载值)

    4. TIM_CounterMode_Down:计数器向下计数模式(从自动重装载值递减到0)

    5. TIM_CounterMode_CenterAligned1/2/3:中央对齐模式(三种不同的中央对齐计数方式)
      递增到自动重装载值)

    6. TIM_CounterMode_Down:计数器向下计数模式(从自动重装载值递减到0)

    7. TIM_CounterMode_CenterAligned1/2/3:中央对齐模式(三种不同的中央对齐计数方式)

    作者:xuan_lili

    物联沃分享整理
    物联沃-IOTWORD物联网 » 江协科STM32 6-1定时器中断详解与代码剖析

    发表回复