求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
要资料
 
追随技术信仰

随时听讲座
每天看新闻
 
 
STM32单片机自学教程
0.前言
1.STM32单片机入门
2.STM32开发C语言
3.STM32F1x系统架构
4.STM32单片机系统电路
5.STM32F1x的寄存器
6.STM32开发环境介绍
7.嵌入式开发常见概念简介
8.STM32开发方式(库函数)介绍
9. Keil5-MDK软件简介
10.创建MDK工程-寄存器版
11.创建MDK工程-基于自建库函数
12.STM32标准库简介
13.创建MDK工程-基于标准库版
14.GPIO简介
15.GPIO输入-按键检测
16.GPIO位带操作
17.RCC-STM32时钟配置
18.STM32中断系统概述
19.基本定时器
 

 
目录
 
第19章.基本定时器
来源:CSDN,作者:村里大明白
39 次浏览
3次  

TIM(Timer)定时器是STM32系列微控制器中常用的外设之一,定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。本章开始介绍定时器的相关内容。

19.1 定时器简介

STM32定时器根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。在前面《第17章.RCC-STM32时钟配置》的图17.1-1 STM32时钟树中,我们可以看到有8个定时器,其中定时器1和8挂载在APB2总线上,定时器2-7挂载在APB1总线上。 注意不同型号的STM单片机的资源是不一样的,我们教程用的STM32F103C8T6定时器资源有TIM1/TIM2/TIM3/TIM4,即一个高级定时器和3个通用定时器,没有基本定时器。

图19.1-1 定时器分类

19.1.1 基本定时器

概述:基本定时器TIM6和TIM7是一个16位的只能向上计数的定时器,只能定时,没有外部IO。

作用:基本定时器用于基本的定时功能。不支持输入捕获和输出比较功能,但可以用于驱动DAC(数模转换器)或产生基本的定时中断。

19.1.2 通用定时器

概述:通用定时器TIM2/3/4/5是一个16位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有4个外部IO(可参考前面第三章中的《图3.3-2 STM32F103C8T6各引脚定义》)。

作用:除具备基本定时器所有功能外,还具有输入捕获、输出比较功能。输入捕获功能可用于测量输入信号的频率和脉宽,输出比较功能可产生PWM波形用于电机、舵机控制等场景。

19.1.3 高级定时器

概述:高级定时器TIM1/8是一个16位的可以向上/下计数的定时器,除了具有通用定时器的所有功能外,还支持互补输出、死区时间控制等高级功能,每个定时器有8个外部IO。

作用:主要用于三相电机控制。

19.2 基本定时器框图

学习基本定时器框图会对定时器有一个很好的整体了解,之后的编程也会有一个清晰的思路。

图19.2-1 基本定时器框图

19.2.1 时钟源

如图中标号①部分,定时器要实现计数功能,首先要给它一个时钟源:定时器时钟TIMxCLK,即内部时钟CK_INT。基本定时器时钟挂载在APB1总线,所以它的时钟来自于APB1总线,但是基本定时器时钟不是直接由APB1总线直接提供,而是先经过一个倍频器。当APB1的预分频器系数为1时,这个倍频器系数为1,即定时器的时钟频率等于APB1总线时钟频率;当APB1的预分频器系数≥2分频时,这个倍频器系数就为2,即定时器的时钟频率等于APB1总线时钟频率的两倍,库函数中APB1 预分频的系数是2,即PCLK1=36Mhz,所以定时器时钟TIMxCLK=36*2=72Mhz。

19.2.2 控制器

控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发DAC转换。

19.2.3 时基单元

时基单元包括:预分频器寄存器(TIMx_PSC)、计数器寄存器(TIMx_CNT)、自动重载寄存器(TIMx_ARR)。基本定时器的这三个寄存器都是16位有效数字,即可设置值范围是0~65535。

PSC 预分频器:时基单元中的预分频器PSC,输入CK_PSC来源于控制器部分,实际上就是来自于内部时钟(CK_INT),输出CK_CNT是分频后的时钟,它是计数器实际的计数时钟,通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率的CK_CNT,计算公式如下,公式中PSC是写入预分频器寄存器(TIMx_PSC)的值。

预分频器寄存器(TIMx_PSC)可以在运行过程中修改它的数值,新的预分频数值将在下一个更新事件时起作用。更新事件发生时,会把TIMx_PSC寄存器值更新到其影子寄存器中,才会起作用。

影子寄存器:从上框图看,预分频器PSC后面有一个影子,自动重载寄存器也有个影子,这就表示这些寄存器有影子寄存器。影子寄存器是一个实际起作用的寄存器,不可直接访问。我们可以把预分频系数写入预分频器寄存器(TIMx_PSC),但是预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的值才会被自动写入其影子寄存器中,这时才真正起作用。

自动重载寄存器:自动重装载寄存器ARR是一个16位的寄存器,这里面装着计数器能计数的最大值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。该寄存器及其影子寄存器和PSC预分频器有所不同,自动重载寄存器是否具有缓冲作用还受到ARPE位的控制。当该位置0时,ARR寄存器不进行缓冲,我们写入新的ARR值时,该值会马上被写入ARR影子寄存器中,从而直接生效;当该位置1时,ARR寄存器进行缓冲,我们写入新的ARR值时,该值不会马上被写入ARR影子寄存器中,而是要等到更新事件发生才会被写入ARR影子寄存器,这时才生效。预分频器寄存器则没有这样相关的控制位。

计数器:基本定时器的计数器(CNT)是一个16位递增的计数器,当寄存器(TIMx_CR1)的CEN位置1,即使能定时器,每来一个CK_CNT脉冲,TIMx_CNT的值就会递增加1。当TIMx_CNT值与TIMx_ARR的设定值相等时,TIMx_CNT的值就会被自动清零并且会生成更新事件(如果开启相应的功能,就会产生DMA请求、产生中断信号或者触发DAC同步),如此循环。TIMx_CNT等于TIMx_ARR时,称之为定时器溢出,定时器溢出就伴随着更新事件的发生。

19.3 定时时间的计算

计数器在CK_CNT的驱动下,计一个数的时间则是CK_CNK的倒数,而根据前面公式CK_CNT=TIMxCLK/(PSC+1),那么记一个数的时间为:(PSC+1)/TIMxCLK,产生一次中断的时间则等于:

其中ARR即为自动重载寄存器的值,因为是从0开始计数的,因此公式中需要+1.

下面我们举例说明。我们设置一个10ms周期的定时器更新中断,一般思路是先设置预分频寄存器,然后才是自动重载寄存器。我们内部时钟TIMxCLK为72MHz,我们把预分频系数设置为7200,即写入预分频寄存器的值PSC为7199,那么CK_CNT=72MHz/7200=10KHz。这样就得到计数器的计数频率为10KHz,计数器1秒钟可以计10000个数。所以我们让计数器计数100个数就能满足要求,即需要设置自动重载寄存器的值ARR为99。如果1秒中断的话,那ARR为10000-1=9999即可。

19.4 基本定时器控制寄存器

下面介绍基本定时器(TIM6/TIM7) 的几个重要的寄存器,完整的可以参考《STM32F10x-中文参考手册》。

19.4.1控制寄存器1(TIMx_CR1)

图19.4-1 TIMx_CR1 寄存器

位7(APRE)用于控制自动重载寄存器ARR是否具有缓冲作用,如果ARPE位置1,ARR起缓冲作用,即只有在更新事件发生时才会把ARR的值写入其影子寄存器里;如果ARPE位置0,那么修改自动重载寄存器的值时,该值会马上被写入其影子寄存器中立即生效。

位0(CEN)用于使能或者禁止计数器,该位置1计数器开始工作,置0停止工作。

19.4.2 DMA/中断使能寄存器(TIMx_DIER)

图19.4-2 TIMx_DIER 寄存器

位8(UDE)用于使能或者禁止更新DMA请求,DMA相关内容,我们后面会再单独介绍,这里我们暂且用不到,置0即可。

位0(UIE)用于使能或者禁止更新中断,我们用到中断时,该位需要置1。

19.4.3 状态寄存器(TIMx_SR)

图19.4-3 TIMx_SR 寄存器

位0(UIF)是中断更新的标志位,当发生中断时由硬件置1,然后就会执行中断服务函数,需要软件清零,所以我们必须在中断服务函数里把该位清零。如果中断后,不把该位清零,那么系统会一直进入中断服务函数。

19.4.4 计数器寄存器(TIMx_CNT)

图19.4-4 TIMx_CNT 寄存器

该寄存器就是计数器的实时计数值。

19.4.5 预分频寄存器(TIMx_PSC)

图19.4-5 TIMx_PSC 寄存器

该寄存器是基本寄存器TIM6/TIM7的16位预分频寄存器,写入数值范围0到65535,分频系数为1到65536。

19.5.6 自动重载寄存器(TIMx_ARR)

图19.4-6 TIMx_ARR寄存器

该寄存器可以由前面寄存器TIMx_CR1的APRE位设置是否进行缓冲。计数器的值会和ARR寄存器影子寄存器进行比较,当两者相等,定时器就会溢出,发生更新事件,如果打开更新中断,还会发生更新中断。

19.5 基本定时器相关库函数

基本定时器功能相对较少,后面通用定时器我们还会介绍相关库函数。这里我们先只介绍基本定时器定时中断的相关库函数,DMA等相关的,会在后续DMA等相关章节再介绍。

19.5.1 内部时钟选择函数:TIM_InternalClockConfig

函数名:TIM_InternalClockConfig

函数原形:TIM_InternalClockConfig(TIM_TypeDef*TIMx)

功能描述:设置 TIMx 内部时钟

输入参数:TIMx:x可以是2,3或者4(注:STM32F103C8T6只有4个定时器,没有基本定时器)

举例:

  1. /* Selects the internal clock for TIM2 */
  2. TIM_InternalClockConfig(TIM2);

19.5.2 时基单元配置函数:TIM_TimeBaseInit

函数名:TIM_TimeBaseInit

函数原形:

void TIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct);

功能描述:根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时基单元,即时基单元初始化;

输入参数:

TIM_TypeDef* TIMx:指向定时器实例的指针。STM32系列微控制器包含多个定时器(如TIM1、TIM2等),每个定时器都有自己的一组寄存器。通过该指针,可以指定要初始化的定时器。

TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct:指向TIM_TimeBaseInitTypeDef结构体的指针,该结构体包含了定时器时间基数单元的配置信息。

时基单元初始化结构体介绍如下:

  1. typedef struct {
  2. uint16_t TIM_Prescaler; // 预分频器
  3. uint16_t TIM_CounterMode; // 计数模式
  4. uint32_t TIM_Period; // 定时器周期
  5. uint16_t TIM_ClockDivision; // 时钟分频
  6. uint8_t TIM_RepetitionCounter; // 重复计算器
  7. } TIM_TimeBaseInitTypeDef;

(1)TIM_Prescaler:定时器预分频器设置,时钟源经预分频器PSC后才是定时器时钟,它设定TIMx_PSC寄存器的值。可设置范围为0至65535,实现1至65536分频。

(2)TIM_CounterMode:STM32定时器支持多种计数模式,如向上计数、向下计数、中央对齐计数(通用定时器章节会介绍)等。基本定时器只能是向上计数,即TIMx_CNT只能从0开始递增,并且无需初始化。

(3)TIM_Period:定时器周期,即设定自动重载寄存器的值,在事件生成时更新到影子寄存器。可设置范围为0至65535。

(4)TIM_ClockDivision:时钟分频,设置定时器时钟CK_INT频率与数字滤波器采样时钟频率分频比,基本定时器没有此功能,不用设置。这个值主要有1,2,4分频,扥别对应TIM_CKD_DIV1 ,TIM_CKD_DIV2,TIM_CKD_DIV4.

(5)TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可以非常容易控制输出PWM的个数。基本定时器这里不用设置。

虽然基本初始化结构体有5个成员,但对于基本定时器只需设置预分频器TIM_Prescaler和自动重载寄存器TIM_Period两个就可以。

举例:

  1. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  2. TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
  3. TIM_TimeBaseStructure.TIM_Prescaler = 0xF;
  4. TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  5. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  6. TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);

19.5.3 定时器状态标志位清除函数TIM_ClearFlag

函数名: TIM_ClearFlag

函数原形:

void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

功能描述:TIM_ClearFlag函数用于清除指定的定时器状态标志位。在STM32的定时器中,状态标志位用于指示定时器当前的状态或发生的事件。例如,当定时器计数到自动重装载寄存器(ARR)的值时,会触发更新事件,并设置相应的状态标志位。通过调用TIM_ClearFlag函数,可以清除这些状态标志位,以便进行后续的状态检测或事件处理。

在定时器的中断服务程序或轮询程序中,可以通过检查状态标志位来判断定时器是否发生了特定的事件。在事件处理完毕后,可以使用TIM_ClearFlag函数清除状态标志位,以避免重复处理同一事件。

参数说明:

TIM_TypeDef* TIMx:指向定时器实例的指针。STM32中有多个定时器(如TIM1、TIM2等),每个定时器都有自己的一组寄存器。通过该指针,可以指定要操作的定时器。

uint16_t TIM_FLAG:要清除的状态标志位。不同的定时器有不同的状态标志位,用于指示定时器的不同状态(如更新事件、输入捕获事件等)。对于基本定时器主要是更新事件TIM_FLAG_Update,对于其他的状态在后续定时器章节再介绍。

举例:

  1. TIM_TypeDef* TIMx = TIM3; // 假设使用TIM3定时器
  2. uint16_t TIM_FLAG = TIM_FLAG_Update; // 假设要清除更新事件的状态标志位
  3. // 清除TIM3的更新事件状态标志位
  4. TIM_ClearFlag(TIMx, TIM_FLAG);

19.5.4 中断功能配置TIM_ITConfig

函数名:TIM_ITConfig

函数原形:

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

参数说明:

TIM_TypeDef* TIMx:指向要配置的定时器的指针。STM32系列微控制器包含多个定时器,如TIM1、TIM2等,此参数用于选择具体的定时器。

uint16_t TIM_IT:指定要配置的中断源。STM32定时器的中断源包括更新中断(Update Interrupt)、捕获/比较中断(Capture Compare Interrupt)等。具体的中断源可以通过宏定义来选择,如TIM_IT_Update、TIM_IT_CCx(x=1,2,3,4)等。常见的如下,对于基本定时器来说,只有更新中断TIM_IT_Update。

①TIM_IT_Update:更新中断(或称溢出中断)。当定时器的计数器达到其预设的自动重装载值(ARR)并溢出时,将触发此中断。这是定时器中最基本且常用的中断类型,常用于实现周期性任务或时间测量。

②TIM_IT_CCx(x=1, 2, 3, 4):捕获/比较中断。STM32定时器具有多个捕获/比较通道(通常为4个),每个通道都可以配置为输入捕获或输出比较模式。当捕获/比较通道的输入信号达到预设的阈值或输出信号与预设值匹配时,将触发此中断。这种中断类型常用于信号测量、PWM输出控制等场景。

③TIM_IT_Trigger:触发中断。当定时器的外部触发输入(如ETR、TIx等)满足预设条件时,将触发此中断。这种中断类型通常用于外部信号的同步或触发其他外设的操作。

④TIM_IT_Break:刹车中断(高级定时器)。当定时器的刹车输入信号有效时,将触发此中断。刹车功能通常用于安全相关的应用,如电机控制中的紧急停车。

3.FunctionalState NewState:指定中断的新状态。这个参数是枚举类型FunctionalState,通常有两个取值:ENABLE(启用中断)和DISABLE(禁用中断)。

功能描述:TIM_ITConfig函数用于启用或禁用指定定时器的一个或多个中断源。通过配置这个函数,用户可以在定时器发生特定事件时产生中断,从而在中断服务程序中执行相应的操作。

举例:

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

19.5.5 定时器中断状态获取函数TIM_GetITStatus

STM32定时器的TIM_GetITStatus函数是一个用于检查定时器中断标志位是否被置位的函数。

函数原型:

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

参数说明:

TIM_TypeDef* TIMx:指向要检查的定时器的指针。STM32系列微控制器包含多个定时器,如TIM1、TIM2等,此参数用于选择具体的定时器。

uint16_t TIM_IT:指定要检查的中断标志位。STM32定时器的中断标志位包括更新中断标志(TIM_IT_Update)、捕获/比较中断标志(TIM_IT_CCx,x=1, 2, 3, 4)等。

返回值:函数返回ITStatus类型的值,表示中断标志位的状态。ITStatus通常是一个枚举类型,包含两个取值:SET(表示中断标志位被置位)和RESET(表示中断标志位未被置位)。

功能描述:TIM_GetITStatus函数用于检查指定定时器的指定中断标志位是否被置位。如果中断标志位被置位,则表示相应的中断事件已经发生,此时可以在中断服务程序中执行相应的中断处理代码。

举例:

  1. void TIM2_IRQHandler(void) {
  2. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
  3. // 处理定时器更新中断
  4. // ...
  5. // 清除中断标志位
  6. TIM_ClearFlag(TIM2, TIM_IT_Update);
  7. }
  8. }

19.5.6 定时器使能函数TIM_Cmd

TIM_Cmd是用于控制定时器(TIM)外设的使能(ENABLE)或失能(DISABLE)状态的函数。

函数原型:

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

参数说明:

TIM_TypeDef* TIMx:这是一个指向定时器结构体的指针,用于选择要操作的定时器。STM32微控制器通常有多个定时器(如TIM1、TIM2等),通过该参数可以选择具体的定时器。

FunctionalState NewState:这是一个枚举类型的参数,用于指定定时器的状态。它通常有两个取值:

ENABLE:使能定时器,即启动定时器的工作。

DISABLE:失能定时器,即停止定时器的工作。

功能描述:TIM_Cmd函数的主要功能是控制定时器的使能或失能状态。当NewState参数为ENABLE时,函数将启动指定的定时器,使其开始计数或执行其他配置的任务。当NewState参数为DISABLE时,函数将停止指定的定时器,使其停止计数或执行其他任务。

举例:

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

19.5.7 清除中断待处理标志位函数TIM_ClearITPendingBit

函数原形:

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

参数说明:

TIM_TypeDef* TIMx:指向定时器实例的指针。STM32中有多个定时器实例,如TIM1、TIM2等,通过此参数可以指定要操作的定时器。

uint16_t TIM_IT:指定要清除的中断标志位。这个参数通常是一个宏定义,代表特定的中断类型,如更新中断、捕获比较中断等。

功能描述:TIM_ClearITPendingBit函数的功能是清除指定定时器的指定中断待处理标志位。当定时器发生某个中断事件并启用了相应的中断时,中断待处理标志位会被置位。通过调用此函数,可以清除相应的中断待处理标志位,从而告知中断控制器该中断事件已经被处理。

TIM_ClearITPendingBit函数通常在定时器中断服务程序(ISR)中使用。当中断服务程序被调用时,表示定时器已经发生了某个中断事件。在中断服务程序中,除了处理中断事件外,还需要清除相应的中断待处理标志位,以确保中断控制器能够正常接收后续的中断请求。

举例:

  1. /* Clear the TIM2 Capture Compare 1 interrupt pending bit */
  2. TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

19.6 基本定时器应用案例

本章我们主要学习基本定时器的定时中断功能,基本定时器没有外部IO口,只能用内部时钟。我们练习的案例也很简单,就是通过基本定时器的定时中断,实现LED灯以1秒为周期进行亮灭。我们直接在前面章节EXTI的例程上修改即可,LED接在PB1口上。由于我这边用的开发板没有基本定时器TIM6-7,因此我们用基本定时器TIM2模拟该功能即可。

本例程大致思路如下,通过定时器10ms触发一次中断,并进行计次,主函数判断记次为100(1秒时间)时反转LED灯。

19.6.1 编程步骤

(1)开定时器时钟;

(2)初始化时基单元初始化结构体;

(3)使能定时器TIMx,的更新update中断;

(4)打开定时器;

(5)编写中断服务函数;

19.6.2 硬件相关宏定义配置

LED灯部分这里就不讲了,直接全部copy 《第15章.GPIO输入-按键检测》中的LED.c和LED.h.

我们硬件相关配置推荐使用宏,这样是方便后期更改的,只用改头文件,其他函数都不用修改。除了硬件相关的配置,参数配置也推荐用宏。同时我们前面知道这几个定时器,APB1和APB2上都有,这样一些配置函数也是可得通过宏来指定,如RCC_APB1PeriphClockCmd函数名可以指定给一个宏。这样不管硬件怎么变,都可以只修改宏定义即可,非常便于移植。我们建立BaseTIM.h头文件,代码如下:

  1. #ifndef __BASETIM_H
  2. #define __BASETIM_H
  3. #include "stm32f10x.h"
  4. /*定时器TIM参数定义*/
  5. #define BASIC_TIM TIM2//定时器选择
  6. #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd//定时器对应总线
  7. #define BASIC_TIM_CLK RCC_APB1Periph_TIM2//总线对应时钟
  8. #define BASIC_TIM_Period 100-1//自动重载计数器
  9. #define BASIC_TIM_Prescaler 7200-1//分频器
  10. #define BASIC_TIM_IRQ TIM2_IRQn//中断号
  11. #define BASIC_TIM_IRQHandler TIM2_IRQHandler//中断服务函数
  12. /*
  13. 我们内部时钟TIMxCLK为72MHz,我们把预分频系数设置为7200,即写入预分频寄存器的值PSC为7199,
  14. 那么CK_CNT=72MHz/7200=10KHz。这样就得到计数器的计数频率为10KHz,计数器1秒钟可以计10000个数。
  15. 所以我们让计数器计数100个数就能10ms中断一次,即需要设置自动重载寄存器的值ARR为99。
  16. */
  17. /*函数声明*/
  18. void BASIC_TIM_Init(void);
  19. #endif /* __BASETIM_H */

19.6.3 定时器相关配置函数

在BaseTIM.c文件主要进行定时器初始化配置,NVIC配置。如下代码:BASIC_TIM_Init()函数包含了NVIC和定时器初始化配置函数,这样后续调用这一个函数就可以实现初始化;

  1. #include "BaseTIM.h"
  2. /* 中断优先级配置*/
  3. static void BASIC_TIM_NVIC_Config(void)
  4. {
  5. NVIC_InitTypeDef NVIC_InitStructure;
  6. // 设置中断组为0
  7. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  8. // 设置中断来源
  9. NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;
  10. // 设置主优先级为 0
  11. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  12. // 设置抢占优先级为0
  13. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  14. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  15. NVIC_Init(&NVIC_InitStructure);
  16. }
  17. /*定时器配置*/
  18. static void BASIC_TIM_Mode_Config(void)
  19. {
  20. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  21. BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);// 开启定时器时钟,BASIC_TIM_APBxClock_FUN即为APB1的时钟
  22. TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period; // 自动重装载寄存器的值
  23. TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;// 时钟预分频数
  24. TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;// 时钟分频因子 ,基本定时器没有,可不用管
  25. TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
  26. //TIM_TimeBaseStructure.TIM_RepetitionCounter=0;// 重复计数器的值,只有高级定时器有,可不用管
  27. /* 初始化定时器*/
  28. TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
  29. /*清除计数器中断标志位*/
  30. TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
  31. /* 开启计数器中断*/
  32. TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
  33. /* 使能计数器*/
  34. TIM_Cmd(BASIC_TIM, ENABLE);
  35. }
  36. void BASIC_TIM_Init(void)
  37. {
  38. BASIC_TIM_NVIC_Config();
  39. BASIC_TIM_Mode_Config();
  40. }

19.6.4 定时器中断服务函数

在中断服务文件stm32f10x_it.c文件中加入如下中断服务函数:

  1. void BASIC_TIM_IRQHandler (void)
  2. {
  3. if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET )
  4. {
  5. counter++;
  6. TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);
  7. }
  8. }

相关例程文件已经上传

 


您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



39 次浏览
3次