【STM32 标准库】定时器(定时+计数)

avatar
作者
筋斗云
阅读量:0

1.定时器简介

 1.1 定时器

    STM32F1有8个定时器。其中,2个基本定时器(TIM6、TIM7)、4个通用定时器(TIM2-TIM5)、2个高级定时器(TIM1、TIM8)。定时器性能:高级 > 通用 > 基本。

 1.2 通用定时器

(1)主要功能:

16位向上、向下、向上/向下自动装载计数器(TIMx_CNT)

16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值

4个独立通道(TIMx_CH1~4):

输入捕获

输出比较

PWM生成(边缘或中间对齐模式)

单脉冲模式输出

使用外部信号(TIMx_ETR)控制定时器,且可实现多个定时器互连(可以用一个定时器控制另外一个定时器)的同步电路

发送如下事件发生时产生中断/DMA:

更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

输入捕获

输出比较

支持针对定位的增量(正交)编码器和霍尔传感器电路

触发输入作为外部时钟或者按周期的电流管理

(2)结构框图:07d250d751734008a202aae694f8ddff.png

(3)主要功能模块描述:

    p1:时钟部分

内部时钟(通过APB1总线倍频(2倍频)而来,即CK_INT=72MHz)。

外部时钟1:TIx

外部时钟2:ETR

内部触发输入:ITRx

    p2:控制器部分

    p3:时基单元。都是16位:

    预分频器(TIMx_PSC,分频系数1~65536)-CK_CNT-> 

    计数器(TIMx_CNT)<--

    自动重装载寄存器(TIMx_ARR)

    计数器模式:向上计数、向下计数、中央对齐(向上/向下计数)

    p4:输入捕获。测量输入信号的脉宽、测量PWM输入信号的频率和占空比。

    p5:输出比较。有效电平、无效电平、翻转、强置为有效电平、强置为无效电平、PWM1、PWM2。

2.通用定时器配置

 2.1 配置步骤

    添加定时器的源文件和头文件及其路径;

    (1)使能定时器时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); 

    (2)初始化定时器参数,包含自动重装值,分频系数,计数方式等 

    void TIM_TimeBaseInit(TIM_TypeDef* TIMx,  //定时器选择:确定哪一个定时器

                 TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct  //结构体指针变量,对结构体成员进行配置,初始化定时器

                 ); 

    typedef struct{   

            uint16_t TIM_Prescaler;    //预分频器n-1         

            uint16_t TIM_CounterMode;   //计数器模式       

            uint32_t TIM_Period;       //自动重载值设置           

            uint16_t TIM_ClockDivision;   //时钟分频因子,通常为1即不分频             uint8_t TIM_RepetitionCounter; //重复计数器,高级定时器才会用 

             } TIM_TimeBaseInitTypeDef;

    定时时间计算:Tout= ((per)*(psc+1))/Tclk;

            Tclk:系统时钟频率

            psc:预分频系数

            per:自动重载值

    (3)设置定时器中断类型,并使能

    void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)     

    (4)设置定时器中断优先级,使能定时器中断通道 

    (5)开启定时器 

    void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) 

    (6)编写定时器中断服务函数 

    TIM4_IRQHandler 

    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);                                       if(TIM_GetITStatus(TIM4,TIM_IT_Update)) {     ...//执行TIM4更新中断内控制 }     

    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

   2.2 配置流程

    (1)添加定时器的源文件和头文件及其路径:

d00b0220ee504d8c9e5e0e5c97797692.png37ce315dd3574282ae734f9b0c2598b4.png5dc3ae16d6134365ba8f88d815a6a789.pnge9c3bbf40e15437d9625ab959d2a0da2.png

    (2)定时器初始化:

8c65fbbc6eff47e8a1354428fd73f436.png

    (3)中断服务函数:

57180cf2b29f457dbd056dc8ef145ddc.png

    (4)主函数:

50c807d87d94441884d9c9cc993ff564.png

3.硬件设计

4.软件设计

    4.1 功能描述

    本实验所要实现的功能是:通过 TIM4 的更新中断控制 DS1 指示灯间隔 500ms 秒状态取反,主函数控制 DS0 指示灯不断闪烁。

   4.2 软件实现

    (1)初始化TIM4,并使能更新中断;

/* ---------------------------------函数声明------------------------------------- *函数名称:TIM4_Iint(u16 per, u16 psc) *输入参数:u16 per:自动重装载值;u16 psc:预分频系数 *返回参数:无 *功    能:初始化定时器TIM4 *作    者:lph *日    期:2024/03/26 ------------------------------------------------------------------------------ */ void TIM4_Iint(u16 per, u16 psc) {     //1.使能定时器时钟     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);     //2.初始化定时器参数     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;          TIM_TimeBaseInitStructure.TIM_Period=per;     TIM_TimeBaseInitStructure.TIM_Prescaler=psc;     TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;     TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);          //3.设置定时器中断类型,并使能     TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);     TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除中断标志位:防止前面被使用          NVIC_InitTypeDef NVIC_InitStructure;          NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;     NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;     NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;     NVIC_Init(&NVIC_InitStructure);          //4.开启定时器     TIM_Cmd(TIM4, ENABLE);          //5.编写定时器中断服务函数      }

    (2)编写TIM4中断函数;

// -----------------------------2.定时器中断服务函数----------------------------- /* ---------------------------------函数声明------------------------------------- *函数名称:TIM4_IRQHandler(void) *输入参数:无 *返回参数:无 *功    能:定时器中断服务函数 *作    者:lph *日    期:2024/03/26 ------------------------------------------------------------------------------ */ void TIM4_IRQHandler(void) {     if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)     {         LED1 = !LED1;     }     TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除中断状态标志位 }

    (3)编写主函数。

/* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "system.h" #include "LED.h" #include "SysTick.h" #include "TIME.h" /* 主函数main() --------------------------------------------------------------*/ int main() {        // 自定义变量     u8 i=0;          // 初始化     SysTick_Iint(72);     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组     LED_Init();     TIM4_Iint(1000, 36000-1);  // 分频系数为36000时,每次计数0.5ms          while(1)     {         i++;         if(i%20==0)         {             LED0 = !LED0;         }         delay_ms(10);     } }

 

 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!