一、stm32定时器

1、定时器简介

定时器就是用来定时的机器,是存在于STM32单片机中的一个外设。其本质就是计数器,只不过 计数器 记录的是STM32的外部情况,所接收的也是外部脉冲,而 定时器 则是由STM32自身提供的一个非常稳定的计数器,这个稳定的计数器就是STM32上连接的晶振部件。

定时器主要功能如下:

2、定时器分类

STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6 )

三种定时器的主要区别如下:

3、通用定时器介绍

STM32的众多定时器中我们使用最多的是高级定时器和通用定时器,而高级定时器一般也是用作通用定时器的功能,下面我们就以通用定时器为例进行讲解,其功能和特点包括:

位于低速的APB1总线上(APB1)
16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。
16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。
4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: 
        ① 输入捕获 

        ② 输出比较

        ③ PWM 生成(边缘或中间对齐模式) 

        ④ 单脉冲模式输出 

可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器): 
        ①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) 

        ②触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) 

        ③输入捕获 

        ④输出比较 

        ⑤支持针对定位的增量(正交)编码器和霍尔传感器电路 

        ⑥触发输入作为外部时钟或者按周期的电流管理

STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。   
使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

二、PWM相关介绍

  PWM(Pulse Width Modulation,脉冲宽度调制)是一种利用脉冲宽度即占空比实现对模拟信号进行控制的技术,即是对模拟信号电平进行数字表示的方法。

  占空比(Duty Cycle),是指在一个周期内,高电平时间占整个信号周期的百分比,即高电平时间与周期的比值: 占空比=Tp/T。

1、工作原理

(1)STM32的定时器除了TIM6和TIM7,其他定时器都可以用来产生PWM输出;

(2)高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出;

(3)通用定时器能同时产生多达4路的PWM输出; STM32中每个定时器有4个输入通道:TIMx_CH1~TIMx_CH4;

(4)每个通道对应1个捕获/比较寄存器TIMx_CRRx,将寄存器值和计数器值相比较,通过比较结果输出高低电平,从而得到PWM信号;

(5)脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。

 如上图所示:在PWM的一个周期内,定时器从0开始向上计数,在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平; 在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平; 当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。

2、PWM的一般步骤

使能定时器和相关IO口时钟。调用函数:RCC_APB1PeriphClockCmd()
RCC_APB2PeriphClockCmd();
初始化IO口为复用功能输出。调用函数:GPIO_Init();
这里是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,所以需要开- 启AFIO时钟,同时设置重映射;调用函数:RCC_APB2PeriphClockCmd();GPIO_PinRemapConfig();
初始化定时器。调用函数:ARR,PSC等:TIM_TimeBaseInit();
初始化输出比较参数。调用函数:TIM_OC2Init();
使能预装载寄存器。调用函数:TIM_OC2PreloadConfig();
使能定时器。调用函数:TIM_Cmd();
不断改变比较值CCRx,达到不同的占空比效果;调用函TIM_SetCompare2()

三、定时器控制LED亮灭

1、工程创建

打开外部时钟,点击 System Core,选择RCC,在右侧弹出的菜单栏中选择Crystal/Ceramic Resonator

选择调试接口,点击 System Core,选择SYS,在右侧弹出的菜单栏中选 Serial Wire

 配置IO口,选择 PB7 作为 LED 灯的阴极输入,将其设置为 GPIO-Output,并改名为LED

配置定时器,选择定时器2来实现定时的功能。选中 TIM2,将定时器2的时钟源设置为内部时钟;设置分频系数为71,向上计数模式,计数周期为50000。
这里将分频系数设置为71,系统处理的时候会自动加1,所以此处进行的是72分频。由于时钟设置为为72MHZ,所以72分频后得到1MHZ的时钟;1MHZ的时钟,计数50000次,得到时间50000/1000000=0.05秒;每隔0.05秒,定时器2产生一次定时中断。这里要设置灯周期性的亮灭,周期为两秒,即亮一秒,灭一秒,则中断产生20次后,改变led的引脚电平。 

配置中断,允许定时器2的中断

配置时钟,将HCLK修改为 72MHz

最后就可生成项目

2、代码编写

在main主函数里面添加定时器启动代码

HAL_TIM_Base_Start_IT(&htim2);

在main主函数后面添加定时器回调中断函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//这里灯亮一秒,灭一秒,则中断产生20次改变一次电平
    static uint32_t time_cnt =0;   //记录中断次数
    if(htim->Instance == TIM2)   
    {
        if(++time_cnt >= 20)   //判断是否已经达到一秒
        {
            time_cnt =0;       //点灯用的中断次数归零
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);    //改变LED所接引脚的电平
        }
    }
    
}

3、实现效果

点亮LED

四、采用PWM模式,实现呼吸灯效果

 1、工程创建

打开外部时钟,点击 System Core,选择RCC,在右侧弹出的菜单栏中选择Crystal/Ceramic Resonator

选择调试接口,点击 System Core,选择SYS,在右侧弹出的菜单栏中选 Serial Wire

配置TIM2
clock source选择internal clock
将 Channel2 设置为 PWM Generation CH2(PWM输出通道2)
Prtscaler (定时器分频系数) 设置为71,即72分频——1MHz
Counter Mode(计数模式)设置为Up(向上计数模式)
Counter Period(自动重装载值) 设置为500,计数器从0向上计数(递增)到自动装载值,然后再次回到0开始计数,并产生一个计数溢出事件.
CKD(时钟分频因子) 设置为No Division (不分频 )

配置USART 

 配置时钟,将 HCLK 设置为 72MHz

 然后就可生成项目

2、代码编写

在 main.c 文件中定义一个变量来记录 pwm 波形的占空比

uint16_t pwm=10; 

在main主函数中添加如下代码

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);

在主函数 while 循环里加入如下代码

 while(pwm<500)
      {
       pwm = pwm + 10;
       __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
       HAL_Delay(20);//延时20毫秒
      }
      while(pwm>0)
      {
      pwm = pwm - 10;
      __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
      HAL_Delay(20);
      }

3、实现效果

呼吸灯


总结

定时器的学习,让我更加深入的了解到stm32的工作原理,同时实现呼吸灯的效果也感觉很有趣。

参考链接:

定时器&PWM应用编程-CSDN博客

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部