51单片机基于定时器的精准呼吸灯

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Goal_zhuimeng/article/details/90574498

51单片机基于定时器的精准呼吸灯

设计目的:实现LED小灯从最暗到最亮再到最暗的循环显示

最暗——最亮——最暗
整个周期为2.88秒(符合呼吸频率)

以下代码可调,可以自己定义时间。 51单片机 P2接LED。

只需要把代码内 Counter = 120;m == 120同时修改为相同的数就行。

设计思路:
定时器T0 实现0.1ms精确定时

将呼吸灯最暗——最亮拆分为120个时间段 每个时间段定时12毫秒(程序中用变量m实现12ms精确定时) 每个时间段之内利用定时器中断显示一个亮度等级

利用高低电平值的比(高低电平之和恒为120),设置不同亮度等级。(程序中用变量BreathBuff 表示亮度等级)

12毫秒 * 120 等级* 2段循环 =2800毫秒

#include<reg52.h>

unsigned char m = 0;						//时间计时

unsigned char BreathBuff;					//周期内高电平持续时间
bit half = 0;								//亮度等级,最亮标志点

int PWM(void);								//作为一个子函数,用于呼吸灯亮度计算


int main(void)
{
	EA = 1;
	TMOD = 0X01;
	TH0 = 0XFF,TL0 = 0X9c;					// 0.1ms 定时
	ET0 = 1; 								//T0中断打开
	TR0 = 1;								//T0定时器打开

	P2 = 0xff; 													

	while(1)
	{
		PWM();
	}
}

int PWM(void)
{
	static unsigned char Counter = 120;				//静态变量,函数内呼吸灯亮度等级刷新
	
	
	if(m == 120)									// 0.1ms*120 = 12ms	12毫秒换一个等级  、	
		m = 0;
		if(half == 0)								// 高电平计数,递减循环
		{								
			Counter--;
			if(Counter == 0)   				// 中点切换					 
			{	
				half = 1;					
			}
		}
		else						    				// 高电平计数递增循环
		{
			Counter++;
			if(Counter == 120)  						// 循环切换
			{	
				half = 0;					
			}
		}
		BreathBuff = Counter;							//将呼吸灯亮度传递出去
	}
	
	return 0;
}


int InterruptTime0(void) interrupt 1				//T0 定时器中断		完成呼吸灯亮度显示
{
	TH0 = 0XFF,TL0 = 0X9c;			//0.1ms 中断
	m++;
	
	if(BreathBuff>1)			//以下代码完成呼吸灯显示      高低电平总数之和恒为120。
	{
			BreathBuff--;
			P2 = 0XFF;
	}
		else				// 12ms完成一个亮度等级显示,一个等级刷新完毕,继续刷新下一个等级。
	{
			P2 = 0X00;
	}
	
}

		
		

以上代码有点多,但是我感觉这样容易理解。

ok,点亮你的呼吸灯吧。

展开阅读全文

没有更多推荐了,返回首页