【STM32】定时器与PWM的LED控制

发布于:2024-06-07 ⋅ 阅读:(171) ⋅ 点赞:(0)

目录

一、定时器

1.定时器模块的功能

2.STM32定时器类别

3.通用定时器

二、PWM

1.工作原理

2.PWM标准外设库输出配置

三、用定时器计数方式,控制LED以2s的频率周期性亮灭

1.STM32Cube配置

(1)GPIO配置

(2)RCC配置

(3)SYS配置

(4)TIM2配置

(5)Clock配置

(6)项目配置

2.KEil代码编写​编辑

3.实验结果

四、采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒

1.STM32Cube配置

(1)RCC配置

(2)SYS配置

(3)TIM3配置

(4)GPIO配置

2.KEil代码编写

3.程序烧录及实验结果

4.KEil波形图查看


一、定时器

1.定时器模块的功能

STM32定时器模块主要有计数、定时、输入捕获、输出比较这四个功能。其中:

计数:脉冲计数,使用使用微控制器内部的外部时钟(PCLK)来计数,是对固定周期的脉冲信号计数。

定时:时间控制,通过对微控制器内部的时钟脉冲进行计数实现定时功能。

输入捕获:对输入信号进行捕获,实现对脉冲的频率测量,可用于对外部输入信号脉冲宽度的测量,比如测量电机转速。

输出比较:将计数器计数值和设定值进行比较,根据比较结果输出不同电平,用于控制输出波形,比如直流电机的调速。

2.STM32定时器类别

STM32定时器主要分为基本定时器、通用定时器和高级定时器。

下面是STM32定时器的分类比较表:

定时器 基本定时器**(TIM6、TIM7)** 通用定时器**TIMx(x=2~5)** 高级定时器**(TIM1、TIM8)**
计数器类型 16**位,向上** 16**位,向上、向下、向上/向下** 16**位,向上、向下、向上/向下**
预分频系数 1**~65535之间的任意数** 1**~65535之间的任意数** 1**~65535之间的任意数**
输入**/捕获通道** 四个独立通道:输入捕获、输出比较、**PWM生成、单脉冲模式输出** 四个独立通道:输入捕获、输出比较、**PWM生成、单脉冲模式输出**
产生中断**/DMA** 可以 可以 可以
刹车(电机控制) 可以

3.通用定时器

STM32通用定时器TIMx(x=2,3,4,5)主要由时钟源、时钟单元、捕获和比较通道等构成,核心是可编程预分频驱动的16位自动装载计数器。

(1)时钟源

当定时器使用内部时钟时,定时器的时钟源统称为TIMxCLK。TIMxCLK的系统默认的时钟频率为72MHz,但其时钟来源并不相同。

定时器TIM2~TIM7挂接在APB1上定时器TIM1和TIM8挂接在APB2上。

若外部晶振的频率为8MHz,则系统默认的时钟频率为72MHz

APB1预分频器的分频系数设置为2,则PCLK1=36MHz;

APB2预分频系数设置为1,则PCLK2=72MHz,TIM1和TIM8的时钟频率TIMxCLK=72MHz;

Cortex系统时钟由AHB时钟(HCLK)8分频得到,即SysTick的频率为9MHz。

(2)预分频器PSC

可以以1~65535之间的任意数值对时钟源CK_PSC的时钟频率进行分频,输出CK_CNT脉冲供计数器CNT进行计数。

(3)计数器CNT

TIMxCNT是一个16位的寄存器,计数范围为1~65535,可以向上计数、向下计数或向下向上双向计数。

要得到想要的计数值,需要对输入时钟频率进行分频。

当计数值达到设定值时,便产生溢出事件,溢出时产生中断或DMA请求,然后再由自动装载寄存器进行重新加载或更新。

计数器溢出中断属于软件中断,执行相应的定时器中断服务程序。

(4)自动装载寄存器ARR

定时器的定时时间主要取决于定时周期和预分频因子,计算公式为:定时时间=(ARR+1)×(预分频值PSC+1)/输入时钟频率或 T=(TIM_Period +1)*(TIM_Prescaler +1)/TIMxCLK这里ARR+1是因为计数器都是从0开始计数的。

二、PWM

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

1.工作原理

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

通用定时器能同时产生多达4路的PWM输出。

STM32中每个定时器有4个输入通道:TIMx_CH1~TIMx_CH4;每个通道对应1个捕获/比较寄存器TIMx_CRRx,将寄存器值和计数器值相比较,通过比较结果输出高低电平,从而得到PWM信号。

在PWM的一个周期内,定时器从0开始向上计数,在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平;

在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平;

当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。

2.PWM标准外设库输出配置

首先配置PWM输出通道,开启TIM3时钟:

STM32规定了具体的引脚作为PWM输出引脚,选择不同的引脚时,还必须使用重定向功能(Remap)

定时器TIM1的引脚复用功能映像:

复用功能 TIM1_REMAP[1:0] = 00**(没有重映像)** TIM1_REMAP[1:0] = 01**(部分重映像)** TIM1_REMAP**[1:0] = 11(完全重映像)** (1)
TIM1_ETR PA12 PE7
TIM1_CH1 PA8 PE9
TIM1__CH2 PA9 PE11
TIM1_CH3 PA10 PE13
TIM1_CH4 PA11 PE14
TIM1_BKIN PB12(2) PA6 PE15
TIM1_CH1N PB13(2) PA7 PE8
TIM1_CH2N PB14(2) PB0 PE10
TIM1_CH3N PB15(2) PB1 PE12

定时器TIM2的引脚复用功能映像:

复用功能 TIM2_REMAP**[1:0]=00(没有重映像)** TIM1_REMAP**[1:0]=01(部分重映像)** TIM1_REMAP[1:0]=10 (**部分重映像)** (1) TIM1_REMAP[1:0]=11**(完全重映像)** (1)
TIM2_CH1_ETR**(2)** PA0 PA15 PA0 PA15
TIM2_CH2 PA1 PB3 PA1 PB3
TIM2_CH3 PA2 PB10
TIM2_CH4 PA3 PB11

定时器TIM3的引脚复用功能映像:

复用功能 TIM3_REMAP[1:0] = 00**(没有重映像)** TIM3_REMAP[1:0] = 10**(部分重映像)** TIM3_REMAP[1:0] = 11**(完全重映像)** (1)
TIM3_CH1 PA6 PB4 PC6
TIM3_CH2 PA7 PB5 PC7
TIM3_CH3 PB0 PC8
TIM3_CH4 PB1 PC9

三、用定时器计数方式,控制LED以2s的频率周期性亮灭

使用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用,见下图),连接一个LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭。

1.STM32Cube配置

(1)GPIO配置

(2)RCC配置

(3)SYS配置

(4)TIM2配置

(5)Clock配置

(6)项目配置

2.KEil代码编写

添加了如下代码:

  HAL_TIM_Base_Start_IT(&htim2);

添加如下代码:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static unsigned char ledState = 0;
    if (htim == (&htim2))
    {
        if (ledState == 0)
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
        else
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
        ledState = !ledState;
    }
}

3.实验结果

四、采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒

接上,采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整占空比变化到一个满意效果;使用Keil虚拟示波器,观察 PWM输出波形。

1.STM32Cube配置

(1)RCC配置

(2)SYS配置

(3)TIM3配置

(4)GPIO配置

2.KEil代码编写

在main.c中对应位置添加下面的代码:

  /* USER CODE BEGIN 1 */
	uint16_t pwmVal=0;   //PWM占空比  
    uint8_t dir=1;  
  /* USER CODE END 1 */
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
  /* USER CODE END 2 */
while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	  while (pwmVal< 500)
	  {
		  pwmVal++;
		  __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal);    //修改比较值,修改占空比
//		  TIM3->CCR1 = pwmVal;    与上方相同
		  HAL_Delay(1);
	  }
	  while (pwmVal)
	  {
		  pwmVal--;
		  __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal);    //修改比较值,修改占空比
//		  TIM3->CCR1 = pwmVal;     与上方相同
		  HAL_Delay(1);
	  }
	  HAL_Delay(200);
  }
  /* USER CODE END 3 */

3.程序烧录及实验结果

4.KEil波形图查看

波形图如下: