//单片机89C51控制,由8个74HC595联级控制60只LED灯,模拟实现的圆盘闹钟的60秒, 按照每秒移动一只LED,计划使用595移位功能
//但是如此之多的595联级移位, 网络上总是找不到先例,自己琢磨了多日还是实现不了, 本人笨拙的程序如下, 希望有此经验的高手
//指教一二,提出我更改!有何妙计! 有缘关注的朋友先感谢了!!!
#include <reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DS= P0^1;
sbit STCP= P0^2;
sbit SHCP= P0^0;
uchar unm1, h,m,second=0;
uchar code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; // 其中一个字节的输出码表
//------延时函数---------------
void delay(uint z)
{
uint x,y;
for(x=0;x<z;x++)
{ for(y=0;y<120;y++);
}
}
//-------1字节数据串行输入---------------
void In595(uchar num)
{
uint j;
for(j=0;j<8;j++)
{ num=table[ ]; //此处若写成unm<<1; 那就是一个灯在一个字节内移位了,8个595的输出口 八处都是同样的移位
DS = CY; // 对于此程序,还要CY标志吗?好像只能代表一个595溢出高位然后写数据,我要求是60口同时输出的
SHCP = 1; // 移位时钟线输出低
SHCP = 0; // 移位时钟线输出
}
}
//-------并行输出-------------------
void Out595()
{
STCP = 0; _nop_();_nop_();
STCP = 1; _nop_();_nop_();
STCP = 0; _nop_();_nop_();
}
//--------所有8个595同时处理------------------------------
void load_595 () // 此处的处理, 就是计划所有口 同时能输出 或60口移位到输出 ??
{ uchar i, j, temp;
for(i=0;i<60;i++) //外循环60个LED又重来
{ for(j=0; j<8+temp;j++) //内循环8个 是一个595的移位循环
for(temp=0;temp<8;temp++)
{ j=table[j+8];
In595(table[j]);
delay(100);
temp++;
if(temp==8)
{temp=0;}
}
}
}
//------初始函数--------------
void init()
{
TMOD=0x01;
TH0=(65536-8000)/256;
TL0=(65536-8000)%256;
EA=1;
ET0=1;
TR0=1;
}
//------T0中断函数-------------
void timer0() interrupt 1
{
unm1++;
TH0=(65536-38000)/256;
TL0=(65536-38000)%256;
if(unm1==16)
{
second++;
Out595(); //每秒锁存输出一次 本人计划的,但不成功
unm1=0;
if(second==60)
{
m++;
second=0;
if(m==60)
{
h++;
m=0;
if(h==24) h=0;
}
}
}
}
//------------主函数-------------------
void main()
{
init();
while(1)
{
TR0=1;
load_595();
}
}
|