如果你觉的还不错,请顶一下,好心情在这谢谢各位了--后面有PDF档可以下载
Led 流水灯 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
好心情
关键字:51 定时器 流水灯 pwm
这个是在51c51上看到的,觉得不错,转帖过来看看谁有兴趣做,我准备下周下一下看看,呵呵 http://www.51c51.com/bbs/dispbbs.asp?boardID=6&ID=21466&page=1
要求:1,程序必须调试通过!2 有注释。3 汇编,c不限,4先到先得!
单片机初学者几乎都做的一个实验就是流水灯实验,因为大家都做,所以就觉得很简单,很多人对这个实验几乎不屑。其实要彻底的玩转这个实验也是很不简单的事情,不信看看你能不能应付我下面的实验题:
硬件前提:用51的P1口控制8个LED,1 点亮,0 熄灭。
(1)第1,3,5,7个灯半亮,其余的全亮。
(2)第1个亮1/8,第2个亮2/8,第3个亮3/8,第4个亮4/8,第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮。
(3)来点小难的,所有的灯逐渐从暗到全亮,再由全亮到暗。
(4)最难的:8个灯从第一个开始依次渐亮,直到最后一个。再从最后一个起渐暗,直到第一个。如此循环往复。这才是真正的流水灯
上周做了此题目的第一个问题,现在看看第二个,呵呵,有了第一个的基础,这个就相对简单了,首先我们因为要控制亮度,所以还是要通过PWM来实现,题目可以分成两个部分来实现
第一个:将亮度分为8灯,从1/8到全亮
应为要分成8个等级,所以采用单个定时器来控制更方便,T0工作在模式2--8位自动载入,设定是时间为Ton,定义全局变量LEDflag(uchar型,最大255),为了方便我们定义
周期T = Ton * 255,同样根据人眼的视觉效应我们定义100Hz,周期T = 10ms,Ton =0.0392ms,取整Ton = 0.04ms,T0没中断1次,LEDflag+1,最大255再加就又变成0,采用查询法根据LEDflag的值改变led的状态,就可以改变亮度
第二个:每个灯用不同的亮度
这个比较简单,只要根据需要让每个led亮的时间不一致就可以了,示意图如下
流程图
主程序
T0中断
源程序(C语言):
/****************************************************************************
* (C) Copyright 2008,单片机初学者
* All Rights reserved.
* 项 目 名 称 : EDN51超级流水灯
* 本 文件名称 : ledshow2.c
* 完 成 作 者 : 好心情 QQ:15942526 cat_li8953#qq.com (为了避免垃圾文件,
所以把@改成了#,如果要用邮件联系,请自己改一下^_^)
* 当 前 版 本 : V1.0
* 完 成 日 期 : 2008年3月21日
* 描 述 :
* 此程序实现,流水灯控制第1个亮1/8,第2个亮2/8,第3个亮3/8,
第4个亮4/8,第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮
*
* 我 的 博 客 : http://blog.ednchina.com/cat_li/
*****************************************************************************/
# include
/****************************定义一下,方便使用*******************************/
# define led P0 //led接在P0口
# define Ton 40 //脉宽0.04ms
# define true 1
code unsigned char stop[3] _at_ 0x3B; //Mon51用,绝对地址引用
unsigned char LEDflag = 0; //全局变量,最大255,保存T0中断次数
/*****************************************************************************
** 函数名称: timer_init()
** 入口参数:无
** 出口参数:无
** 功能描述: 定时器初始化,T0模式2,8为自动载入
*****************************************************************************/
void timer_init() //定时器初始化
{
TMOD = 0x02; //T0 方式2,8位自动载入
TH0 = 256 - Ton; //T0初始值
TL0 = 256 - Ton; //重载值
TR0 = true; //启动T0
ET0 = true; //开T0,T1中断
EA = true; //全局中断允许
}
/*****************************************************************************
** 函数名称: time0_int()
** 入口参数:中断1
** 出口参数:无
** 功能描述: 使用工作组0
*****************************************************************************/
void time0_int() interrupt 1 using 0 //T0中断函数,中断1,使用工作组0
{
LEDflag++; //修改LEDflag
}
/*****************************************************************************
** 函数名称: led_show2()
** 入口参数:无
** 出口参数:无
** 功能描述: 根据ledflag的值,点亮led,实际led亮度并不是呈线性变化,根据led亮度
** 状况适当调整case后面的值
*****************************************************************************/
led_show2()
{
switch(LEDflag)
{
case 0: // 全亮 第8个
{
led = 0x00;
break;
}
case 32: // 7/8亮 第7个led
{
led = 0x80;
break;
}
case 64: // 6/8亮 第6个led
{
led = 0xc0;
break;
}
case 96: // 5/8亮 第5个led
{
led = 0xe0;
break;
}
case 128: // 4/8亮 第4个led
{
led = 0xf0;
break;
}
case 160: // 3/8亮 第3个led
{
led = 0xf8;
break;
}
case 192: // 2/8亮 第2个led
{
led = 0xfc;
break;
}
case 224: // 1/8亮 第1个led
{
led = 0xfe;
break;
}
}
}
void main()
{
timer_init();
while(1)
{
led_show2();
}
}
上面 的程序已经实际调试运行通过,有疑问可以和我QQ联系
欢迎大家提意见,:-)
用户42640 2008-4-8 08:38
用户82043 2008-4-7 20:34
用户115267 2008-4-1 22:33
用户42640 2008-3-22 19:19