【TIM】定时器定时中断

文章详细介绍了如何在STM32F10x微控制器中配置TIM定时器,包括时基单元初始化、时钟源选择、中断使能和NVIC配置。在中断服务程序中,实现了每秒自动加计数的功能,同时展示了如何处理中断标志位和清除中断。
摘要由CSDN通过智能技术生成
用到的TIM配置函数
  • TIM_TimeBaseInit();时基单元初始化
  • TIM_TimeBaseStructInit();给结构体变量赋一个默认值
  • TIM_Cmd();使能计数器
  • TIM_ITConfig();使能中断输出控制
///时钟源选择用这里的六个参数
  • TIM_InternalClockConfig();选择内部时钟
  • TIM_ITRxExternalClockConfig();选择ITRx其他定时器的时钟
  • TIM_TIxExternalClockConfig();选择TIx捕获通道的时钟
  • TIM_ETRClockMode1Config();选择ETR通过外部时钟模式1输入的时钟
  • TIM_ETRClockMode2Config(); 选择ETR通过外部时钟模式2输入的时钟
  • TIM_ETRConfig();配置ETR引脚的预分频器、极性、滤波器等参数
  • TIM_PrescalerConfig();用来单独写预分频值
  • TIM_CounterModeConfig();用来改变计数器的计数模式
  • TIM_ARRPreloadConfig();自动重装器预装功能配置
  • TIM_SetCounter();手动写一个计数值
  • TIM_SetAutoreload(); 手动写一个自动重装值
  • TIM_GetCounter();获取当前计数器的值
  • TIM_GetPrescaler();获取当前预分频器的值

编写TIM定时器定时中断代码:以【定时器定时中断】为例

初始化定时器时从左至右参考该图流程
1、完成驱动文件导入操作和编写驱动程序基本代码(参考之前文章)
//TIM定时器不涉及外部硬件,因此将配置文件放在【System】文件夹里
2、在Timer.c中初始化函数 Timer_Init
void Timer_Init(void)
{
//第一步:开启时钟(注意使用APB1的开启时钟函数,因为TIM2是APB1总线的外设
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    
    
//第二部:选择时基单元的时钟源(在stm32f10x_tim.h文件中查找函数)
    TIM_InternalClockConfig(TIM2);//对于定时中断,这里选择为内部时钟源
//时基单元就由内部时钟驱动了
    
    
//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)
    TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//指定下一次更新事件时加载到ARR自动重新加载寄存器中的值  
                                                      //Period【周期】      //ARR取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//指定用于划分TIM时钟的预分频器值    PSC取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//指定重复计数器的值(高级定时器才用得上,本项目给0)
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化时基单元
    
    //TIM_TimeBaseInit会手动生成一个更新事件,导致刚一上电就立刻进入中断(现象:Num一开始不是00000而是00001)
    TIM_ClearFlag(TIM2,TIM_FLAG_Update);//手动清除更新标志位,避免刚初始化完成就进中断
    
//第四步:配置输出中断控制,使能更新中断输出到NVIC(在stm32f10x_tim.h文件中查找函数)
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//开启了更新中断到NVIC的通路
//第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
    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;//指定IRQ通道的抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//指定IRQ通道的响应优先级
    NVIC_Init(&NVIC_InitStructure);
//第六步:启动定时器(在stm32f10x_tim.h文件中查找函数)
    TIM_Cmd(TIM2,ENABLE);
    
//至此定时器就可以开始工作了,当产生更新时,就会触发中断
}
3、在Timer.c中编写中断服务程序函数 TIM2_IRQHandler
在STM32中,中断函数的名字都是固定的,每个中断通道都对应一个中断函数(名字参考启动文件startup_stm32f10x_md.s)
文件中以 IRQHandler结尾的字符串就是中断函数的名字
中断函数都是无参无返回值的
void TIM2_IRQHandler(void)//当定时器产生更新中断时,这个函数就会被自动执行
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
    {
    Num ++;
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
    }
}
4、实现 定时器每秒自动加Num功能
//在maic.c文件中定义一个全局变量uint16_t Num
//中断函数是在Timer模块里,如果在中断函数里写Num++,那么Num就是跨越不同.c文件的变量了
-----------------解决方法一
如果想跨文件使用变量,可以在使用变量的那个文件顶部用【extern】声明要用的变量
extern uint16_t Num;
extern声明变量就是告诉编译器我现在有Num这个变量,请求编译器帮忙在全文件中查找
-----------------解决方法二
直接将Timer.c文件中的中断服务程序函数TIM2_IRQHandler放在main.c的主函数外定义使用,注释掉原来Timer.c的中断函数
//对于定时器而言,这个中断函数就是为别的文件服务的,所以中断函数可以放在使用它的地方
5、在Timer.h中声明初始化函数 Timer_In it
void Timer_Init(void);
//中断函数不用声明,因为中断函数不需要调用,会自动执行
6、在主程序main.c中 #includ"Timer.h"
#include "Timer.h"
7、在主循环之前先初始化外部中断
8、在主循环中编写程序主体
int main(void)
{
    OLED_Init();
    Timer_Init();
    
    OLED_ShowString(1,1,"Num:");
    
    while(1)
    {
        OLED_ShowNum(1,5,Num,5);
        OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);//观察CNT计数器的变化情况
    }
}
void TIM2_IRQHandler(void)//当定时器产生更新中断时,这个函数就会被自动执行
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
    {
        Num ++;
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
    }
}
实现功能:上电后OLED显示从0每隔一秒计数Num+1,CNT显示计数器值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值