今天介绍一个STM32很重要的定时中断,以及一个实例:定时器的定时中断。
#include "stm32f10x.h" // Device header
extern uint16_t Num;
void TIMER_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//´ò¿ªÊ±ÖÓ
TIM_InternalClockConfig(TIM2);//Ñ¡ÔñÄÚ²¿Ê±ÖÓTIM2
TIM_TimeBaseInitTypeDef TIM_Instrcture;
TIM_Instrcture.TIM_ClockDivision=TIM_Channel_1 ;
TIM_Instrcture.TIM_CounterMode=TIM_CounterMode_Up;
TIM_Instrcture.TIM_Period=10000-1;
TIM_Instrcture.TIM_Prescaler=7200-1;
TIM_Instrcture.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_Instrcture);//ÅäÖÃʱ»ùµ¥Ôª
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//¿ªÆô¸üÐÂÖжϵ½NVIC
NVIC_InitTypeDef NVIC_Instructure;
NVIC_Instructure.NVIC_IRQChannel=TIM2_IRQn ;
NVIC_Instructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Instructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_Instructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_Instructure);//ÅäÖÃNVIC
TIM_Cmd(TIM2,ENABLE);//¿ªÆô¶¨Ê±Æ÷
}
void TIM2_IRQHandler(void)//ÖжϺ¯Êý
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
以上是初始化TIM的代码,大家可以自取
接下来我会给大家解析代码
上图是定时器中断的基本结构,我们思路就是沿着这个图将通路打通就可以进行操作了。
第一步:创建工程 .c .h文件
添加TIM的工程文件夹,然后完善基本结构(参照之前的文章)
第二步:打开时钟
上图是定时器的分类,我们这个实例选择的是内部时钟,所以用TIM2,所以打开APB1就可以
第三步:选择时钟源
因为我们是选用的内部时钟,所以选择TIM_InternalClockConfig(TIM2)
这个函数就是用来配置内部时钟的,可以根据实际情况来选择时钟类型。
第四步:配置时基单元(很重要)
在配置时基单元是我们选用TIM_TimeBaseInit函数,配置时跟之前配置GPIO,NVIC一样,设立一个结构体后,引出结构体中各个元素,然后根据实际要求选择。
第一个元素是指定的时钟的划分,就是几分频,这里工程没有要求,选择第一个
第二个元素是选择计数器模式
这个根据实际情况。选择第一个
第三个和第四个就是配置预分频器和自动重装器
这个也是可以调节定时的快慢。(这里我也不是很懂那个换算,频率啥的)不过预分频和自动重装器与实际都有一位的偏差,要减1.
第五个元素也根据自己选择
这样时基单元就配置完成了。
第五步:中断控制输出
我们启用的是TIM2所以将数据填入即可。控制中断送到CPU里面
第六步:配置NIVC(这部分之前有讲过,跟之前一样,我就不赘述了)
第七步:开启定时器
开启TIM2的时钟
至此时钟的初始化就结束了。将头文件放进.h文件中声明一下。开始写中断函数
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
获取中断标志位,进入循环加一后清除中断标志位。
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "TIMER.h"
uint16_t Num;
int main(void)
{
OLED_Init();
TIMER_Init();
OLED_ShowString(1,1,"Num:");
while(1)
{
OLED_ShowNum(1,5,Num,5);
}
}
这里main文件里面的NUM按理是不能放在.C文件里的。但是可以有两种方法跨文件使用变量:第一种在文件声明 extern 变量。第二种:直接将中断函数复制一下放在主函数后面
至此本次实验就完成啦。需要接线图的可以私我噢。