1 )TIM3时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能 TIM3 时钟
** **
2 )初始化定时器参数,设置自动重载值,分频系数,计数方式等
voidTIM_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;
**第一个参数 TIM_Prescaler 是用来设置分频系数的
第二个参数 TIM_CounterMode 是用来设置计数方式
可以设置为向上计数,向下计数方式还有中央对齐计数方式,比较常用的是向上计数模式 TIM_CounterMode_Up 和向下计数模式 TIM_CounterMode_Down。
第三个参数是设置自动重载计数周期值
第四个参数是用来设置时钟分频因子。
针对 TIM3 初始化范例代码格式:TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 5000;
TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
**
3 )设置 TIM3_DIER 允许更新中断。
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState;
第一个参数是选择定时器号,这个容易理解,取值为 TIM1~TIM17。
第二个参数非常关键,是用来指明我们使能的定时器中断的类型
第三个参数就很简单了,就是失能还是使能。TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
**
4 )TIM3 中断优先级设置。
利用 NVIC_Init 函数 初始化nvic
5 )允许 TIM3 工作,也就是使能 TIM3 。
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
**TIM_Cmd(TIM3, ENABLE); //使能 TIMx 外设
**
6 )编写中断服务函数。
用来读取中断状态寄存器的值判断中断类型的函数是:ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t);
该函数的作用是,判断定时器 TIMx 的中断类型 TIM_IT 是否发生中断。比如,我们要判断定
时器 3 是否发生更新(溢出)中断,方法为:if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
固件库中清除中断标志位的函数是:void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
该函数的作用是,清除定时器 TIMx 的中断 TIM_IT 标志位,TIM3 的溢出中断发生后,我们要清除中断标志位,方法是:TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
固件库还提供了两个函数用来判断定时器状态以及清除定时器状态标
志位的函数 TIM_GetFlagStatus 和 TIM_ClearFlag,他们的作用和前面两个函数的作用类似。只
是在 TIM_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而
TIM_GetFlagStatus 直接用来判断状态标志位。
timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
timer.c
#include "timer.h"
#include "led.h"
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
LED1=!LED1;//DS1翻转
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
TIM3_Int_Init(5000-1,8400-1); //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms
while(1)
{
LED0=!LED0;//DS0翻转
delay_ms(200);//延时200ms
};
}