STM32——如何配置通用定时器中断

STM32的定时器

STM32F103ZET6一共有8个定时器,其中分别为:

高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。

STM32——如何配置通用定时器中断_第1张图片
STM32——如何配置通用定时器中断_第2张图片
除非APB1的分频系数是1,否则通用定时器的时钟等于APB1时钟的2倍。

默认调用SystemInit函数情况下:
SYSCLK=72M
AHB时钟=72M
APB1时钟=36M
所以APB1的分频系数=AHB/APB1时钟=2
所以,通用定时器时钟CK_INT=2*36M=72M

定时器中断的一般步骤

实例要求:通过TIM3的中断来控制led1的亮灭
硬件:LED——GPIOB,GPIO_Pin_5

  • 1、使能定时器时钟。调用函数:RCC_APB1PeriphClockCmd();
  • 2、初始化定时器,配置ARR、PSC。调用函数:TIM_TimeBaseInit();
  • 3、开启定时器中断,配置NVIC。调用函数:void TIM_ITConfig();NVIC_Init();
  • 4、使能定时器。调用函数:TIM_Cmd();
  • 5、编写中断服务函数。调用函数:TIMx_IRQHandler()。

定时时间的计算公式

决定CK_CNT的频率是由分频系数决定的,分频系数PSC决定了计数器计数一次的时间 t=1/CK_CNT
CK_CNT=CK_INT/(71+1)=1MHz
1/CK_CNT=1us
APB1的预分频系数决定是36MHzx1还是36MHzx2,这里的APB1预分频系数是2则是72MHz
(PSC+1)/72MHz=1us
Arr的重装周期是1~65535,参考寄存器手册,所以不需要减一,分频系数减一,周期不需要

//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!

void LED_Init(void)										
{
     GPIO_InitTypeDef GPIO_InitStructure;
     	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB端口时钟
    	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
     GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5
     GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 输出高 此时状态为灭 低电平亮
}
 
void TIM3_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 			//时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = 1000;		 				//自动重装载寄存器周期的值1/CK_CNT=1us,1000x1us=1ms	
	TIM_TimeBaseStructure.TIM_Prescaler =71; 						//设置用来作为TIMx时钟频率除数的预分频值CK_CNT=CK_INT/(71+1)=1MHz
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		//TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  	//TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 				//根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );						 //使能指定的TIM3中断,允许更新中断
	
	TIM_Cmd(TIM3, ENABLE);  										//使能TIMx					 
}

void NVIC_Init(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 				//设置NVIC中断分组2:2位抢占优先级,2位响应优先级	

 	NVIC_InitTypeDef NVIC_InitStructure;							//中断优先级NVIC设置
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  				//TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  		//先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  			//从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 				//IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  								//初始化NVIC寄存器
}

void TIM3_IRQHandler(void)   										//TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  			//检查TIM3更新中断发生与否
		{
			time++;
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); 				//清除TIMx更新中断标志 
		}
}
 
int main(void)
{		
	delay_init();	    	 										//延时函数初始化	  
	LED_Init();			    										//LED端口初始化
	TIM3_Init();												//1ms的计时
  	NVIC_Init();													//NVIC初始化
  	while(1)
	{
   		if(time==500)												//500x1ms=500ms
   		{
   			LED0=!LED0;
   			delay_ms(200);
   			time = 0;
   		}		   
	}	 
}	 

库函数解析:

定时器参数初始化:

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

typedef struct
{
  uint16_t TIM_Prescaler;        
  uint16_t TIM_CounterMode;     
  uint16_t TIM_Period;        
  uint16_t TIM_ClockDivision;  
  uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef; 

IM_TimeBaseStructure.TIM_Period = 1000; 
TIM_TimeBaseStructure.TIM_Prescaler =71; 
TIM_TimeBaseStructure.TIM_ClockDivision =   TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode =   TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

定时器使能函数: void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

定时器中断使能函数:void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

状态标志位获取和清除:

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

你可能感兴趣的:(STM32单片机)