|
給你一個(gè)示例,是壇友寫的,改按你的接法。用4了個(gè)按鍵。
無標(biāo)題.jpg (259.63 KB, 下載次數(shù): 32)
下載附件
2019-1-26 15:56 上傳
/*******************************
STC89C52RC,晶振11.0592MHz
(如果晶振12MHz時(shí)間更準(zhǔn)些)
********************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_EN=P2^7; //定義1602液晶LCDEN端,使能信號
sbit LCD_RS=P2^6; //定義1602液晶RS端,數(shù)據(jù)/命令選擇端(H/L)
//sbit LCD_RW=P2^5; //定義1602液晶RW端,讀/寫選擇端(H/L)已接地禁止讀
sbit BUZZ=P2^3; //定義蜂鳴器端,按鍵釋放和整點(diǎn)響
sbit key_1=P3^0; //進(jìn)入調(diào)試方式
sbit key_2=P3^1; //調(diào)試+
sbit key_3=P3^2; //調(diào)試-
sbit key_4=P3^3; //退出調(diào)試方式
sbit MND_1=P3^7; //矩陣鍵盤模擬地
uchar code keycode[] = {0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,//按鍵鍵值
0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
uchar yue,ri,shi,fen,miao,week,nian; //月、日、時(shí)、分、秒、周、年變量
uchar flag=0; //功能鍵計(jì)數(shù)變量
uint count=0; //中斷計(jì)數(shù)變量
bit Cnt1s=0; //秒標(biāo)志
uchar code table[7][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"};//顯示周
/***********毫秒級延時(shí)函數(shù)**********/
void delay(uint x)
{
uint y,z;
for(y=x;y>0;y--)
for(z=110;z>0;z--);
}
/***********蜂鳴器發(fā)聲函數(shù)**********/
void di(uint dd)
{
BUZZ=0;
delay(dd);
BUZZ=1;
}
/***********LCD1602忙等待**********/
/*
uchar busycheck()
{
uchar s; //臨時(shí)變量
LCD_RS=0; //允許寫指令
// LCD_RW=1; //允許讀數(shù)據(jù)(讀寫端已接地,禁止讀)
LCD_EN=1; //高電平使能讀數(shù)據(jù)
delay(1); //延時(shí)
s=P0; //讀P0數(shù)據(jù)賦值s
LCD_EN=0; //低跳變執(zhí)行
return s; //返回s值 s=0x80有效
}
*/
/***********液晶寫指令函數(shù)**********/
void write_com(uchar com)
{
// while((busycheck()&0x80)==0x80);//忙等待
LCD_RS=0; //允許寫指令
// LCD_RW=0; //讀寫端已接地,禁止讀
LCD_EN=0; //初始設(shè)置LCD_EN低電平
P0=com; //傳遞指令
delay(5); //延時(shí)
LCD_EN=1; //使能寫入
delay(5); //延時(shí)
LCD_EN=0; //低跳變執(zhí)行
}
/***********液晶寫數(shù)據(jù)函數(shù)**********/
void write_date(uchar date)
{
// while((busycheck()&0x80)==0x80);//忙等待
LCD_RS=1; //允許寫數(shù)據(jù)
// LCD_RW=0; //讀寫端已接地,禁止讀
LCD_EN=0; //初始設(shè)置LCD_EN低電平
P0 =date; //傳遞數(shù)據(jù)
delay(5); //延時(shí)
LCD_EN=1; //使能寫入
delay(5); //延時(shí)
LCD_EN=0; //低跳變執(zhí)行
}
/***********寫年函數(shù)**********/
void write_nian(uchar add,uchar date)reentrant //reentrant定義為可重入函數(shù),允許被遞歸調(diào)用
{
uint bai,shi,ge; //定義百、十、個(gè)變量
bai=date/100; //分解百
shi=date%100/10; //分解十
ge=date%100%10; //分解個(gè)
write_com(0x80+add); //寫指令、設(shè)置顯示位置
write_date(0x30+bai);//寫數(shù)據(jù)百位0~9對應(yīng)的字符碼是0x30~0x39
write_date(0x30+shi);//寫數(shù)據(jù)十位
write_date(0x30+ge); //寫數(shù)據(jù)個(gè)位
/*write_date(dat[bai]);
write_date(dat[shi]);
write_date(dat[ge]);*/
}
/***********大小月份設(shè)置**********/
uchar dxy(uchar r)
{
uchar k;
switch(r)
{
case 1:
k=31;
break;
case 2: //閏年29天, 平年28天
if((2000+nian)%100==0)
if((2000+nian)%400==0)
k=29;
else
k=28;
else if((2000+nian)%4==0)
k=29;
else
k=28;
break;
case 3:k=31;break;
case 4:k=30;break;
case 5:k=31;break;
case 6:k=30;break;
case 7:k=31;break;
case 8:k=31;break;
case 9:k=30;break;
case 10:k=31;break;
case 11:k=30;break;
case 12:k=31;break;
}
return k;
}
/***********寫月、日、時(shí)、分、秒函數(shù)**********/
void write_yrsfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add); //設(shè)置顯示位置
write_date(0x30+shi);
write_date(0x30+ge);
/*write_date(dat[shi]);
write_date(dat[ge]);*/
}
/***********寫星期函數(shù)**********/
void write_week(uchar add,uchar date)
{
uchar i;
write_com(0x80+add); //設(shè)置顯示位置
for(i=0;i<3;i++)
{
write_date(table[date]);
delay(5);
}
}
/***********初始化函數(shù)**********/
void init()
{
count=0; //
// P0=0xff; //關(guān)閉發(fā)光二極管
write_com(0x38); //設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
write_com(0x0c); //設(shè)置開顯示,不顯示光標(biāo)
write_com(0x06); //寫一個(gè)字符后地址指針加1
write_com(0x01); //顯示清零,數(shù)據(jù)指針清零
write_com(0x80); //設(shè)置顯示初始位置
write_com(0x80+1); //寫出年份的最高位“2”
write_date('2'); //寫數(shù)據(jù)'2'
write_com(0x80+5); //寫指令,顯示位置 日期顯示部分的的兩'-'
write_date('-'); //寫數(shù)據(jù)'-'
write_com(0x80+8); //寫指令,顯示位置 日期顯示部分的的兩'-'
write_date('-'); //寫數(shù)據(jù)'-'
write_com(0x80+0x40+6); //寫指令,時(shí)間顯示部分的的兩個(gè)“:”
write_date(':'); //寫數(shù)據(jù)':'
write_com(0x80+0x40+9); //寫指令,時(shí)間顯示部分的的兩個(gè)“:”
write_date(':'); //寫數(shù)據(jù)':'
miao=0; //秒
fen=0; //分
shi=0; //時(shí)
week=5; //星期
ri=20; //日
yue=5; //月
nian=17; //年
write_yrsfm(0x40+10,miao); //寫入秒
write_yrsfm(0x40+7,fen); //寫入分
write_yrsfm(0x40+4,shi); //寫入時(shí)
write_week(12,week); //寫入星期
write_yrsfm(9,ri); //寫入日
write_yrsfm(6,yue); //寫入月
write_nian(2,nian); //寫入年
}
/***********按鍵掃描函數(shù)**********/
void keyscan()
{
if(key_1==0) //功能鍵按下
{
delay(10); //消抖
if(key_1==0)//功能鍵確認(rèn)按下
{
flag++; //記錄功能鍵按下次數(shù)
while(!key_1); //確認(rèn)釋放功能鍵
di(100); //每當(dāng)有按鍵釋放蜂鳴器發(fā)出滴聲提醒
if((flag==1)||(flag==8)) //第一次按下功能鍵光標(biāo)閃爍到秒位置
{
TR0=0; //關(guān)閉定時(shí)器
write_com(0x80+0x40+11); //光標(biāo)定位到秒位置
write_com(0x0f); //光標(biāo)開始閃爍
}
if(flag==2) //第二次按下功能鍵光標(biāo)閃爍到分鐘位置
{
write_com(0x80+0x40+8);
}
if(flag==3) //第三次按下功能鍵光標(biāo)閃爍到時(shí)位置
{
write_com(0x80+0x40+5);
}
if(flag==4) //第四次按下功能鍵光標(biāo)閃爍到星期位置
{
write_com(0x80+12);
}
if(flag==5) //第五次按下功能鍵光標(biāo)閃爍到日位置
{
write_com(0x80+10);
}
if(flag==6) //第六次按下功能鍵光標(biāo)閃爍到月位置
{
write_com(0x80+7);
}
if(flag==7) //第七次按下功能鍵光標(biāo)閃爍到年位置
{
write_com(0x80+4);
}
if(flag==8) //第八次按下功能鍵退出功能鍵
flag=1; //記錄變成1;光標(biāo)重新回到秒位置
}
}
if(key_4==0) //退出調(diào)節(jié)
{
delay(10);
if(key_4==0)
{
while(!key_4); //釋放按鍵
if(TR0==0)
di(100); //只在調(diào)節(jié)時(shí)有按鍵釋放蜂鳴器發(fā)出滴聲
flag=0; //功能鍵按鍵次數(shù)清零
write_com(0x0c); //取消光標(biāo)閃爍
count=0;
Cnt1s=0;
TR0=1; //啟動(dòng)定時(shí)器
}
}
if(flag!=0) //功能鍵按下后flag=1
{ //增大鍵
if(key_2==0) //只有功能鍵按下后,增大和減少鍵才有效
{
delay(10);
if(key_2==0)//確認(rèn)增加按下
{
while(!key_2); //釋放按鍵
di(100); //每當(dāng)有按鍵釋放蜂鳴器發(fā)出滴聲提醒
if(flag==1) //功能鍵第一次按下調(diào)節(jié)秒
{
miao++; //秒加1
if(miao>59)
miao=0;
write_yrsfm(0x40+10,miao); //每調(diào)節(jié)一次送液晶顯示一下
write_com(0x80+0x40+11); //顯示位置重新回到調(diào)節(jié)處
}
if(flag==2) //功能鍵第二次按下調(diào)節(jié)分
{
fen++;
if(fen>59)
fen=0;
write_yrsfm(0x40+7,fen);
write_com(0x80+0x40+8);
}
if(flag==3) //功能鍵第三次按下調(diào)節(jié)時(shí)
{
shi++;
if(shi>23)
shi=0;
write_yrsfm(0x40+4,shi);
write_com(0x80+0x40+5);
}
if(flag==4) //功能鍵第四次按下調(diào)節(jié)星期
{
week++;
if(week>6)
week=0;
write_week(12,week);
write_com(0x80+12);
}
if(flag==5) //功能鍵第五次按下調(diào)節(jié)日
{
ri++;
if(ri>(dxy(yue)))
ri=1;
write_yrsfm(9,ri);
write_com(0x80+10);
}
if(flag==6) //功能鍵第六次按下調(diào)節(jié)月份
{
yue++;
if(yue>12)
yue=1;
write_yrsfm(6,yue);
write_com(0x80+7);
}
if(flag==7) //功能鍵第七次按下調(diào)節(jié)年份
{
nian++;
write_nian(2,nian);
write_com(0x80+4);
}
}
}
//減少鍵
if(key_3==0) //減少鍵被按下
{
delay(10);
if(key_3==0)//確認(rèn)減少鍵被按下
{
while(!key_3);//按鍵釋放
di(100); //每當(dāng)有按鍵釋放蜂鳴器發(fā)出滴聲
if(flag==1) //功能鍵第一次按下調(diào)節(jié)秒
{ //秒減1
miao--;
if((miao==(-1))||(miao>59)) //59到0循環(huán)遞減;
miao=59;
write_yrsfm(0x40+10,miao); //每調(diào)節(jié)一次送液晶顯示一下
write_com(0x80+0x40+11); //顯示位置重新回到調(diào)節(jié)處
}
if(flag==2) //功能鍵第二次按下調(diào)節(jié)分
{
fen--;
if((fen==(-1))||(fen>59))
fen=59;
write_yrsfm(0x40+7,fen);
write_com(0x80+0x40+8);
}
if(flag==3) //功能鍵第三次按下調(diào)節(jié)時(shí)
{
shi--;
if((shi==(-1))||(shi>23))
shi=23;
write_yrsfm(0x40+4,shi);
write_com(0x80+0x40+5);
}
if(flag==4) //功能鍵第四次按下調(diào)節(jié)星期
{
week--;
if((week==(-1))||(week>6))
week=6;
write_week(12,week);
write_com(0x80+12);
}
if(flag==5) //功能鍵第五次按下調(diào)節(jié)日
{
ri--;
if((ri==0)||ri>dxy(yue))
ri=dxy(yue);
write_yrsfm(9,ri);
write_com(0x80+10);
}
if(flag==6) //功能鍵第六次按下調(diào)節(jié)月份
{
yue--;
if((yue==0)||(yue>12))
yue=12;
write_yrsfm(6,yue);
write_com(0x80+7);
}
if(flag==7) //功能鍵第七次按下調(diào)節(jié)年份
{
nian--;
write_nian(2,nian);
write_com(0x80+4);
}
}
}
}
}
void LCD_Refresh()
{
if(flag==0) //調(diào)整時(shí)停止刷新
{
if((ri>dxy(yue))||(ri<1)) //大小月匹配
ri=1;
write_yrsfm(9,ri); //日若變化則重新寫入
if(Cnt1s==1) //1秒時(shí)間到
{
Cnt1s=0; //清零
miao++; //秒、分、時(shí)、星期、日、月、年自動(dòng)調(diào)節(jié)功能運(yùn)行
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
di(500); //整點(diǎn)提醒
shi++;
if(shi==24)
{
shi=0;
week++;
ri++;
if(week>6)
week=0;
write_week(12,week); //星期若變化則重新寫入
if(ri>dxy(yue))
{
ri=1;
yue++;
if(yue==13)
{
yue=1;
nian++;
write_nian(2,nian); //年份若變化則重新寫入
}
write_yrsfm(6,yue); //月份若變化則重新寫入
}
write_yrsfm(9,ri); //日若變化則重新寫入
}
write_yrsfm(0x40+4,shi); //時(shí)若變化則重新寫入
}
write_yrsfm(0x40+7,fen); //分若變化則重新寫入
}
write_yrsfm(0x40+10,miao); //秒若變化則重新寫入
}
}
}
void Timer0Init() //100微秒@12.000MHz
{
TMOD = 0x02; //設(shè)置定時(shí)器自動(dòng)重載模式
// TL0 = 0x9C; //設(shè)置定時(shí)初值
// TH0 = 0x9C; //設(shè)置定時(shí)重載值
TL0=0xA4; //定時(shí)器裝初值 100微秒@11.0592MHz
TH0=0xA4; //定時(shí)器裝初值 100微秒@11.0592MHz
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
EA=1; //開總中斷
ET0=1; //開定時(shí)器0中斷
}
/***********主函數(shù)**********/
void main()
{
MND_1=0; //矩陣鍵盤模擬地
init(); //初始化程序
Timer0Init(); //初始化定時(shí)器
di(100); //開機(jī)蜂鳴器提示音
while(1) //不停地檢測按鍵是否被按下
{
keyscan(); //按鍵掃描程序
LCD_Refresh(); //液晶屏顯示刷新
}
}
/***********中斷函數(shù)**********/
void timer0() interrupt 1
{
count++; //11.0592MHz誤差0.17%,12MHz誤差0
if(count>=10017) //1秒/11.0592MHz
// if(count>=10000) //1秒/12MHz
{
count=0; //清0
Cnt1s=1; //1秒標(biāo)標(biāo)志置1
}
}
|
|