我編的簡單時鐘用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;
}
}
}
}
}