这是一个单片机2408点阵时钟电子制作,用单片机直驱点阵,这里用的是STC89C52,驱动能力不是很好,有条件的话用STC12C5A60S,驱动能力已经比较好,屏的亮度会比较高。图中是用STC89C52单片机,直驱三个8*8的共阳点阵屏,亮度还基本可以,白天看都很清楚!P0口需要接上1K的上拉电阻,P1-P3口分别接三个8*8屏的阴极,用去了单片机的全部32个I/O口。为了能调时间,P2口的P2.0-P2.6接屏的1-7列,P2.7口接一个按扭作于调时间,调整方法: 长按一次是进入调时状态,短按是加1,长按二次是调分,短按是加1,长按3次回复正常状态! 感兴趣的爱好者可以动手实践一下,体验一下电子制作点阵时钟的乐趣。
//单片机点阵电子钟C语言程序
//MCU:STC89C52RD 晶振频率:12MHZ
//编写:桃源客 日期:2010-06-7
//电子小制作整理http://www.5imcu.net/转载请保留。
#include
#include
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit KEY=P2^7; //时调整键
uchar keymode; //键状态
uchar keydate; //键值,
uint keycount; //键延时值
unsigned char c=0; //时分调整位置变量,0不调,1时调时,2时调分
bit D7,D6; //键值有效,长按标志,
bit SHAN; //闪烁标志位
uchar second,minute,hour; //定义秒、分、时寄存器
//以下字模与ASCII对应是,只要将 'A'-0x20就可以得到A的字模了
//高8*5宽 ASCII码
//采用"字模提取软件V2.2"
//提取方式:纵向取模,字节倒序
uchar code ASCII86[10][5]=
{
{0x3E,0x41,0x49,0x41,0x3E},//0
{0x00,0x42,0x7F,0x40,0x00},//1
{0x72,0x49,0x49,0x49,0x46},//2
{0x21,0x41,0x49,0x4D,0x32},//3
{0x18,0x14,0x12,0x7F,0x10},//4
{0x27,0x45,0x45,0x45,0x38},//5
{0x3C,0x4A,0x49,0x49,0x31},//6
{0x41,0x21,0x11,0x09,0x07},//7
{0x36,0x49,0x49,0x49,0x36},//8
{0x46,0x49,0x49,0x29,0x16},//9
};
uchar code seg[24][3]=
{
{0xfe,0xff,0xff},
{0xfd,0xff,0xff},
{0xfb,0xff,0xff},
{0xf7,0xff,0xff},
{0xef,0xff,0xff},
{0xdf,0xff,0xff},
{0xbf,0xff,0xff},
{0x7f,0xff,0xff},
{0xff,0xfe,0xff},
{0xff,0xfd,0xff},
{0xff,0xfb,0xff},
{0xff,0xf7,0xff},
{0xff,0xef,0xff},
{0xff,0xdf,0xff},
{0xff,0xbf,0xff},
{0xff,0x7f,0xff},
{0xff,0xff,0xfe},
{0xff,0xff,0xfd},
{0xff,0xff,0xfb},
{0xff,0xff,0xf7},
{0xff,0xff,0xef},
{0xff,0xff,0xdf},
{0xff,0xff,0xbf},
{0xff,0xff,0x7f}
}; //P1,P3,P2扫描列选码
uchar disbuf[]={0,0,0,0,0,0};//定义缓冲数组区
void delay(uchar t); //延时函数
void init(); //初始化函数
void display(); //显示函数
[page]
void main()
{
init(); //调用初始化函数
P0=0xff; P1=0x00; P3=0x00; P2=0x00;
for(c=0;c<10;c++) delay(255);
P1=0xff; P3=0xff; P2=0xff; //测试点阵屏全亮3秒.
P0=0x00; P1=0x00; P3=0x00; P2=0x00;
for(c=0;c<10;c++) delay(255);
P1=0xff; P3=0xff; P2=0xff; //测试点阵屏全灭3秒.
P0=0xff; P1=0x00; P3=0x00; P2=0x00;
for(c=0;c<10;c++) delay(255);
P1=0xff; P3=0xff; P2=0xff; //测试点阵屏全亮3秒.
P0=0x00; P1=0x00; P3=0x00; P2=0x00;
for(c=0;c<10;c++) delay(255);
P1=0xff; P3=0xff; P2=0xff; //测试点阵屏全灭3秒.
c=0;
while(1) //主程序循环
{
switch(keymode) //键盘处理程序
{
case 0x00:
if(KEY==0) { keymode=1; keycount=2;}
break;
case 0x01:
if(keycount==0)
{ if(KEY==0)
{ keymode=2; keydate=1;D7=0;} else {keymode=0; break;}
}
else
{
keycount--;
break;}
case 0x02:
if(KEY==1)
{ keymode=0; D7=1; break;}
else
{keymode=3; keycount=50; break; }
case 0x03:
if(KEY==1)
{ keymode=0; D7=1; break;}
else
if(keycount==0)
{ keymode=4; D6=1; break; }
else
{ keycount--; break;}
case 0x04:
if(KEY==1)
{keymode=0; D7=1; break;}
else
break;
default: break;
}
//以下的键值调时间处理
if(D7==1)
{
if(D6==0) {
if(c==1) hour++;
if(hour==24) hour=0;
if(c==2) minute++;
if(minute==60) minute=0;
D7=0; }
else
{c++; if(c>2) c=0; D6=0; D7=0;}
}
disbuf[0]=(second);
disbuf[1]=(second/10);
disbuf[2]=(minute);
disbuf[3]=(minute/10);
disbuf[4]=(hour);
disbuf[5]=(hour/10);
display(); //调用显示函数
}
}
void init()
{
TMOD=1;TH0=0X3C;TL0=0XB0; //定时器0模式1,50毫秒
ET0=1;TR0=1;EA=1; //开定时器0中断、启动定时器0、开总中断
}
void display( )
{
unsigned char i,j=0; //j为列位置变量
for(i=0;i<5;i++) //时十位
{
if(disbuf[5]==0) P0=0x00; //时十分为0时不显示
else P0=ASCII86[disbuf[5]];
P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
delay(1);
P1=0xff; P3=0xff; P2=0xff;
j++;
}
j++; //隔一列
for(i=0;i<5;i++) //时个位
{
if(c==1&&SHAN)P0=0x00;
else P0=ASCII86[disbuf[4]]; //调时状态时个位闪烁
P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
delay(1);
P1=0xff; P3=0xff; P2=0xff;
j++;
}
if(!SHAN) {P0=0x81;} else P0=0x00; //秒闪
P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
delay(1);
P1=0xff; P3=0xff; P2=0xff;
j++;
for(i=0;i<5;i++) //分十位
{
P0=ASCII86[disbuf[3]];
P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
delay(1);
P1=0xff; P3=0xff; P2=0xff;
j++;
}
j++;
for(i=0;i<5;i++) //分个位
{
if(c==2&&SHAN)P0=0x00;
else P0=ASCII86[disbuf[2]]; //调分状态时分闪烁
P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
delay(1);
P1=0xff; P3=0xff; P2=0xff;
j++;
}
}
void delay(uchar t)
{
uchar i; //定义变量
for(;t>0;t--) //如果t大于0,t减1(外层循环)
for(i=124;i>0;i--); //i等于124,如果i大于0,i减1
}
void timer0() interrupt 1 //定时器0(中断1)
{
uchar tim1,tim2; //定义临时变量
TL0=TL0+0XB0;TH0=0X3C; //重装定时器初值
tim1++; //每中断一次tim1加1
if(tim1==10) //中断10(0.5秒)
{
SHAN=!SHAN; //闪烁标志取反
tim1=0;tim2++; //tim1清零,tim2加1
if(tim2==2) //到了1秒
{
tim2=0;second++; //tim2清零,秒加1
if(second>=60) //如果秒到60
{
second=0;minute++; //秒变0,分加1
if(minute>=60) //如果分到60
{
minute=0;hour++; //分变0,时加1
if(hour>=24) hour=0; //如果时到24,时变0
}
}
}
}
}