stm32f103——基本定时器与定时器中断

        我们前面已经学过了滴答定时器,那么定时器的原理与它一样,只不过滴答定时器是在内核中的定时器,而定时器是片上外设

        定时器分为:基本定时器通用定时器

而基本定时器所拥有的功能,通用定时器都有。所以,通用定时器内集成了基本定时器。        

        定时器作用:产生一个精准的定时

stm32f03中基本定时器为TIM6和TIM7:

 

 

 ​​​​​​​​​​​​​​

         16位预分频器:将输入进来的72Mhz进行预分频,但是它是16位的,所以它的分配系数范围为1~65535。

        16位自动重装载累加器:用来装载我们设置的计数值。当16位计数单元计数完后,它就将设置的计数值传给计数单元,让计数单元重新开始计数。

        16位计数单元:它的内部就是定时器计数的过程,即从计数值开始计数。其内部的数值是变化的。

定时器的计数值设置:

我们用定时器来定时1s,那么这个计数值我们应该设置为多少?

先来设置16位预分频的分频系数,我们设置为7200。

所以\frac{72000000}{7200}  =  10000HZ,经过预分频后72Mhz变成了10000hz

所以,T =  \frac{1}{f}  =  \frac{1}{10000},即:在10000hz频率下,计数10000次,需要花费1s的时间。换而言之就是,在10000hz频率下,想要延时1s就需要计数10000次。所以,此时计数值我们设置为10000。

所以,计算值设置为多少,需要先知道预分频的系数,才能计算出来。

库函数:

 

 计数模式:

        向上计数:从0计数到计数值

        向下计数:从计数值计数到0 

        中央对模式1:从0计数到计数值 又 从计数值计数到0 

        中央对模式2:从计数值计数到0 又 从0计数到计数值

        中央对模式3:与中央对模式2一样。

 定时器中断源:

        TIM_IT_Update  更新中断:即计数值计数完了,溢出了,此时产生中断。也就是计数溢出中断。注意:只有这个中断源是基本定时器的,其他的都是通用定时器的。

  

标志位: 

        TIM更新标志位:计数器计数溢出后,该标志位置SET,但是是否此时产生中断它是不会去管的。注意:只有这个标志位是基本定时器的,其他的都是通用定时器的。

 清除标志位。

        计数器计数溢出后,产生中断时,该标志位置SET。

        清除标志位。

编程步骤:

基本定时器产生1s延时,编程步骤:
        1》打开时钟-----TIM6 
        2》初始化定时器6
            ----自动重装载累加器的值
            ----预分频器的值
        3》配置中断源-----计数器溢出时,产生定时器中断
        4》配置中断优先级----NVIC初始化
            ----中断通道号----stm32f10x.h
            ----主优先级 
            ----次优先级 
            ----使能 
        5》编写中断服务函数
            void TIM6_IRQHandler(void)
            {
                if(SET==TIM_GetITStatus(TIM6,TIM_IT_Update)){
                    TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
                    ledflag=~ledflag;
                }
            }
            
        6》使能定时器6

编写程序:

//定时器每定时1秒钟,就进入定时器中断

void TIM6_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;
    NVIC_InitTypeDef  NVIC_InitStruct;
    //  1》打开时钟-----TIM6 
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6, ENABLE);

    // 2》初始化定时器6
    TIM_TimeBaseInitStruct.TIM_Period     =10000;
    TIM_TimeBaseInitStruct.TIM_Prescaler  =7200-1;
    TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);

    // 3》配置中断源-----计数器溢出中断
    TIM_ITConfig(TIM6, TIM_IT_Update,ENABLE);

    // 4》配置中断优先级----NVIC初始化
    NVIC_InitStruct.NVIC_IRQChannel   =TIM6_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority        =2;
    NVIC_InitStruct.NVIC_IRQChannelCmd                =ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    // 6》使能定时器6
    TIM_Cmd(TIM6,ENABLE);
}

中断服务函数:

void TIM6_IRQHandler(void)
{
    if(SET==TIM_GetITStatus(TIM6,TIM_IT_Update)){
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
        ledflag=~ledflag;
    }
}

uint8_t ledflag=0;

int main(void)
{
    LED_Config();
    RCC_ConfigTo72M();//将系统时钟配置成72MHZ 
    Systick_Config(72);
    TIM6_Config();
    // 4,如果是程序的第一个中断,需要设置优先级分钟
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    while(1){

        if(0==ledflag){
            LED_CTRL(LEDR,LED_OPEN);
        }else{
            LED_CTRL(LEDR,LED_CLOSE);
        }

    }
}

在配置的过程中,出现的问题:

问题1:在配置TIM_TimeBaseInitTypeDef结构体时,我们发现该结构体里面多了一个成员。如下图红色框:

 仔细一看注释才发现,该成员是用于TIM1和TIM8通用定时器的。所以,我们在配置的时候,又疑问,需要学会先查看注释。

该成员的作用:

        还记得前面滴答定时器中1864的问题吗?这个就是解决类似1864问题的系数。当它为2的时候,计数器需要计数溢出两遍,才会产生中断。当它为3的时候,计数器需要计数溢出三遍,才会产生中断,以此类推。

问题2:为什么预分频器的分频系数设置需要减1? 

         这个是基本定时器中预分频器的寄存器,我们可以看到红框中有一个+1,也就是说我们给该寄存器设置一个16位的值放在PSC[15:1]中,但是硬件会自动再加1。其目的就是防止有人将PSC[15:1]中的值设置为0。因为,由前面可知:分配系数范围为1~65535(即1~0xffff)而不是0~65535。所以,一旦有人设置为0,那么PSC[15:1]中的值实际上是1。

        所以我们设置PSC[15:1]中的值为7200,实际上PSC[15:1]中的值为7200+1 = 7201,但是我们想要的是7200,所以需要-1。所以,我们设置为7200-1 = 7199;此时PSC[15:1]中的值会自动加1,其值为7199+1 = 7200。

问题3:如果我们想再不改变预分频系数和计数值的情况下:每过5秒才改变小灯状态,而不是每过1s就改变小灯状态,那么怎么办?

我们可以修改中断服务函数:当i等于5时,再进入if中去改变小灯状态

中断服务函数:

void TIM6_IRQHandler(void)
{

     static int i = 0;
     if(i == 5){

        if(SET==TIM_GetITStatus(TIM6,TIM_IT_Update)){
                TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
                ledflag=~ledflag;

                i = 0;
        }

     }

     i++;

}

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值