使用通用定时器实现呼吸灯

呼吸灯的实现原理

呼吸灯本质上是利用加在LED上的电压变化引起的灯的亮度改变,但是我们单片机的电压不能实时调节,也就导致了无法通过调节电压来调节灯的亮度,但是我们可以通过通用定时器控制PWM输出占空比不同的PWM波,来实现施加在灯上电压的时间,进而改变灯的亮度。

想实现呼吸灯,我们就得让PWM的占空比有规律的变化。

CubeMX配置

这里我们首先得查看自己板子上的LED灯原理图,我这里的两个LED灯的引脚分别是PE5,PB5。这两个中只有PB5才有对应的定时器TIM3,所以我这里采用TIM3输出PWM波

通过官方手册我们可以查到,这里的PB5可以部分重映像后复用为TIM3的通道2,这里直接在芯片上找到PB5,选择TIM3_CH2。然后选择开启TIM3,选择PWM CH2即可开启。

 

 

 

基本配置如图

这里完成后我们还得开启时钟,在RCC中选择外部晶振高速模式,然后在时钟树配置为72MHz,点击回车,CubeMX会自动生成其他时钟。最后再在NVIC中打开全局中断,设置优先中断为1,次优先级为0,这样就配置完成了,点击生成代码即可。

代码完成部分

CubeMX已经帮我们完成了时钟、GPIO、TIM等地方的初始化,我们现在需要完成主函数的配置部分,在主函数中调用

HAL_TIM_Base_Start_IT(&htim3); // 这个库函数是开启TIM3的中断

HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2);  // 使用TIM3通道开启PWM

这样主函数部分就配置完成了,但是当我们烧录进单片机中发现只能使LED常亮,这是因为我们还没有实现中断的回调函数,中断发生后中断函数未作出反应,所以我们应该重新实现中断函数(这个函数HAL库中有定义为弱函数,我们得重新实现这个函数),在tim.c文件中实现这个函数。

uint16_t PulseWidth = 0;  // 设置脉宽
uint16_t dirInc = 1;  // 设置脉宽变化方向(1为递增,0为递减)
// 函数名称不能改变,不然中断无法调用这个函数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance != TIM3)  // 判断是否是TIM3引起的中断
		return;
	if(dirInc == 1)  // 判断计数方向,即呼吸灯是变亮还是变灭
	{
		PulseWidth ++;
		if(PulseWidth>=199)  
		{
			PulseWidth = 199;
			dirInc = 0;  // 更改脉宽变化方向
		}
	}
	if(dirInc == 0)
	{
		PulseWidth --;
		if(PulseWidth <=1)
		{
			PulseWidth = 1;
			dirInc = 1;
		}
	}
	// 这个函数用来设置CCR寄存器的值,即修改PWM波的占空比
    // 这个函数是HAL库中定义好的
	__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, PulseWidth);
}

最后烧录进板子,发现LED灯已经可以正常实现呼吸功能了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值