10-STM32 基本定时器TIM

STM32F1定时器资源:

F1系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器。
基本定时器TIM6 和TIM7:
16 位只能向上计数的定时器,只能定时,没有外部 IO

通用定时器 TIM2/3/4/5
①16 位的可以向上/下计数的定时器,可以定时
②可以输出比较
③可以输入捕捉
④每个定时器有四个外部 IO。

高级定时器 TIM1/8:
①16 位的可以向上/下计数的定时器,可以定时
②可以输出比较
③可以输入捕捉
④可以有三相电机互补输出信号
⑤每个定时器有 8 个外部 IO。

基本定时器TIM6/7:

基本定时器的核心是时基

①时钟源
定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB1 预分频器后分频提供,如果 APB1 预分频系数等于 1,则频率不变(72MHz)。库函数中 APB1 预分频的系数是 2,即 PCLK1=36M,所以定时器时钟 TIMxCLK=36*2=72M。

程序中可以看出APB1时钟是由AHB进行2分频得到:72MHz/2= 36MHz

②计数器时钟
定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。PSC 是一个 16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)。 psc是从0开始的

③计数器
计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。

④自动重装载寄存器
自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。

定时时间的计算
定时器的定时时间等于计数器的中断周期乘以中断的次数。

(1)计数器在 CK_CNT 的驱动下,计一个数的时间T= 1/(TIMxCLK/(PSC+1));

(2)重装载值为ARR,则中断周期为 T*ARR

(3)如果在中断服务程序里面设置一个变量 time,用来 记 录 中 断 的 次 数 , 那 么 就 可 以 计 算 出 我 们 需 要 的 定 时 时 间 等 于 : time*T*ARR。

如TIMxCLK=72 000 000, PSC=7199, ARR=49,则一次中断时间是:5ms

结构体:

1 typedef struct
2 {
3   uint16_t TIM_Prescaler;          //16位   预分频值                                
4   uint16_t TIM_CounterMode;   //计数模式(向上、向下...)    基本定时器只能向上,故不用设置                              
5   uint16_t TIM_Period;              //16位  定时器周期        ARR自动重装值        
6   uint16_t TIM_ClockDivision;       //时钟分频 设置定时器时钟 CK_INT 频率与数字滤波器采样时钟频率分频比,基本定时器没有此功能,不用设置                 
7   uint8_t TIM_RepetitionCounter; //重复计数器,只有TIM1和TIM8才有  利用它可以非常容易控制输出 PWM 的个数
8                                        
9 } TIM_TimeBaseInitTypeDef; 

实验代码:

通过TIM6实现基本定时功能使LED翻转

 1 #include "user_timer.h"
 2 #include "user_delay1.h"
 3 
 4 //文件:基本定时器tim6和tim7
 5 //功能:实现5ms定时
 6 
 7 uint8_t Timer_count =0;
 8 //定时器优先级配置函数
 9 static void NVIC_Config(void)
10 {
11     
12      NVIC_InitTypeDef NVIC_InitStructure;
13   //优先级配置
14     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 0--4    0--4
15         
16     NVIC_InitStructure.NVIC_IRQChannel =TIM6_IRQn;  
17     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;  //抢占优先级
18     NVIC_InitStructure.NVIC_IRQChannelSubPriority= 3;  //响应优先级
19     NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; 
20     NVIC_Init(&NVIC_InitStructure);
21 }
22 
23 
24 //定时器配置函数
25 void TIM6_Time_Init(u16 arr,u16 psc)//如arr=49 psc=7199 ---10khz(0.1ms)--5ms
26 {
27     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
28 
29     NVIC_Config();
30     
31     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); //开时钟--APB1时钟为36M, 但是TIM2-7的时钟是由36M的2倍频过来的 72MHz
32     
33     TIM_TimeBaseStructure. TIM_Period = arr;//自动重装值
34     TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数
35     //TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; //设置时钟分割   //基本定时器没有此功能
36     //TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; //默认向上计数
37     TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure); //初始化TIM6
38     
39     TIM_ClearFlag(TIM6,TIM_FLAG_Update); //清除计数器中断标志位
40     TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE );//TIM中断使能
41         
42   TIM_Cmd(TIM6, ENABLE); //使能定时器
43 }
44 
45 
46 /***********中断服务函数************/
47 void TIM6_IRQHandler(void)   
48 {
49   if(TIM_GetITStatus(TIM6, TIM_IT_Update)) //是否产生中断
50    {   
51       Timer_count++;
52          if(Timer_count==200)
53          {
54            GPIOD->ODR ^= GPIO_Pin_2;
55              Timer_count=0;
56          }
57           
60          TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
61    }
62 }
原文地址:https://www.cnblogs.com/darren-pty/p/13992190.html