• 新手必看!!超详细!STM32-基本定时器


    一、基本定时器的作用

    1. 定时
    2. 触发输出直接驱动DAC。

    二、基本定时器的框图

    在这里插入图片描述

    以STM32F103系列为例,具体开发板请查看开发手册。

    类别定时器总线位数计数方向预分频系数是否可以产生DMA捕获/比较通道互补输出
    基本定时器TIM6 / TIM7APB116位向上1~65536可以0
    通用定时器TIM2 /TIM3 /TIM4/ TIM5APB116位向上/向下/中央对齐1~65536可以4
    高级定时器TIM1 /TIM8APB216位向上/向下/中央对齐1~65536可以4

    三、基本定时器的寄存器

    1. 控制寄存器-TIMx->CR1

    在这里插入图片描述

    位 0:CEN 计数器使能 (Counter enable)

        0:禁止计数器
        1:使能计数器
    
    • 1
    • 2

    位 1:UDIS 更新禁止 (Update disable)(没有使用中断可以不设置)

       0:使能 更新 (UEV),更新事件可通过以下事件之一生成:(1)计数器上溢(2)将 UG 位置 1
    
       1:禁止 更新UEV。定时到达后不会生成更新事件。
    
    • 1
    • 2
    • 3

    位 2: URS 选择更新请求源 (Update request source)

        0:如果使能了中断或DMA,以下任一事件可以产生一个更新中断或DMA请求。此类事件包括:(1)计数器上溢;(2)将 UG 位置 1
        1:只有计数器上溢才会生成更新中断或DMA请求。
    
    • 1
    • 2

    位 3: OPM 单脉冲模式 (One-pulse mode)

        0:计数器在发生更新事件时不会停止计数
        1:计数器在发生下一更新事件时停止计数(将 CEN 位清零)。
    
    • 1
    • 2

    位 7: ARPE 自动重载预装载使能 (Auto-reload preload enable)

        0: TIMx_ARR 寄存器不进行缓冲(影子寄存器无效)。
        1: TIMx_ARR 寄存器进行缓冲(影子寄存器有效)。
    
    • 1
    • 2

    2. 控制寄存器-TIMx->CR2(用于高级定时器,这里我们先不看。)

    在这里插入图片描述

    3.事件产生寄存器-TIMx->EGR

    在这里插入图片描述
    位 0: 产生更新事件(该位由软件设置,由硬件自动清除)

     0:无作用
     1:重新初始化定时器的计数器并产生对寄存器的更新。
    
    • 1
    • 2

    4. DMA/中断使能寄存器-TIMx->DIER

    在这里插入图片描述

    位 8: 更新DMA请求

        0:禁止更新DMA请求。
    	1:使能更新DMA请求。
    
    • 1
    • 2

    位 0: 更新中断请求

       0:禁止更新中断。
       1:使能更新中断。
    
    • 1
    • 2

    5. 状态寄存器(中断标志)-TIMx->SR

    在这里插入图片描述

    如果清除中断标志位需要软件清0。读取该寄存器的位0来判断是否发生中断。

    位 0: 更新中断标志位

       0:没有发生中断(定的时间还没到)。
       1:发生了中断。如果发生中断,则该位由硬件置1。
    
    • 1
    • 2

    6. 计数器-TIMx->CNT

    在这里插入图片描述

    位 [ 15:0 ]:用于计数,范围0~65535。一般不用设置。基本定时器默认为0开始。

    7. 预分频器-TIMx->PSC

    在这里插入图片描述

    位 [ 15:0 ]: 设置预分频系数。

    8. 自动重装载寄存器-TIMx->ARR

    在这里插入图片描述
    位 [ 15:0 ]: 设置重装载值。

    四、实验

    实验1. 查询方式:用定时器TIM6实现延时1s闪烁LED1灯。
    实验2. 中断方式:用TIM7实现1s反转一次LED灯。

    补:定时时间计算如下:
    注意单位Tout为ms。
    在这里插入图片描述
    arr:重装载值。
    psc:预分频系数。
    Tclk:定时器时钟。基本定时器为72Mhz。

    实验1. 查询方式:利用TIM6实现定时1s的功能。

    在这里插入图片描述

    ●伪代码:

    定时器初始化
    {
    	1.打开APB1定时器6的时钟。
    	2.设置单脉冲模式。
    	3.设置预分频系数。
    	4.设置自动重装载值。
    	5.UG置1,产生更新事件。(将上面的配置更新到寄存器)
    	6.使能计数器。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    因为设置了单脉冲模式,所以当发生更新事件时,就会自动关闭定时器,所以不需要手动关闭。
    ●具体代码:

    void TIM6_Init(u16 psc,u16 arr)
    {
       RCC->APB1ENR |=(0X01 <<4); //1.打开APB1时钟
       TIM6->CR1 |=(0X01 <<3);  //2.设置单脉冲模式。
       TIM6->PSC =psc ; //3.设置分频系数
       TIM6->ARR =arr;  //4.设置装载值(上限值)  
       TIM6->EGR |=(0x01 <<0); //5.UG置1,产生更新事件。(将上面的配置更新到寄存器)
       TIM6->CR1 |=(0x01 <<0); //6.使能计数器
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ●主函数:

    int main()
    {
    	 LED_Init();
    	 while(1)
    	 {
    	   TIM6_Init(999,71); //(999+1)*(71+1)/72000 000 =1000 ms。
    	   LED1=1;
    	   TIM6_Init(999,71);
    	   LED1=0;  
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实验二:中断方式:用TIM7实现1s反转一次LED灯。

    ●伪代码:

    定时器初始化
    {
    	1.打开APB1定时器7的时钟。
    	2.设置影子寄存器--缓冲。
    	3.设置循环模式。
    	
    	4.选择更新请求源。
    	
    	5.设置预分频系数。
    	6.设置自动重装载值。
    	7.UG置1,产生更新事件。(将上面的配置更新到寄存器)
    
        8. 设置中断优先级。
         
        9.使能NVIC控制器。
    	10.使能定时器。
    	11.使能定时器中断。
    	12.使能更新事件。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ●具体代码:

    void TIM7_Init(u16 psc, u16 arr)
    {
    	RCC->APB1ENR |= 1<<5;//1.使能定时器7的时钟
    	TIM7->CR1 |= 1<<7;  //2.TIM7_ARR 寄存器进行缓冲
    	TIM7->CR1&=~(1<<3);//3.计数器在发生更新事件时不会停止计数(循环计数,循环定时)
    
    	TIM7->CR1&=~(1<<2);//4.选择更新请求源,允许①计数器上溢;②将 UG 位置 1 ,这两种情况产生更新事件
    		
    	TIM7->PSC = psc;//5.设置预分频系数。
    	TIM7->ARR = arr;//6.设置自动重装载值。
    	TIM7->EGR |= 1<<0;//7.UG置1,产生更新事件。(将上面的配置更新到寄存器)
    	
    	NVIC_SetPriority(SysTick_IRQn,NVIC_EncodePriority(7-2,1,2));  // 8. 设置中断优先级。
    	
    	NVIC_EnableIRQ(TIM7_IRQn);//9.使能NVIC控制器。
    	TIM7->CR1|=1<<0;// 10.使能定时器。
    	TIM7->DIER |= 1<<0;// 11.使能定时器中断。
    	TIM7->CR1&=~(1<<1);//12.使能更新事件。
    }
    
    void  TIM7_IRQHandler(void)
    {
       if(TIM7->SR&(1<<0))  //判断中断标志是否置1
       {
          TIM7->SR &=~(1<<0);//中断标志清零
          LED=!LED;
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    ●主函数:

    int main(void)
    {
    	LED_Init();
    	TIM7_Init(999,72);
    	while(1)
    	{
    	
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    pandas(综合测试)
    AI数字人:最强声音驱动面部表情模型VideoReTalking
    Java Double toHexString()方法具有什么功能呢?
    sql添加索引
    前端基础面试题八股文
    CityEngine记录1:工程目录
    安装hadoop,并配置hue
    docker部署ES及kibana整个流程
    第60章 ApplicationPart自动集成整体性和独立性插件项
    柏林噪声算法(Perlin Noise)
  • 原文地址:https://blog.csdn.net/qq_48361010/article/details/134478897