STM32F103C8T6片上外设笔记2——定时器中断
详细,分步介绍了定时器的基本结构,以及代码
一、定时器的简单介绍(例程在结语部分,可以直接跳转)
定时器,一般分为三种,基础定时器,通用定时器和高级定时器。
一般来说,STM32F103的基础定时器为TIM6、TIM7。通用定时器为TIM2~5,高级定时器则为TIM1和TIM8.
在STM32F03C8T6中,有一个高级定时器,为TIM1,三个通用定时器,TIM2、TIM3和TIM4。
这个为基础定时器的框图

这个为高级定时器的框图

由此可见,定时器之间的差距。本笔记,主要介绍的还是通用定时器。对于高级会提上两嘴。
废话不多说,先上手册。

通过手册,我们可以了解通用定时器的主要功能。
二、通用定时器的结构
1、通用定时器的基本结构

分析图框,我们大概可以了解定时器的基本结构
2、通用定时器的计数方式
通用定时器有三种计数模式。
第一种是向上计数模式

第二种是向下计数

还有中央对齐

三、实现定时器中断的代码
1、配置定时器
首先开启和选择时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);//选择内部时钟
之后配置时机单元,用结构体来进行配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择分频倍率,此为不分频
//选择内部时钟的话,不分频的情况下,是72MHZ
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数方式,此为向上计数
//
TIM_TimeBaseInitStructure.TIM_Period = 10000-1;//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//PSC
//这两条确定定时器的定时时间,此为1ms
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//高级定时器才会用到,我们填0
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
注意,对于定时器的定时频率,也就是定时时间,我们可以用这个公式来确定

2、配置中断
接下来对于中断进行配置。
首先使能中断,并将TIM2选择为更新中断
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断,TIM_IT_Update为更新中断
接下来,为中断优先级进行分组。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
然后配置中断的结构体,确定中断通道和优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//配置中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//启用中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
NVIC_Init(&NVIC_InitStructure);
最后一步,使能定时器
TIM_Cmd(TIM2,ENABLE);//使能定时器
3、中断函数
当定时器溢出,就会触发中断,随后就会进入中断函数,并执行中断函数中的代码。当中断函数中的代码执完毕后,程序会回到中断点,继续按照原来的代码进行执行。
打开启动文件,可以在里面找到TIM2的中断函数
void TIM2_IRQHandler(void)
当触发中断,就会进入这个函数。
但是如此还不算万事大吉,我们还要先检查一下中断标志位
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//获取中断标志位并进行判断
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
}
如此,才算真正写完中断,要想让中断执行的代码,写在判断内部即可
四、结语
最后总结一下,定时器是STM32中,功能、结构最复杂的片上外设。
此笔记只是介绍了通用定时器,对于高级定时器,与通用定时器,还要许多不一样的地方。
还需努力进行探索。
要想真正弄明白,还是要对手册进行深度研究。
最后,贴上完整例程
#include "stm32f10x.h" // Device header
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);//选择内部时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择分频倍率,此为不分频
//选择内部时钟的话,不分频的情况下,是72MHZ
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数方式,此为向上计数
TIM_TimeBaseInitStructure.TIM_Period = 10000-1;//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//高级定时器才会用到,我们填0
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断,TIM_IT_Update为更新中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//配置中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//启用中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2,ENABLE);//使能定时器
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
更多推荐



所有评论(0)