06:(标准库)定时器一:时基单元

06:(标准库)定时器一:时基单元定时器是一种专门负责定时功能的片上外设 而 F1 系列的单片机最多由 14 个定时器 TIM1 TIM14

大家好,欢迎来到IT知识分享网。

1、什么是定时器

   定时器是一种专门负责定时功能的片上外设,而F1系列的单片机最多由14个定时器(TIM1~TIM14)。而STM32F103C8T6一共只有4个定时器

在这里插入图片描述
如上图所示:STM32F103C8T6有一个高级定时器TIM1,3个通用定时器TIM2~4。而高级定时器TIM1挂载在APB2上面。

2、时基单元的基本结构

在这里插入图片描述
如图为定时器的基本结构,而时基单元是定时器结构的一部分,如下图所示。

在这里插入图片描述
如图:时基单元的基本结构由预分频器PSC,计数器CNT,自动重装寄存器ARR,重复计数器RCR组成。而RCR只有高级定时器才有,通用定时器没有。

 PSC (Prescaler): 对速时钟信号 分频 CNT (Counter) :在时钟脉冲激励下 计数 ARR (Auto Reload Register ):用于设置定时周期 RCR (Repetition Counter Register):用于设置定时的 的次 Update事件 - 当RCR溢 时产生 Update中断 - 由Update事件引发的中断 

2.1:脉冲的来源

在这里插入图片描述
由晶振而来,具体情况可参考时钟树的相关知识。

在这里插入图片描述

由上图所示:如果是APB1产生的频率,那么频率 * 2,如果是APB2产生的频率,那么频率 * 1 STM32F103C8T6的定时器来源的频率max = 72MHz

2.2:预分频器PSC

在这里插入图片描述

预分频器由PSC由计数器,比较器和自动重装器构成。

在这里插入图片描述
想要分频率的频率脉冲连接计数器,作为输入信号。当计数器从1开始计数,数值和计数周期通过比较器相较,如果计数值 > 计数周期时,比较器输出一个脉冲,计数值归0,重新开始计数。

如上图所示:计数周期为7,输入脉冲输入了8个脉冲,比较器才输出1个脉冲,实现8分频
如上图:预分频器为16bit,就是计数器为16bit,则它能分频的最大倍数为:2^16 – 1 +1 = 65536 。

2.3:计数器CNT

在这里插入图片描述
例如:如果是2bit的计数器,N也为2bit,那么最大分频倍数为2^2 = 4。
没有脉冲来时:计数器为00
第1个脉冲来:计数器为01
第2个脉冲来:计数器为10
第3个脉冲来:计数器为11
第4个脉冲来:计数器变为00,然后向外输出一个脉冲。
在这里插入图片描述






在这里插入图片描述

2.4:update事件与预加载

在这里插入图片描述N值决定了 的周期,有时我们需要在 运行的过程中 态地调整N的值为了防止出错这个调整需要加一些保护措施(预加载 Preload)。新的N值首先被写 shadow中,等到下一次Update事件时传 active ,至此才能真正发挥作用。
在这里插入图片描述
如图:在计数的中途改变N的值时,N的值保存在影子寄存器中,然后等待这一次的计数完成后,影子寄存器在将N的值写入shadow里面。

3、本章常见的标准库函数

与时基单元相关的库函数如下:

1.TIM_DeInit(TIM_TypeDef* TIMx);
   •功能:该函数用于将指定的定时器 TIMx 恢复为默认状态。通常在重新配置定时器之前使用,以确保定时器处于初始配置。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。


2.TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
   •功能:初始化定时器的时基单元。此函数配置定时器的计数频率、计数模式、预分频器等设置。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_TimeBaseInitStruct:指向一个 TIM_TimeBaseInitTypeDef 结构体,该结构体定义了定时器的时间基准设置。
      •TIM_TimeBaseInitTypeDef结构体
                TIM_Prescaler:预分频器值。
                TIM_CounterMode:计数模式,有以下选项:
                    TIM_CounterMode_Up        向上计数
                    TIM_CounterMode_Down      向下计数
                    TIM_CounterMode_CenterAligned1 中心对齐模式1
                TIM_Period:定时器的自动重载值。计数器每当达到该值时会重载。
                IM_ClockDivision:时钟分割。用于细化定时器的时钟频率。不常用
                TIM_RepetitionCounter:仅适用于高级定时器(如 TIM1、TIM8)。控制定时器的重复计数。












TIM_TimeBaseInitTypeDef TIM_BaseStruct; TIM_BaseStruct.TIM_Prescaler = 72 - 1; // 设置预分频器,外部时钟为72 MHz,预分频器设置为 72 TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up; // 设置为升计数模式 TIM_BaseStruct.TIM_Period = 1000 - 1; // 设置定时器周期为1000 TIM_TimeBaseInit(TIM1, &TIM_BaseStruct); // 初始化 TIM1 

3.void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
   •功能:将TIM_TimeBaseInitTypeDef结构体中的成员变量初始化为默认值
   •参数
      •TIM_TimeBaseInitStruct:这是一个指向TIM_TimeBaseInitTypeDef结构体的指针。TIM_TimeBaseInitTypeDef结构体包含了定时器基本定时参数的定义。


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 

4.void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
   •功能:该函数用于启用或禁用定时器。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •NewState:ENABLE/DISABLE



5.void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
   •功能:该函数用于配置定时器的中断功能。它通过启用或禁用定时器的特定中断,控制定时器事件发生时是否触发中断.
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_IT:该参数指定要启用或禁用的定时器中断类型。定时器中断种类通常包括:
           TIM_IT_Update: 定时器溢出中断(计数器达到最大值后溢出)。
           TIM_IT_CC1: 通道 1 捕获比较中断(捕获到上升沿/下降沿产生中断。CCR == CNT时产生中断)
           TIM_IT_CC2: 通道 2 捕获比较中断。
           TIM_IT_CC3: 通道 3 捕获比较中断。
           TIM_IT_CC4: 通道 4 捕获比较中断。
           TIM_IT_Trigger: 触发事件中断。
           TIM_IT_Break: 中断断开事件。
      •NewState:ENABLE/DISABLE。











6.void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
   •功能:该函数用于设置定时器的预分频器值。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •Prescaler:预分频值,用来设置定时器计数器的时钟频率。
      •TIM_PSCReloadMode:预分频器重新加载模式。该参数指定了预分频器值更新的时机。
                TIM_PSCReloadMode_Update: 预分频器在计数器更新事件时重新加载。
                TIM_PSCReloadMode_Immediate: 预分频器立即重新加载。






// 设置 TIM2 的预分频器为 1000,并且预分频器值立即重新加载 TIM_PrescalerConfig(TIM2, 1000, TIM_PSCReloadMode_Immediate); 

7.void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
   •功能:该函数配置定时器的计数模式,可以选择向上计数、向下计数或中心对齐计数模式。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_CounterMode:计数器的计数模式。STM32 提供了三种不同的计数模式:
                TIM_CounterMode_Up: 向上计数模式。
                TIM_CounterMode_Down: 向下计数模式。
                TIM_CounterMode_CenterAligned: 中心对齐计数模式,






8.void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
   •功能:该函数用于启用或禁用定时器的 ARR 预加载功能。启用时,ARR 寄存器的值将在下一个计数周期时生效,而不是等待计数器溢出事件。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •NewState:使能或禁用 ARR(自动重装载寄存器)预加载功能。
                ENABLE: 启用 ARR 的预加载功能。
                DISABLE: 禁用 ARR 的预加载功能。





9.void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
   •功能:用于启用或禁用定时器的 预装载功能。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •NewState:指定的定时器(例如:TIM1, TIM2 等)。
             ENABLE        启用预装载功能。
             DISABLE        禁用预装载功能。





10.void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
   •功能:该函数配置定时器为一次脉冲模式。在一次脉冲模式下,定时器将只触发一个脉冲事件。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_OPMode: 一次脉冲模式,决定是否启用一次脉冲模式。可以选择:
             TIM_OPMode_Single        启用单次脉冲模式。
             TIM_OPMode_Repetitive        启用重复脉冲模式。





11.void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
   •功能:该函数设置定时器的计数器初值。定时器的计数器通常从 0 开始
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •Counter:设置定时器的计数器值。



//将TIM2 的计数器设置为 1000 TIM_SetCounter(TIM2, 1000); 

12.void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
   •功能:该函数设置定时器的自动重载值。当计数器值达到该值时,定时器将自动重置并重新开始计数。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •Autoreload:设置自动重载寄存器的值。



//设置 TIM1 的自动重载值为 5000 TIM_SetAutoreload(TIM1,5000); 

13.FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
   •功能:该函数用于检查定时器的某个标志位是否已经被设置。返回值指示该标志位的当前状态
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_FLAG:指定要检查的标志位。可以是以下常见标志之一:
           TIM_FLAG_Update:定时器溢出(更新事件)标志。
           TIM_FLAG_CC1:通道1捕获比较标志(捕获到上升沿/下降沿置位。CCR == CNT时置位)
           TIM_FLAG_CC2:通道2捕获比较标志。
           TIM_FLAG_CC3:通道3捕获比较标志
           TIM_FLAG_CC4:通道4捕获比较标志
           TIM_FLAG_Trigger:触发事件标志。
           TIM_FLAG_Break:断开事件标志。
   •返回值
      •SET:表示指定的标志位已被设置。
      •RESET:表示指定的标志位未被设置。













14.void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
   •功能:该函数用于清除指定的定时器标志位。通常在处理中断服务时使用
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_FLAG:指定要清除的标志位。可以是以下常见标志之一:
           TIM_FLAG_Update:定时器溢出(更新事件)标志。
           TIM_FLAG_CC1:通道1捕获比较标志。
           TIM_FLAG_CC2:通道2捕获比较标志。
           TIM_FLAG_CC3:通道3捕获比较标志
           TIM_FLAG_CC4:通道4捕获比较标志
           TIM_FLAG_Trigger:触发事件标志。
           TIM_FLAG_Break:断开事件标志。










15.ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
   •功能:该函数用于检查定时器中断标志位的状态,返回该中断是否已经触发。
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_IT:指定要检查的标志位。可以是以下常见标志之一:
           TIM_IT_Update:定时器溢出中断标志。
           TIM_IT_CC1:通道1捕获比较中断标志。
           TIM_IT_CC2:通道2捕获比较中断标志。
           TIM_IT_CC3:通道3捕获比较中断标志。
           TIM_IT_CC4:通道4捕获比较中断标志。
           TIM_IT_Trigger:触发事件中断标志。
           TIM_IT_Break:断开事件中断标志。
   •返回值
      •SET:表示指定的中断标志位已被设置(即中断发生)。
      •RESET:表示指定的中断标志位未被设置(即中断未发生)。













16.void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
   •功能:该函数用于清除定时器的中断挂起位。它通常在中断服务中使用
   •参数
      •TIMx:指定的定时器(例如:TIM1, TIM2 等)。
      •TIM_IT:指定要检查的标志位。可以是以下常见标志之一:
           TIM_IT_Update:定时器溢出中断标志。
           TIM_IT_CC1:通道1捕获比较中断标志。
           TIM_IT_CC2:通道2捕获比较中断标志。
           TIM_IT_CC3:通道3捕获比较中断标志。
           TIM_IT_CC4:通道4捕获比较中断标志。
           TIM_IT_Trigger:触发事件中断标志。
           TIM_IT_Break:断开事件中断标志。










在这里插入图片描述

在这里插入图片描述

4、通过定时器中断来设置延迟函数

#include "stm32f10x.h" // Device header void Time_Init(void); void LED_Init(void); void Delay_us(uint64_t us); void Delay_ms(uint32_t ms); static uint32_t count = 0; int main(void) { 
    Time_Init(); LED_Init(); while(1) { 
    GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); Delay_ms(1000); GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); Delay_us(); } } void LED_Init(void) { 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStruct); } /* 定时器的初始化 */ void Time_Init(void) { 
    //1. 使能挂载定时器TIM3的总线时钟 RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3,ENABLE);//复位 RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3,DISABLE);//复位 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能时钟 //2. 使能ARR寄存器的预加载特性 TIM_ARRPreloadConfig(TIM3,ENABLE);//打开预加载特性 //3. 初始化时基单元,这些都是配置影子寄存器中 TIM_TimeBaseInitTypeDef TIMInitStruct; TIMInitStruct.TIM_Prescaler = 71;//配置预分频器PSC TIMInitStruct.TIM_Period = 999;//配置自动重装寄存器ARR TIMInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//配置计数器为向上计数模式 TIM_TimeBaseInit(TIM3,&TIMInitStruct); //4. 收到启动Update事件,必须手动启动,因为配置好了的定时器参数在影子寄存器中 TIM_GenerateEvent(TIM3,TIM_EventSource_Update); //5. 使能Updata中断 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//打开Updata触发的中断源 //6. 配置NVIC NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVICInitStruct; NVICInitStruct.NVIC_IRQChannel = TIM3_IRQn; NVICInitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVICInitStruct.NVIC_IRQChannelSubPriority = 0; NVICInitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVICInitStruct); //7. 使能定时器TIM3 TIM_Cmd(TIM3,ENABLE); } /* 定时器的中断函数,由上面的定时器初始化得,PSC = 71,则分频72倍,72MHz/72 = 1MHz 1MHz代表1s/ = 0.000001s = 1us,所以没间隔1us计数一次。 自动重装器为999,则代表每隔1000 * 1us = 1ms触发一个Update事件,然后产生一个中断。 */ void TIM3_IRQHandler(void) { 
    //判断中断标准位,是谁产生的中断源 if(TIM_GetFlagStatus(TIM3,TIM_FLAG_Update) == SET)//如果是Update产生的中断源 { 
    TIM_ClearFlag(TIM3,TIM_FLAG_Update);//清除中断标准位 count++;//代表每隔1ms,count加1。 } } /* 定义一个ms的延迟函数 */ void Delay_ms(uint32_t ms) { 
    uint64_t time = count + ms; while(count < time); } /* 定义一个us的延迟函数 */ void Delay_us(uint64_t us) { 
    uint64_t time = count * 1000 + TIM_GetCounter(TIM3) + us;//TIM_GetCounter(TIM3)获取计数器计数的值 while(count * 1000 + TIM_GetCounter(TIM3) < time); } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117738.html

(0)
上一篇 2025-11-18 17:26
下一篇 2025-11-18 17:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信