基于STC89C52单片机的霓虹灯

基于STC89C52单片机的霓虹灯

1、设计要求

        使用PWM驱动8个LED灯

        人眼不能观察到灯光全灭

        灯光要有动画效果

2、设计概述

        本实验所用芯片为STC89C52,所用硬件是由华清远见基于STC89C52开发的智能小车,该小车具有流水灯模块、蜂鸣器模块、独立键盘模块、矩阵键盘模块等。这里着重介绍流水灯模块,流水灯模块共有八个不同颜色的LED灯,由主控芯片STC89C52的P1端口八个引脚分别控制。此外,STC89C52不具备PWM的硬件模块,所以需要自己写程序模拟PWM方波,PWM就是脉冲宽度调制的缩写,方波高电平时间跟周期的比例叫占空比,例如1s钟内高电平占0.5s,占空比就是50%。

3、原理图以及线路连接

        本实验只需要用到智能小车的核心板,不需要连接线。下图为流水灯模块的原理图

4、要求分析和参考代码

        首先是第一、二条要求 :使用PWM驱动8个LED灯

                                                人眼不能观察到灯光全灭

        由于没有PWM的硬件模块,要用软件实现PWM的话首先就得用到定时器,所以先把定时器要用到的功能设置好。下面是参考代码,首先先把led灯全部灭掉,然后是设置定时器,这里用到的是STC89C52的定时器0,因为方式2的定时是最精准的,在这里也够用,所以设置定时器0的工作方式为方式2;然后就是初值的设置,这里我们设置的周期为100us,也就是每100us进入一次中断,由方式2的初值计算公式 256 - X = 100 解得初值X为156;然后就是将定时器0的中断允许位以及总中断的中断允许位置1,开启总中断以及定时器0中断,最后TR0置1,开启定时器。

void neon()
{
	P1 = 0xFF;		//初始将led灯全部灭掉

	TMOD = 0x02;	//定时器0设置方式2

	TH0 = 156;		//设置进入中断函数的周期
	TL0 = 156;

	EA = 1;			//总中断以及定时器0中断允许位置1
	ET0 = 1;

	TR0 = 1;		//开启定时器0
}

        定时器功能设置好之后就是中断函数了,同样对照参考代码,逐条解释

        这里time就是一个无符号变量,每进入一次中断函数就+1,当time==99时,我们就将P1口全部置0,也就是开启LED灯,当time等于100时,我们将P1口全部置1,也就是关闭LED灯,同时将time清0,这样就能实现循环,每进入100次中断,就是一个周期,由于定时器设置的进入中断时间是100us,进入100次的时间也就是100us × 100 = 10ms,由于时间是极短的,人眼不能察觉到它的变化,这样我们就实现使用PWM驱动8个LED灯以及人眼不能观察到灯光全灭的要求。

void inter_timer0(void) interrupt 1
{
	time++;
	if(99 == time)			  //这里值越大,灯光越暗
		P1 = 0;
	if(100 == time)
	{	
		P1 = 0xff;
		time = 0;
	}	
}

最后的要求就是 灯光要有动画效果

        首先,要有动画效果的话,八个灯的亮度就不能是一致的,不然就看不到灯光的变化,这里,就只要把上面代码中的 P1 = 0xff 改为 P1 = 0xfe ,这样,在P1口置1的时候,P1.0口就不会置1,led0也就不会灭,而其他的led1~led7都会灭掉,这样就静态的显示了一盏灯亮,其他灯相对较暗的效果,但这样还是静态的,要有动画效果,就要让相对较亮的这盏灯不断地移动,要达到这个效果,就只要动态的改变P1口的值就行了,这里设置一个变量t,对应P1口的值,然后动态改变t的值,同时设置一个变量i,表示较亮的灯在当前位置停留的时间。当停留时间足够,即i==10,以后,首先将i清0,然后将i左移,由原先的0000 0001变为0000 0010,然后取反,变成1111 1101,这样较亮的灯,就从led0,变成了led1,然后不断左移,当t==0x80,也就是

1000 0000之后,将t重新置1,不断循环,这样就达到了动态的效果。。

void inter_timer0(void) interrupt 1
{
	time++;
	if(99 == time)			  //这里值越大,灯光越暗
		P1 = 0;
		//P1 = ~t;
	if(100 == time)
	{	//P1 = 0;
		P1 = ~t;
		time = 0;
		i++;
		if(10 == i)			  //通过改变这个值的大小可以改变灯变化的速度
		{
			i = 0;
			if(t < 0x80)		  
				t = (t << 1);
			else if(t == 0x80)
				t = 1; 

		}
	}	
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值