hal库利用PWM制作呼吸灯

实验目的

使用TIM3和TIM4,分别输出一个PWM波形,PWM的占空比随时间变化,去驱动你外接的一个LED以及最小开发板上已焊接的LED(固定接在 PC13 GPIO端口),实现2个 LED呼吸灯的效果。

实验材料

硬件

  • STM32F103C8T6最小开发板
  • CH340模块
  • LED灯一个
  • 杜邦线若干
  • 面包板一块

软件

  • KEIL5
  • FLYMCU

实验原理

呼吸灯,就是指灯光设备的亮度随着时间由暗到亮逐渐增强,再由亮到暗逐渐衰减, 很有节奏感地一起一伏,就像是在呼吸一样。要控制 LED 灯达到呼吸灯的效果,实际上就是要控制 LED 灯的亮度拟合呼吸特性曲线。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KazyWMNN-1667782846011)(E:\学习资料\嵌入式作业\12_hal_pwm\5.png)]

因为引脚要么输出1,要么0,没有“慢慢升高或降低”这一说法,因此要实现呼吸灯,需要使用到PWM。所谓PWM,就是通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。

以正弦信号为例,通过一系列不同的脉冲宽度的信号,可以等效地得到正弦信号:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OwC6hSLa-1667782846011)(E:\学习资料\嵌入式作业\12_hal_pwm\6.png)]

对于呼吸特性曲线,也一样可以用这种方法拟合,让LED灯阴极引脚输出呼吸特性曲线的等效脉冲信号波形,就可以实现呼吸灯。

项目制作

CubeMX初始化

1、时钟配置

在这里插入图片描述
在这里插入图片描述
按上图依次配置,将PCLK1配置为36MHz。

2、定时器配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cp2qXP2n-1667782846013)(E:\学习资料\嵌入式作业\12_hal_pwm\3.png)]

因为实验要求控制两个LED,因此我使用TIM3与TIM4进行输出PWM。上图以配置TIM3介绍过程。

点击TIM3,再勾选内部时钟,并选择通道2输出PWM。这里也可以选用其他通道,不过这会导致PWM输出的GPIO口不同,要注意一下。

再选择分频为71,计数为500。这里的计数不用写太大。

配置一下项目路径与名称,以及使用的ide,生成项目。

代码实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UbgCNWJm-1667782846013)(E:\学习资料\嵌入式作业\12_hal_pwm\4.png)]

源码在这里:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);
	uint16_t status = 0;
	int16_t duty_num = 0;
  while (1)
  {
		HAL_Delay(50);
		if (status == 0){
			duty_num = duty_num + 17;
			if(duty_num > 500)
			{
				status = 1;
				duty_num = 493;
			}
		}
		else{
			duty_num = duty_num - 17;
			if(duty_num < 17)
			{
				status = 0;
				duty_num = 17;
			}
		}
		
		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,duty_num);
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_2,duty_num);

  }

}

呼吸灯有两个过程,一个过程是慢慢亮灯,一个是慢慢灭灯。一个周期中低电平占比越多,灯就越亮。这里变量duty_num用来设置一个周期中高电平的时间。我的定时器一个周期计数个数为500,因此duty_num的范围就是0-500之间。

想要慢慢变亮,就慢慢降低高电平所占一个周期的时间,即每隔一段时间降低duty_num的值;想要慢慢变暗,就慢慢提升高电平所占一个周期的时间,即每隔一段时间增大duty_num的值。

那每次增大多少呢?

主循环第一行,设置的每50ms改一次占空比。首先要知道你想让一个呼吸灯亮灭的周期是多少,比如我想让led灯一呼一吸是3秒,那么就是3000ms,要设置60次占空比。

前面说过,呼吸灯有两个过程,一个过程是慢慢亮灯,一个是慢慢灭灯,两个过程时间一样,那么每个过程要设置30次占空比。设置占空比就是设置高电平在一个中断周期中所占时间,前面说了一个中断周期数500个数,灯最亮的时候高电平时间为0,为了30次将0变成500,每次让duty_num增大500/30,就是17。灯由灭变亮同理。

知道了每次duty_num变化量,那么就可以将新的duty_num值用于设置高电平计数个数。

但是由于每次是加17,因此当493加到510时,会超过一个中断周期的500计数,因此要检测溢出。如果检测到duty_num为510,就改成500,并开始逐渐减小。

因为减小的时候是500开始减,每次减17,因此最后会出现负数。也要做一样的操作。

实验现象

接3.3V到面包板外围,LED灯正极接面包板正极,阴极接TIM3的PWM输出口;拿一个杜邦线一端插入TIM4的PWM输出口,另一端插入PC13口(自带的LED灯阴极是这个口)。

连接好串口模块,烧录程序,发现外接的LED与自带的LED一起变成了呼吸灯:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qHJznfqE-1667782846014)(E:\学习资料\嵌入式作业\12_hal_pwm\1.gif)]

总结

使用PWM来拟合呼吸波曲线,来控制LED灯的亮度。使用HAL库配置定时器,使定时器按照占空比输出高低电平。并以一定时间间隔修改占空比。

参考资料

http://www.mcublog.cn/stm32/2021_01/stm32cubemx-pwm-huxideng/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值