我编的简单时钟用298元的单片机学习板测试通。源程序点击下载
/*
这是我看了《十天学会单片机》(郭天祥的教程)第十课时写的,综合了矩阵键盘,串口通信,数码管
动态显示,定时器中断的简单时钟程序。用51电子网买的298元80C51单片机学习板
(/n.asp?id=12519&i=xie343706382)测试时请将p1口用排线连到CZ2上,控制8位
数码管用。P0口用来检测矩阵键盘的,P3.0和P3.1是串口通信用,控制74H164N芯片段选8位数码管。
数码管显示内容为时分秒个两位,按下K16为设置按钮,按一下调节秒数,再按一下调节分钟,再按一
下调节小时。再按下退出,走时。调节时按K1至K10分别代表0到9。
我的QQ343706382,希望有喜欢单片机的朋友。和我联系。
*/
#include
#include
#define uchar unsigned char//宏定义字符型
#define uint unsigned int//宏定义长整型
uchar temp,num,keyzhi;//定义两个变量
//keyzhi,是键盘返回值用来判断按下什么键子了temp和num也是键盘扫描用的临时变量
uchar code table[]={//定义字串数组数码管显示用分别是 0123456789.和全灭,这个数码管是共阳极的
0x12,0xfa,0x1c,0x98,
0xf0,0x91,0x11,0xda,
0x10,0x90,0xef,0xff};
uchar code table2[]={//字串数组 数码管段位用,通74HC164N芯片控制8个数码管,的段显示
0x80,0x40,0x20,0x10,
0x08,0x04,0x02,0x01};
uint count,gnj,wz;//count,用来计算时间,count++18次是一秒。
//gnj,功能键值gnj值为1,设置秒数,为2,设置分钟,为3设置小时。
char miao,shi,fen;//分别代表秒,时,分。
//变量定义结束
void delay()//延时函数,很短的延时
{ ;; }
void delay1(uint x)//延时函数
{
uint a,b;
for(a=x;a>0;a--)for(b=110;b>0;b--);
}
void xianshi(uchar s,uchar f,uchar m)//显示函数,显示格式为,小时,分钟,秒
{
uint ssw,sgw,fsw,fgw,msw,mgw;//分别代表小时,分钟,秒钟的十位和个位
if(m>59)//如果秒数大于59,就显示光标 点闪烁
{
if(wz==1)
{
msw=10;
mgw=miao%10;
}
else
{
msw=miao/10;
mgw=10;
}
}
else
{
msw=m/10;
mgw=m%10;
}
if(f>59)
{
if(wz==1)
{
fsw=10;
fgw=fen%10;
}
else
{
fsw=fen/10;
fgw=10;
}
}
else
{
fsw=f/10;
fgw=f%10;
}
if(s>24)
{
if(wz==1)
{
ssw=10;
sgw=shi%10;
}
else
{
ssw=shi/10;
sgw=10;
}
}
else
{
ssw=s/10;
sgw=s%10;
}
REN=1;//打开74H164N芯片写入口
SBUF=table2[0];//发送数据,数码管第一位亮
delay();
P1=table[ssw];//显示小时的十位
delay1(3);
P1=0xff; //消除数码管光影。
SBUF=table2[1];
delay();
P1=table[sgw];//小时的个位
delay1(3);
P1=0xff;
SBUF=table2[2];
delay();
P1=table[fsw];
delay1(3);
P1=0xff;
SBUF=table2[3];
delay();
P1=table[fgw];
delay1(3);
P1=0xff;
SBUF=table2[4];
delay();
P1=table[msw];
delay1(3);
P1=0xff;
SBUF=table2[5];
delay();
P1=table[mgw];
delay1(3);
P1=0xff;
/* SBUF=table2[6];//调试时用的,
delay();
P1=table[gnj];//显示功能键的值
delay1(3);
P1=0xff;
SBUF=table2[7];
delay();
P1=table[keyzhi];//显示按键的值
delay1(3);
P1=0xff;
*/
REN=0;
}
uchar keyscan() //键盘扫描程序 利用P0口的4×4的矩阵键盘。
{
P0=0xfe;
temp=P0;
num=0;
if (temp!=0xfe)
{
delay1(5);
temp=P0;
if (temp!=0xfe)
{
switch(temp)
{
case 0xee:num=16;
break;
case 0xde:num=12;
break;
case 0xbe:num=8;
break;
case 0x7e:num=4;
break;
}
}
while(temp!=0xfe){temp=P0;}
}
if (num==16)//判断是否要调整时间
{
gnj++;
if(gnj==4)gnj=0;
num=0;
TR0=0;//关定时器
}
P0=0xfd;
temp=P0;
if (temp!=0xfd)
{
delay1(5);
temp=P0;
if (temp!=0xfd)
{
switch(temp)
{
case 0xed:num=15;
break;
case 0xdd:num=11;
break;
case 0xbd:num=7;
break;
case 0x7d:num=3;
break;
}
}
while(temp!=0xfd){temp=P0;}
}
P0=0xfb;
temp=P0;
if (temp!=0xfb)
{
delay1(5);
temp=P0;
if (temp!=0xfb)
{
switch(temp)
{
case 0xeb:num=14;
break;
case 0xdb:num=10;
break;
case 0xbb:num=6;
break;
case 0x7b:num=2;
break;
}
}
while(temp!=0xfb){temp=P0;}
}
P0=0xf7;
temp=P0;
if (temp!=0xf7)
{
delay1(5);
temp=P0;
if (temp!=0xf7)
{
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=9;
break;
case 0xb7:num=5;
break;
case 0x77:num=1;
break;
}
}
while(temp!=0xf7){temp=P0;}
}
P0=0xff;
return num;
}//键盘扫描程序over
void init()//初始化函数
{
shi=23;//小时
fen=59;//分钟
miao=58;//秒钟
TMOD=0x01;//设置定时器工作模式
TH0=(65536-51000)/256;//装初值让它5毫秒中断一次count++
TL0=(65536-51000)%256;
EA=1;//打开总中断
ET0=1;//开定时器中断
TR0=1;//开定时器
}
void main()//主函数
{
uint san;//这个变量是用来显示闪烁效果的
init();//初始化
wz=1;
while(1)//进入大循环
{
if(gnj!=0)//判断设置键
{
wz=1;
while(gnj==1)//功能键=1时设置秒钟
{
if(san<30)//闪烁显示秒
{
xianshi(shi,fen,miao);
}
if(san>40)
{
xianshi(shi,fen,70);//让显示函数,在秒的位置显示点
}
san++;
if(san>60)
{
san=0;
}
keyzhi=keyscan();//调用键盘
if(keyzhi!=0&keyzhi<11)//判断键盘在1到10之间
{
if(wz==1)//wz用来控制设置的是十位还是个位
{
miao=(keyzhi-1)*10;//设置秒十位
if(miao>59)miao=50;
keyzhi=0;
}
if(wz==2)
{
miao=miao+keyzhi-1;//设置个位
keyzhi=0;
wz=0;
gnj++;
}
wz++;
}
}
wz=1;
while(gnj==2)//设置分钟
{
if(san<20)
{
xianshi(shi,fen,miao);
}
if(san>40)
{
xianshi(shi,70,miao);
}
san++;
if(san>60)
{
san=0;
}
keyzhi=keyscan();
if(keyzhi!=0&keyzhi<11)
{
if(wz==1)
{
fen=(keyzhi-1)*10;
if(fen>59)fen=50;
keyzhi=0;
}
if(wz==2)
{
fen=fen+keyzhi-1;
keyzhi=0;
wz=0;
gnj++;
}
wz++;
}
}
wz=1;
while(gnj==3)//设置小时
{
if(san<20)
{
xianshi(shi,fen,miao);
}
if(san>40)
{
xianshi(70,fen,miao);
}
san++;
if(san>60)
{
san=0;
}
keyzhi=keyscan();
if(keyzhi!=0&keyzhi<11)
{
if(wz==1)
{
shi=(keyzhi-1)*10;
if(shi>20)shi=20;
keyzhi=0;
}
if(wz==2)
{
shi=shi+keyzhi-1;
if(shi>23)shi=23;
keyzhi=0;
wz=0;
gnj=0;
}
wz++;
}
}
}
else
{
TR0=1;//打开定时器
}
keyzhi=keyscan();//扫描键盘
xianshi(shi,fen,miao);//显示时分秒
}
}
void timer0() interrupt 1//定时器函数
{
TH0=(65536-51189)/256;
TL0=(65536-51190)%256;
count++;
if(count==18)//加到18正好1秒中
{
count=0;
miao++;//秒加一
if(miao==60)//60秒加一分
{
miao=0;
fen++;
if(fen==60)//60分加一小时
{
fen=0;
shi++;
if(shi==24)//到24小时加以天
{
shi=0;
}
}
}
}
}