定时器中断TIME
通用定时器配置步骤(TIME2-TIME5)
(1)使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟
(2)初始化定时器参数,包含自动重装值,分频系数,计数方式等
voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
typedef struct
{
uint16_t TIM_Prescaler; //定时器预分频器 1-65535
uint16_t TIM_CounterMode; //计数模式 向上计数,向下计数,向上向下计数三种
uint32_t TIM_Period; //定时器周期
uint16_t TIM_ClockDivision; //时钟分频
uint8_t TIM_RepetitionCounter; //重复计数器
} TIM_TimeBaseInitTypeDef;
了解结构体成员功能后,就可以进行配置,例如:
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_Period=1000; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=35999; //分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
定时器定时时间计算公式如下: Tout= ((per)*(psc+1))/Tclk;
(3)设置定时器中断类型,并使能
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
(4)设置定时器中断优先级,使能定时器中断通道
NVIC初始化库函数是NVIC_Init();
(5)开启定时器
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
(6)编写定时器中断服务函数
TIM4_IRQHandler
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
if(TIM_GetITStatus(TIM4,TIM_IT_Update))
{
...//执行TIM4更新中断内控制
}
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
固件库中还有两个函数是用来读取状态标志位以及清除中断标志位,函 数分别为TIM_GetFlagStatus和TIM_ClearFlag。
编写定时器中断控制程序
本实验所要实现的功能是:通过TIM4的更新中断控制D2指示灯间隔 500ms秒状态取反,主函数控制D1指示灯不断闪烁。程序框架如下:
(1)初始化TIM4,并使能更新中断等
(2)编写TIM4中断函数
(3)编写主函数
time.c
#include "time.h"
#include "led.h"
/*******************************************************************************
* 函 数 名 : TIM4_Init
* 函数功能 : TIM4初始化函数
* 输 入 : per:重装载值
psc:分频系数
* 输 出 : 无
*******************************************************************************/
void TIM4_Init(u16 per,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //开启定时器中断
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//定时器中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4,ENABLE); //使能定时器
}
/*******************************************************************************
* 函 数 名 : TIM4_IRQHandler
* 函数功能 : TIM4中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update))
{
led2=!led2;
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
time.h
#ifndef _time_H
#define _time_H
#include "system.h"
void TIM4_Init(u16 per,u16 psc);
#endif
main.c
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "time.h"
int main()
{
u8 i;
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
LED_Init();
TIM4_Init(1000,36000-1); //定时500ms
while(1)
{
i++;
if(i%20==0)
{
led1=!led1;
}
delay_ms(10);
}
}