求89c52 8位双向流水灯程序,各种花样显示,急急急!

如题所述

第1个回答  2016-10-07
我自己写的LED花样闪烁程序,请参考。
/*----------------------------------------------------------
按键S2、S3为LED灯闪动花样选择键(S2、S3选择顺序相反,可循环),
S4、S5为闪动速度选择键(按S4加速、S5减速),启动后默认按花样
1(单个灯从左到右循环)闪动。闪动间隔有50、100、200、400、
800ms可选。
-----------------------------------------------------------*/
#include <REGX52.H>
#include <intrins.h>
#include <stdlib.h>
#define uchar unsigned char
#define uint unsigned int
sbit s2=P3^4; //定义四个按键
sbit s3=P3^5;
sbit s4=P3^6;
sbit s5=P3^7;
uchar mod,modnum,p1_val,speed,keyflag,num0,num,l_r,state;
/*---------------------变量含义----------------------------

mod:闪动花样代码; modnum:共有几种闪动花样;
p1_val:用于赋初值; speed:标记闪动速度;
keyflag:花样按键按下标记; num0:计算延时几个50ms;
num:花样内其他计数用; l_r:标记闪动方向
state:标记花样变化状态 t0num:T0中断次数
----------------------------------------------------------*/
uchar code mod4[]={ //用于花样4
0x7e,0xbd,0xdb,0xe7};
/*-----------------------延时子函数-----------------------*/
void delayxms(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
/*-----------------------按键子函数-----------------------*/
void keyscan()
{
if(s2==0) //检测按键S2
{
delayxms(10); //防抖延时
if(s2==0)
{
keyflag=1; //花样按键按下时,标记状态为1
mod++; //闪动花样标志+1
if(mod>modnum) //设置花样循环选择
mod=1;
num0=0;
}
while(!s2); //等待按键释放
}
if(s3==0) //检测按键S3
{
delayxms(10);
if(s3==0)
{
keyflag=1;
mod--; //闪动花样标志-1
if(mod<1)
mod=modnum;
num0=0;
}
while(!s3);
}
if(s4==0) //检测按键S4
{
delayxms(10);
if(s4==0)
{
speed/=2; //提高闪动速度
if(speed<1)
speed=1;
}
while(!s4);
}
if(s5==0) //检测按键S5
{
delayxms(10);
if(s5==0)
{
speed*=2; //降低闪动速度
if(speed>16)
speed=16;
}
while(!s5);
}
}
/*-----------------------初始化函数-----------------------*/
void init()
{
modnum=6; //用于修改共有几种闪动花样
mod=1; //启动按花样1闪动
speed=16; //启动按最慢速度闪动
keyflag=1; //启动后默认标志为1
EA=1; //开总中断
ET0=1; //开T0中断
TMOD=0x01; //设置T0为16位定时器
TH0=(65536-50000)/256; //赋初值50ms
TL0=(65536-50000)%256;
TR0=1; //启动T0
}
/*-------------------------主函数-------------------------*/
void main()
{
init();
while(1)
{
keyscan(); //一直扫描按键
switch(mod) //根据花样标志值选择闪动花样
{
/*-----------------【1】循环左移流水灯--------------------*/
case 1:
if(keyflag) //当花样按键按下时重置P1口、
{ //花样按键标志状态
keyflag=0;
P1=0xfe;
}
if(num0>=speed) //延时到达选定的时间时,变化LED状态
{
num0=0; //清零延时计数值
P1=_crol_(P1,1); //循环左移
}
break;
/*-----------------【2】循环右移流水灯--------------------*/
case 2:
if(keyflag)
{
keyflag=0;
P1=0x7f;
}
if(num0>=speed)
{
num0=0;
P1=_cror_(P1,1); //循环右移
}
break;
/*---------------【3】1357和2468交替闪烁------------------*/
case 3:
if(keyflag)
{
keyflag=0;
P1=0xaa;
}
if(num0>=speed)
{
num0=0;
P1=~P1; //交替闪烁
}
break;
/*-----------------【4】两边合拢再散开--------------------*/
case 4:
if(keyflag)
{
keyflag=0;
num=0;
l_r=0; //用于指示灯变化的方向
}
if(num0>=speed&&l_r==0)
{
num0=0;
P1=mod4[num];
num++;
if(num==3)
l_r=1;
}
if(num0>=speed&&l_r==1)
{
num0=0;
P1=mod4[num];
num--;
if(num==0)
l_r=0;
}
break;
/*-------【5】逐个点亮,全亮后反向逐个熄灭,左右循环-------*/
case 5:
if(keyflag)
{
keyflag=0;
p1_val=0xfe;
num=0;
l_r=0;
}
if(state==0)
{
if(num0>=speed&&l_r==0) //从左到右逐个点亮
{
num0=0;
P1=p1_val;
p1_val<<=1;
if(p1_val==0)
l_r=1;
}
if(num0>=speed&&l_r==1) //全亮后从右到左逐个熄灭
{
num0=0;
P1=p1_val;
num++;
switch(num)
{
case 1:
p1_val=0x80;
break;
case 2:
p1_val=0xc0;
break;
case 3:
p1_val=0xe0;
break;
case 4:
p1_val=0xf0;
break;
case 5:
p1_val=0xf8;
break;
case 6:
p1_val=0xfc;
break;
case 7:
p1_val=0xfe;
break;
case 8:
p1_val=0xff;
break;
}
if(p1_val==0xff)
{
state=1;
l_r=0;
p1_val=0x7f;
num=0;
}
}
}
else
{
if(num0>=speed&&l_r==0) //从右到左逐个点亮
{
num0=0;
P1=p1_val;
p1_val>>=1;
if(p1_val==0)
l_r=1;
}
if(num0>=speed&&l_r==1) //全亮后从左到右逐个熄灭
{
num0=0;
P1=p1_val;
num++;
switch(num)
{
case 1:
p1_val=0x01;
break;
case 2:
p1_val=0x03;
break;
case 3:
p1_val=0x07;
break;
case 4:
p1_val=0x0f;
break;
case 5:
p1_val=0x1f;
break;
case 6:
p1_val=0x3f;
break;
case 7:
p1_val=0x7f;
break;
case 8:
p1_val=0xff;
break;
}
if(p1_val==0xff)
{
state=0;
l_r=0;
p1_val=0xfe;
num=0;
}
}
}
break;
/*-----------------------T0中断函数-----------------------*/

void time0() interrupt 1 //延时50ms
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num0++; //延时计数值
}本回答被网友采纳
第2个回答  2016-01-23
还要吗
相似回答