单片机入门者必然会从点亮一盏LED灯开始,如果LED数量比较多,就不能使用单个引脚去控制,例如光立方,利用锁存器和人体的视觉暂留效果就可以占用少量引脚实现光立方。
所需材料:STC89C52一个、12MHz晶振一个、30pF瓷片电容两个、按键开关一个、10K色环电阻一个、10uF电解电容一个、10K九脚排阻一个、74HC573锁存器九个、LED灯512个、洞洞板、焊锡丝、导线。
电路结构:每一个灯板有64个LED灯,横向共阴,纵向共阳,各灯板同一行的共阴端连接在一起。单片机P0端与9个573的输入端连接在一起,一个573的输出端与8个灯板的同行共阴端对应连接,另外8个573各与每个灯板的共阳端对应连接,一个573的使能端与P1.0连接,另外8个573的使能端与P2对应连接。
电路分析:先从P0口给控制共阴端的573送入相应数据,再给控制共阳端的573送入相应数据,各个LED的高低电平对应就点亮相应的灯了,用动态扫描的方式就可以出现动态效果。
附上代码:
#include
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
sbit line_LATCH=P1^0;//定义锁存使能端口 行扫描的锁存端口
sbit LATCH1=P2^0;//定义锁存使能端口 第一灯板的字节锁存
sbit LATCH2=P2^1;
sbit LATCH3=P2^2;
sbit LATCH4=P2^3;
sbit LATCH5=P2^4;
sbit LATCH6=P2^5;
sbit LATCH7=P2^6;
sbit LATCH8=P2^7;
void Delay(unsigned int t)
{
while(--t);
}
unsigned char line[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};// 显示行值01234567
//显示程序
void display(unsigned char *Data)
{
unsigned char i;
for(i=0;i<8;i++)
{
DataPort=line[i]; //先给行(灯板的公共端)输入数据
line_LATCH=1; //打开锁存,把数据line[i]放进去
line_LATCH=0; //关闭锁存,阻止外部数据进来
DataPort=Data[i]; //把数组Data[0~7]里的值依次传给第一灯板的573锁存器中
LATCH1=1;LATCH1=0;
DataPort=Data[8+i];LATCH2=1;LATCH2=0;
DataPort=Data[16+i];LATCH3=1;LATCH3=0;
DataPort=Data[24+i];LATCH4=1;LATCH4=0;
DataPort=Data[32+i];LATCH5=1;LATCH5=0;
DataPort=Data[40+i];LATCH6=1;LATCH6=0;
DataPort=Data[48+i];LATCH7=1;LATCH7=0;
DataPort=Data[56+i];LATCH8=1;LATCH8=0;
Delay(200); //扫描间隙延时,时间太长会闪烁,太短会造成重影
DataPort=0xff; // 清空行锁存器里数据,防止出现乱码
line_LATCH=1;line_LATCH=0;
}
}
//点亮所有灯
void light()
{
unsigned int i;
for(i=0;i<5000;i++)
{
DataPort=0x00;
line_LATCH=1;line_LATCH=0;
DataPort=0xff; //把0xff送进锁存器1~8中,使它们的输出引脚都输出高电平,与行锁存器的0x00相对,点亮所有的灯
LATCH1=1;LATCH1=0;
LATCH2=1;LATCH2=0;
LATCH3=1;LATCH3=0;
LATCH4=1;LATCH4=0;
LATCH5=1;LATCH5=0;
LATCH6=1;LATCH6=0;
LATCH7=1;LATCH7=0;
LATCH8=1;LATCH8=0;
}
}
//熄灭所有灯
void dark()
{
unsigned int i;
for(i=0;i<5000;i++)
{
DataPort=0x00;
line_LATCH=1;line_LATCH=0;
DataPort=0x00;
LATCH1=1;LATCH1=0;
LATCH2=1;LATCH2=0;
LATCH3=1;LATCH3=0;
LATCH4=1;LATCH4=0;
LATCH5=1;LATCH5=0;
LATCH6=1;LATCH6=0;
LATCH7=1;LATCH7=0;
LATCH8=1;LATCH8=0;
}
}
void fb()
{
unsigned char i;
unsigned char code fb0[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//定义空间为64的数组并赋值,用以传递给显示子程序
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
unsigned char code fb1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb4[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb5[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb6[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code fb7[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
for(i=0;i<10;i++) display(fb0);//调用显示子程序display,并把数组fb0的数组名作为实参传给指针式形参
for(i=0;i<10;i++) display(fb1);
for(i=0;i<10;i++) display(fb2);
for(i=0;i<10;i++) display(fb3);
for(i=0;i<10;i++) display(fb4);
for(i=0;i<10;i++) display(fb5);
for(i=0;i<10;i++) display(fb6);
for(i=0;i<10;i++) display(fb7);
for(i=0;i<10;i++) display(fb7);
for(i=0;i<10;i++) display(fb6);
for(i=0;i<10;i++) display(fb5);
for(i=0;i<10;i++) display(fb4);
for(i=0;i<10;i++) display(fb3);
for(i=0;i<10;i++) display(fb2);
for(i=0;i<10;i++) display(fb1);
for(i=0;i<10;i++) display(fb0);
}
void main()
{
unsigned char i;
while(1)
{
for(i=0;i<2;i++) fb();
for(i=0;i<20;i++) light();
for(i=0;i<20;i++) dark();
}
}