STM32定时器及输出PWM完成呼吸灯

一、STM32定时器原理

定时器就是计数器,定时器的作用就是设置一个时间,然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能,还可以实现捕获脉冲宽度,计算PWM占空比,输出PWM波形,编码器计数等。

STM32的定时器分为基本定时器、通用定时器和高等定时器。

在这里插入图片描述

1、基本定时器

功能:作为时基,定时功能。

2、通用定时器

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开始计数的。

3、高级定时器

功能:除具备通用定时器所有功能外,还具备带死区控制的互补信号输出、刹车输入等功能 (可用于电机控制、数字电源设计等)。

二、PWM工作原理

PWM(Pulse Width Modulation,脉冲宽度调制)是一种利用脉冲宽度即占空比实现对模拟信号进行控制的技术,即是对模拟信号电平进行数字表示的方法。
占空比(Duty Cycle),是指在一个周期内,高电平时间占整个信号周期的百分比,即高电平时间与周期的比值:
占空比=Tp/T
在这里插入图片描述

  • STM32的定时器除了TIM6和TIM7,其他定时器都可以用来产生PWM输出;
  • STM32中每个定时器有4个输入通道:TIMx_CH1~TIMx_CH4;
  • 每个通道对应1个捕获/比较寄存器TIMx_CRRx,将寄存器值和计数器值相比较,通过比较结果输出高低电平,从而得到PWM信号;
  • 脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。

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

三、控制LED以2s的频率周期性地亮-灭

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

引脚:GPIOB14
定时器:Tim2

1、STM32CubeMX建立项目

(1)配置RCC
在这里插入图片描述
(2)配置SYS
在这里插入图片描述
(3)选择GPIO引脚
在这里插入图片描述
(4)配置定时器Timer
在这里插入图片描述
(5)配置时钟树
在这里插入图片描述

由上文定时器定时时间的计算方法可知:
T=(ARR+1)×(预分频值PSC+1)/输入时钟频率
此处 ARR=6399 PSC=4999 输入时钟频率=16
T=5000 x 6400/16=2000000us=2s

(6)创建文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、代码编写

(1)在main文件的main函数中 "/* USER CODE BEGIN 2 / … / USER CODE END 2 */"之间加入该代码(省略号部分)

 HAL_TIM_Base_Start_IT(&htim2);

(2)在main文件的main函数中 "/* USER CODE BEGIN 4 / … / USER CODE END 4 */"之间加入该代码(省略号部分)

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

3、运行结果

在这里插入图片描述

四、STM32输出PWM完成呼吸灯

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

1、STM32CubeMX建立项目

(1)配置RCC
(2)配置SYS(前两步与上述一致)
(3)配置定时器Timer3
在这里插入图片描述

在这里插入图片描述
(4)配置时钟树
在这里插入图片描述
(5)创建文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、代码编写

main文件
占空比初始值为0,如果小于500(也就是PWM周期),设置每隔1毫秒,占空比加1;如果大于500,每隔一毫秒减1。

  /* 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、逻辑分析仪

波形
在这里插入图片描述
由波形变化可知:
波形宽度由宽变窄,又由窄变宽对应着LED灯的亮度由暗变亮,又从亮变暗,与实践结果一致

总结

通过本次实验,了解到了可以使用定时器实现时间的控制和如何用PWM完成呼吸灯的设置,开心!!!

参考资料

https://blog.csdn.net/Morzart/article/details/134123197?spm=1001.2014.3001.5506
https://blog.csdn.net/superSmart_Dong/article/details/134565102?spm=1001.2014.3001.5506
https://blog.csdn.net/weixin_55376063/article/details/127595225?spm=1001.2014.3001.5502

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你解答这个问题。 首先,PWM(Pulse-Width Modulation)是一种调制技术,可以用来控制电路中的电压或电流。在呼吸实验中,我们可以使用 PWM 技术来控制 LED 的亮度,实现呼吸效果。 在 STM32 中,可以使用定时器模块来实现 PWM 功能。具体步骤如下: 1. 选择一个可用的定时器模块,并配置其时钟源和预分频器。 2. 配置定时器模块为 PWM 模式,并设置 PWM 的周期和占空比。 3. 配置定时器模块的输出通道,将其连接到 LED 的控制引脚上。 4. 启动定时器模块,开始 PWM 输出。 下面是一个简单的呼吸实验代码示例: ```c #include "stm32f10x.h" #define LED_PIN GPIO_Pin_13 #define LED_PORT GPIOC void delay(uint32_t ms) { uint32_t i; while (ms--) { for (i = 0; i < 1000; i++); } } void led_pwm_breath(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能定时器时钟和 GPIO 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 配置 LED 控制引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); // 配置定时器基本参数 TIM_TimeBaseStructure.TIM_Period = 1000; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 配置定时器输出通道为 PWM 模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); // 启动定时器 TIM_Cmd(TIM1, ENABLE); while (1) { // 增加占空比 for (int i = 0; i <= 1000; i += 10) { TIM_SetCompare1(TIM1, i); delay(10); } // 减小占空比 for (int i = 1000; i >= 0; i -= 10) { TIM_SetCompare1(TIM1, i); delay(10); } } } int main(void) { led_pwm_breath(); return 0; } ``` 在上面的代码中,我们使用 TIM1 定时器模块来控制 LED 的亮度。首先,我们配置 TIM1 的时钟源和预分频器,使其时钟频率为 1MHz。然后,我们将 LED 控制引脚 PC13 配置为推挽输出模式,将其连接到 TIM1 的通道 1 上。 接着,我们配置 TIM1 的输出通道 1 为 PWM1 模式,并设置 PWM 的周期为 1000(即 1kHz),占空比为 50%。最后,我们启动 TIM1 定时器,并在一个无限循环中不断增加和减小 PWM 的占空比,实现呼吸效果。 希望这个例子对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值