基本定时器

前言

按定时器的功能可以分为定时,输出比较(输出PWM波),输入捕获(测量输入信号的脉冲宽度,频率),互补输出,按照定时器分类可以分为基本定时器(只有定时功能),通用定时器(有前三个功能),高级定时器(有全部功能),对于我们的F103系列有2个高级定时器TIM1和TIM8,4个通用定时器TIM2/3/4/5,2个基本定时器TIM6和TIM7
基本定时器_第1张图片
基本定时器_第2张图片
基本定时器_第3张图片
基本定时器没有外部的GPIO,不能实现输入捕获和输出比较,只能用来定时,它的时钟来自PCLK1,为72M,可实现1-65536分频, 高级定时器来自APB2,一般也为72M

功能框图

基本定时器_第4张图片
1
该部分为时钟源,上面的图示已经说明基本定时器的时钟源来自PCLK1,为72M,具体定时器的时钟为多少还要看预分频系数为多少
2.
该部分为控制器部分,控制器用于控制定时器的复位,使能,计数,触发DAC,涉及到的寄存器为:CR1/2,DIER,EGR,SR
3
该部分为时基,包括预分频器,计数器,自动重装载寄存器,1-16位的预分频器PSC对内部时钟CK_PSC进行分配之后,得到计数器时钟CK_CNT = CK_PSC/(PSC+1),计数器CNT在计数器时钟的驱动下开始计数,计数一次的时间为1/CK_CNT,所以计数的时间为自动重装载寄存器(ARR+1)乘以1/CK_CNT,特别注意的是PSC和ARR都有影子寄存器,功能框图上有个影子寄存器,影子寄存器的存在起到一个缓冲的作用,用户值->寄存器->影子寄存器->起作用,如果不使用影子寄存器则用户值在写到寄存器之后则里面起作用,由TIMx_CR1:APRE位控制,还有一个是TIM1和TIM8重复计数寄存器(TIMx_RCR),它用来记录计数结束产生的次数,当我们往该寄存器[7:0]位写入x时,则定时器要发生x次计数结束才会发生中断,也就是我们总计数时间为单次计数时间乘以x.
基本定时器_第5张图片
bsp_timer.c

#include "bsp_basrtimer.h"
void NVIC_Config(void)
{
     NVIC_InitTypeDef NVIC_InitStructure;
     // 设置中断组为0
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	
	 // 设置中断来源	
     NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
     // 设置主优先级为 0
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     // 设置抢占优先级为3
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority  = 3;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure);	
}
void Timer_Config(void)
{    
     // 开启定时器时钟,即内部时钟CK_INT=72M
	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
     TIM_TimeBaseInitTypeDef Time_InitStructure;
     // 时钟分频因子1
	 Time_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	 // 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
	 Time_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	 / 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
	 Time_InitStructure.TIM_Period = 999;
	 // 时钟预分频数为
	 Time_InitStructure.TIM_Prescaler = 71;
	 // 重复计数器的值,基本定时器没有,不用管
	 Time_InitStructure.TIM_RepetitionCounter = 0;
	
	  // 初始化定时器
    TIM_TimeBaseInit(TIM6, &Time_InitStructure);
		
		// 清除计数器中断标志位
    TIM_ClearFlag(TIM6, TIM_FLAG_Update);
	  
		// 开启计数器中断
    TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
		
		// 使能计数器
    TIM_Cmd(TIM6, ENABLE);

}
void CONFIG(void)
{
      NVIC_Config();
	 Timer_Config();
} 

main.c

#include "bsp_usart.h"
#include "hseconfig.h"
#include "bsp_basrtimer.h"
__IO uint16_t time  = 0;
int main(void)
{ 
	//uint8_t i=0;
	HseConfig(9);
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	USART1_Init(9600);
	printf("这是一个中断实验\n");
	CONFIG();
  while(1)
	{
	  if(time == 500)
		{
		  time = 0;
			printf("进入中断啦\n");
		}
	
	}
}

中断服务函数

void  TIM6_IRQHandler(void)
{
   if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET)
	 {
	    time ++;
		  TIM_ClearITPendingBit(TIM6,TIM_FLAG_Update);
	 }

}

基本定时器_第6张图片
上述代码定时的时间为500*1ms=500ms

你可能感兴趣的:(STM32)