#include<reg51.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
int b=0;//有符號標志位
uint8 gewei;//個位
uint8 shiwei;//十位
uint8 a[6]; //用來存儲時,分,秒的個位和十位的"動態數組"
uint8 code number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint8 keyNum=0;//按鍵掃描后得到的鍵值從1到16
static uint8 miao=0;//秒
static uint8 fen=30;//分
static uint8 shi=12;//時
uint16 counter;
sbit ADDR0=P2^2;
sbit ADDR1=P2^3;
sbit ADDR2=P2^4;
void delay()/***********************延時函數*****************************/
{
uint16 i=800;
while (i--);
}
void timer1_init()/*****************定時器1初始化***********************/
{
TMOD|=0X10 ;
TMOD&=0XDF;
TH1=0XFC;
TL1=0X67;
TR1=1;
}
void int_init()/*********************定時器1溢出中斷初始化**************/
{
ET1=1;
EA=1;
}
void key_deal()/*********************每個按鍵對應的單擊事件(共4*4=16個按鍵)********/
{
switch(keyNum)
{
case 1 :switch(b)//數字0
{
case 1:miao=miao/10*10+0;break;
case 2:miao=miao%10+0*10;break;
case 3:fen=fen/10*10+0; break;
case 4:fen=fen%10+10*0; break;
case 5:shi=shi/10*10+0; break;
case 6:shi=shi%10+10*0; break;
default:break;
}
break;
case 2 : switch(b)//+加號鍵
{
case 0:break;
case 1:shiwei=miao/10;gewei=miao%10;if(gewei==9) gewei=0; else gewei++; miao=shiwei*10+gewei;keyNum=0;break;
case 2:shiwei=miao/10;gewei=miao%10;if(shiwei==5) shiwei=0;else shiwei++;miao=shiwei*10+gewei;keyNum=0;break;
case 3:shiwei=fen/10; gewei=fen%10; if(gewei==9) gewei=0; else gewei++; fen=shiwei*10+gewei;keyNum=0; break;
case 4:shiwei=fen/10; gewei=fen%10; if(shiwei==5) shiwei=0;else shiwei++;fen=shiwei*10+gewei;keyNum=0; break;
case 5:shiwei=shi/10; gewei=shi%10;
if(shiwei<2&&gewei<9) {gewei++; goto zz1;}
if(shiwei<2&&gewei==9) {gewei=0; goto zz1;}
if(shiwei>1&&gewei==3) {gewei=0; goto zz1;}
if(shiwei>1&&gewei<3) {gewei++; goto zz1;}
zz1:
shi=shiwei*10+gewei;keyNum=0; break;
case 6:shiwei=shi/10; gewei=shi%10; if(gewei<4&&shiwei==2) {shiwei=0; goto zz2;}
if(gewei<4&&shiwei<2) {shiwei++; goto zz2;}
if(gewei>3&&shiwei==1) {shiwei=0; goto zz2;}
if(gewei>3&&shiwei<1) {shiwei++; goto zz2;}
zz2:
shi=shiwei*10+gewei;keyNum=0; break;
default :break;
}
break;
case 3 :switch(b)//-減號鍵
{
case 0:break;
case 1:shiwei=miao/10;gewei=miao%10;if(gewei==0) gewei=9; else gewei--; miao=shiwei*10+gewei;keyNum=0;break;
case 2:shiwei=miao/10;gewei=miao%10;if(shiwei==0) shiwei=5;else shiwei--;miao=shiwei*10+gewei;keyNum=0;break;
case 3:shiwei=fen/10; gewei=fen%10; if(gewei==0) gewei=9; else gewei--; fen=shiwei*10+gewei;keyNum=0; break;
case 4:shiwei=fen/10; gewei=fen%10; if(shiwei==0) shiwei=5;else shiwei--;fen=shiwei*10+gewei;keyNum=0; break;
case 5:shiwei=shi/10; gewei=shi%10; if(shiwei<2&&gewei==0) {gewei=9; goto xx1;}
if(shiwei<2&&gewei>0) {gewei--; goto xx1;}
if(shiwei>1&&gewei==0) {gewei=3; goto xx1;}
if(shiwei>1&&gewei>0) {gewei--; goto xx1;}
xx1:
shi=shiwei*10+gewei;keyNum=0; break;
case 6:shiwei=shi/10; gewei=shi%10; if(gewei<4&&shiwei==0) {shiwei=2; goto xx2;}
if(gewei<4&&shiwei>0) {shiwei--; goto xx2;}
if(gewei>3&&shiwei==0) {shiwei=1; goto xx2;}
if(gewei>3&&shiwei>0) {shiwei--; goto xx2;}
xx2:
shi=shiwei*10+gewei;keyNum=0; break;
default :break;
}
break;
case 5 :switch(b)//數字3
{
case 1:miao=miao/10*10+3;break;
case 2:miao=miao%10+3*10;break;
case 3:fen=fen/10*10+3; break;
case 4:fen=fen%10+10*3; break;
case 5:shi=shi/10*10+3; break;
default:break;
}
break;
case 6 :switch(b)//數字6
{
case 1:miao=miao/10*10+6;break;
case 3:fen=fen/10*10+6; break;
case 5:if(shi/10<2) shi=shi/10*10+6; break;
default:break;
}
break;
case 7:switch(b)//數字9
{
case 1:miao=miao/10*10+9;break;
case 3:fen=fen/10*10+9; break;
case 5:if(shi/10<2) shi=shi/10*10+9; break;
default:break;
}
break;
case 9 :switch(b)//數字2
{
case 1:miao=miao/10*10+2;break;
case 2:miao=miao%10+2*10;break;
case 3:fen=fen/10*10+2; break;
case 4:fen=fen%10+10*2; break;
case 5:shi=shi/10*10+2; break;
case 6:if(shi%10<4) shi=shi%10+10*2; break;
default:break;
}
break;
case 10 :switch(b)//數字5
{
case 1:miao=miao/10*10+5;break;
case 2:miao=miao%10+5*10;break;
case 3:fen=fen/10*10+5; break;
case 4:fen=fen%10+10*5; break;
case 5:if(shi/10<2) shi=shi/10*10+5; break;
default:break;
}
break;
case 11:switch(b)//數字8
{
case 1:miao=miao/10*10+8;break;
case 3:fen=fen/10*10+8; break;
case 5:if(shi/10<2) shi=shi/10*10+8; break;
default:break;
}
break;
case 12: --b;if(b<0) b=6; keyNum=0;break;//移位鍵,向右移一位
case 13 :switch(b)//數字1
{
case 1:miao=miao/10*10+1;break;
case 2:miao=miao%10+1*10;break;
case 3:fen=fen/10*10+1; break;
case 4:fen=fen%10+10*1; break;
case 5:shi=shi/10*10+1; break;
case 6:shi=shi%10+10*1; break;
default:break;
}
break;
case 14 :switch(b)//數字4
{
case 1:miao=miao/10*10+4;break;
case 2:miao=miao%10+4*10;break;
case 3:fen=fen/10*10+4; break;
case 4:fen=fen%10+10*4; break;
case 5:if(shi/10<2) shi=shi/10*10+4; break;
default:break;
}
break;
case 15:switch(b)//數字7
{
case 1:miao=miao/10*10+7;break;
case 3:fen=fen/10*10+7; break;
case 5:if(shi/10<2) shi=shi/10*10+7; break;
default:break;
}
break;
case 16: ++b;if(b>6) b=0; keyNum=0;break;//移位鍵,向左移一位
default:break;
}
}
void refresh_led()/***************************數碼管刷新函數************************/
{
static uint8 j=0;
switch(j)
{
case 0:if(b==1){ADDR0=0;ADDR1=0;ADDR2=0;j++;if(counter<500) P0=number[a[0]]; else P0=0x00;}
else{ADDR0=0;ADDR1=0;ADDR2=0;j++;P0=number[a[0]];}break;
case 1:if(b==2){ADDR0=1;ADDR1=0;ADDR2=0;j++;if(counter<500) P0=number[a[1]]; else P0=0x00;}
else{ADDR0=1;ADDR1=0;ADDR2=0;j++;P0=number[a[1]];}break;
case 2:ADDR0=0;ADDR1=1;ADDR2=0;j++;P0=0x40;break;
case 3:if(b==3){ADDR0=1;ADDR1=1;ADDR2=0;j++;if(counter<500) P0=number[a[2]]; else P0=0x00;}
else{ADDR0=1;ADDR1=1;ADDR2=0;j++;P0=number[a[2]];}break;
case 4:if(b==4){ADDR0=0;ADDR1=0;ADDR2=1;j++;if(counter<500) P0=number[a[3]]; else P0=0x00;}
else{ADDR0=0;ADDR1=0;ADDR2=1;j++;P0=number[a[3]];}break;
case 5:ADDR0=1;ADDR1=0;ADDR2=1;j++;P0=0x40;break;
case 6:if(b==5){ADDR0=0;ADDR1=1;ADDR2=1;j++;if(counter<500) P0=number[a[4]];else P0=0x00;}
else{ADDR0=0;ADDR1=1;ADDR2=1;j++;P0=number[a[4]];}break;
case 7:if(b==6){ADDR0=1;ADDR1=1;ADDR2=1;j=0;if(counter<500) P0=number[a[5]]; else P0=0x00;}
else{ADDR0=1;ADDR1=1;ADDR2=1;j=0;P0=number[a[5]];}break;
default:break;
}
}
void key_scan()/*********************矩陣鍵盤掃描函數***********************************************/
{
uint8 hang,lie,tmp1,tmp2;
tmp1=0x01;//0000 0001
for(lie=0;lie<4;lie++)
{
P1=0xf0;
P1=~tmp1;
tmp1*=2;
if((P1&0xf0)<0xf0)
delay();
if((P1&0xf0)<0xf0)
{
tmp2=0x10;
for(hang=0;hang<4;hang++)
{
if((P1&tmp2)==0x00)
{
keyNum=lie*4+hang+1;
return;
}
tmp2*=2;
}
}
}
key_deal();
}
void interrupt_timer1() interrupt 3/*******************定時器1溢出中斷*****************/
{
TH1=0XFC;
TL1=0X67;
counter++;
if(counter==1000)
{
counter=0;
if(b!=0) goto cc;
miao++;
cc:
if(miao==60)
{
miao=0;
fen++;
}
if(fen==60)
{
fen=0;
shi++;
}
if(shi>23)
{
shi=0;
}
a[0]=miao%10;
a[1]=miao/10;
a[2]=fen%10;
a[3]=fen/10;
a[4]=shi%10;
a[5]=shi/10;
}
refresh_led();
}
//////////////////LCD1602顯示
sbit RS = P2^6 ;
sbit RW = P2^5 ;
sbit EN = P2^7 ;
sbit BUSY = P0^7;
unsigned char code word1[]={"Hi,teacher wan!"};
unsigned char code word2[]={"made by Mr GUO"};
/**
* 等待繁忙標志
*/
void wait(void)
{
P0 = 0xFF;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
/**
* 寫數據
*/
void w_dat(uint8 dat)
{
wait();
EN = 0;
P0 = dat;
RS = 1;
RW = 0;
EN = 1;
EN = 0;
}
/**
* 寫命令
*/
void w_cmd(uint8 cmd)
{
wait();
EN = 0;
P0 = cmd;
RS = 0;
RW = 0;
EN = 1;
EN = 0;
}
/**
* 發送字符串到LCD
*/
void w_string(uint8 addr_start, uint8 *p)
{
w_cmd(addr_start);
while (*p != '\0')
{
w_dat(*p++);
}
}
/**
* 初始化1602
*/
void Init_LCD1602(void)
{
w_cmd(0x38); // 16*2顯示,5*7點陣,8位數據接口
w_cmd(0x0C); // 顯示器開、光標開、光標允許閃爍
w_cmd(0x06); // 文字不動,光標自動右移
w_cmd(0x01); // 清屏
}
void main()/*****************************主函數******************/
{
Init_LCD1602();
w_string(0x80,word1);
w_string(0xC0,word2);
timer1_init();
int_init();
while(1)
{
key_scan();
}
}
|