前言
利用通用定时器TIM3的定时功能实现开发板上的LED灯亮1s,灭1s。本文只讲程序实现,定时器的基本概念和库函数见上一篇文章STM32F407基础教程9——定时器基本概念与库函数
本文所用工程文件百度网盘下载链接:STM32F407工程模板(更新至EXTI).rar
链接: https://pan.baidu.com/s/1Ij4eH7do0bYkzpS_QxONVg 提取码: XTLG
一、文件准备
1、打开工程文件,添加stm32f4xx_tim.c文件到项目工程,因为定时器相关库函数都在该文件中。
【注】stm32f4xx_tim.c文件在工程文件夹下的Driver文件夹下的src文件夹里。
2、在工程文件夹下的Hardware文件新建文件夹TIMER。
3、在Keil中点击File->new,新建文件。点击保存,命名为Timer.c,存放至TIMER文件夹中。同理,新建文件Timer.h,存放至TIMER文件夹中。
4、将Timer.c添加进工程,将头文件Timer.h添加至头文件路径下。
【注】上述步骤已在该文章STM32F407基础教程4——GPIO口之点亮LED灯中详细说明,文本不再赘述此过程。总体效果见下图。
二、程序实现
1、定时器中断使用流程
定时器中断使用流程主要包括三部分,NVIC配置、定时器配置、定时器中断服务程序
(1)NVIC配置(NVIC配置详细内容见STM32F407基础教程6——中断控制)
NVIC配置包括了中断分组设置、中断通道选择、中断优先级设置及使能中断等。
NVIC_InitTypeDef NVIC_InitStructure;//1-定义NVIC结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//2-设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//3-选择TIM3中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//4-设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//5-设置相应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//6-中断使能
NVIC_Init(&NVIC_InitStructure);//NVIC初始化
(2)定时器配置:配置定时器时基单元及开启定时器中断
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //1-定义结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//2-开启TIM3时钟
TIM_TimeBaseStructure.TIM_Period = 10000-1;//3-设置自动重载值ARR
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;//4-设置预分频PSC
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//5-选择计数模式
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);//6-完成初始化
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//7-使能TIM3中更新中断
TIM_Cmd(TIM3,ENABLE);//8-使能定时器TIM3
(3)编写中断服务程序:检测中断标志、中断处理程序、清除中断标志
定时器中断函数名见下表:
void TIM3_IRQHandler(void)
{ //检查是否有TIM3更新中断发生
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{//功能语句
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除中断标志位
}
}
2、Timer.c文件程序如下
void TIM3_Init(){/*1-定义TIM3、NCIV结构体*/NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/*2-开启TIM3时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启TIM3时钟/*3-时基配置*/TIM_TimeBaseStructure.TIM_Period = 10000-1;//自动重装载ARR值TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;//预分频PSC值TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//1分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//完成初始化/*4-使能定时器更新中断*/TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);/*5-NVIC配置*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置中断分组NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//选择TIM3中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//设置抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设置相应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断使能NVIC_Init(&NVIC_InitStructure);//NVIC初始化/*6-使能定时器*/TIM_Cmd(TIM3,ENABLE);}/*TIM3中断服务函数*/void TIM3_IRQHandler(){if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //判断是否为更新中断{GPIO_ToggleBits(GPIOF, GPIO_Pin_9);//翻转IO状态}TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//清除更新中断}
void TIM3_Init(void);
int main(){LED_Init();TIM3_Init();while(1){}}

