基于定时器实现呼吸灯

呼吸灯的关键在于调节led灯的亮度,也就是在肉眼观察不到的情况下调节灯亮的时间占比。在学习中断以后,可以引用定时中断来方便我们调节led灯亮的时间占比

void Delay1us(uint x)		//@11.0592MHz
{
	while(x--)
	{
	_nop_();
	_nop_();
	_nop_();
	}
}

延时函数之一使用了微秒级延时函数,这样既可以在肉眼观察不到的范围内调节时间占比,又能使亮度过度的更丝滑。以下是代码:

#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar led;
sbit led_sel=P2^3;
sbit beep=P3^4;          //蜂鸣器引脚
uint UintCnt,k,flag;
uint dangci=1000;        //档次,档次越大,越丝滑
void Init()
{
	P0M1=0x00;    //0000 0000
	P0M0=0xff;    //1111 1111

	P2M1=0x00;    //0000 0000
	P2M0=0x08;    //0000 1000
	
	EA=1;         //打开总开关
	ET0=1;
	led_sel=1;
	flag=0;
	beep=0;       //蜂鸣器置0
}

void Timer0Init()		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void Delay65ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 3;
	j = 188;
	k = 61;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay1us(uint x)		//@11.0592MHz
{
	while(x--)
	{
	_nop_();
	_nop_();
	_nop_();
	}
}

void main()
{
	Init();
	Timer0Init();
	led=0xff;
	k=0;
	UintCnt=0;
	while(1)
	{
		if(k!=0)
		{
		P0=led;
		Delay1us(k);
		}
		else
		{
			EA=0;//关闭总中断开关,防止下面延时完后,k不是0;
			flag=0;
			Delay65ms();//适量延长熄灭的时间,加强视觉效果
			EA=1;//打开总开关
		}
		if(k==dangci-650)//屏蔽了变换不明显且时间长的部分,650不是固定的,可以自己调试
			flag=1;
		P0=0x00;
		Delay1us(dangci);
	}
}

void time0() interrupt 1
{
	UintCnt++;
	if(UintCnt==10)//控制变换速度,10ms变换一次
	{
		UintCnt=0;
		if(flag==0)
			k++;
		else
			k--;
	}
}

由于蜂鸣器在程序执行过程会响(不知道为什么,可能是因为蜂鸣器与T0同引脚),所以引入beep引脚并置0,到达静音的效果。

(若有不足和错误,还请各位斧正) 

你可能感兴趣的:(STC-B,单片机)