?? my_clock.c
字號:
#define uchar unsigned char //宏定義字符型變量(無符號字符類型)
#define uint unsigned int //宏定義整型變量
#include "reg52.h" //定義89E58RD特殊功能寄存器
#include "intrins.h" //調(diào)用空操作延時函數(shù)_nop_()
sbit BELLING =P0^0; //鬧鐘信號引腳
sbit RS = P3^5; //數(shù)據(jù)/命令選擇端引腳
sbit RW = P3^6; //讀/寫選擇端引腳
sbit E = P3^7; //能使信號引腳
sbit ESC = P1^0; //退出鍵
sbit EN = P1^1; //確定鍵
sbit UP = P1^2; //右移鍵
sbit DOWN = P1^3; //左移
#define DPORT P2 //定義特殊功能寄存器端口
const uchar NoDisp=0; //無顯示
const uchar NoCur=1; //有顯示無光標
const uchar CurNoFlash=2; //有光標但不閃爍
const uchar CurFlash=3; //有光標且閃爍
void LcdPos(uchar,uchar); //確定光標位置
void LcdWd(uchar); //寫字符
void LcdWc(uchar); //送控制字(檢測忙信號)
void LcdWcn(uchar ); //送控制字子程序(不檢測忙信號)
void mDelay(uchar ); //延時,毫秒數(shù)由j決定
void WaitIdle(); //正常讀寫操作之前檢測LCD控制器狀態(tài)
uchar getkey();
//在指定的行與列顯示指定的字符,xpos:行,ypos:列,c:待顯示字符
void WriteChar(uchar c,uchar xPos,uchar yPos) //定義WriteChar函數(shù)
{ LcdPos(xPos,yPos);
LcdWd(c);
}
void WriteString(uchar *s,uchar xPos,uchar yPos) //定義WriteString函數(shù)
{ uchar i;
if(*s==0) //遇到字符串結(jié)束
return;
for(i=0;;i++)
{
if(*(s+i)==0)
break;
WriteChar(*(s+i),xPos,yPos);
xPos++;
if(xPos>=15) //如果XPOS中的值未到15(可顯示的最多位)
break;
}
}
void SetCur(uchar Para) //定義光標函數(shù)
{ mDelay(2); //延時
switch(Para)
{ case 0:
{ LcdWc(0x08); //關(guān)顯示
break;
}
case 1:
{ LcdWc(0x0c); //開顯示但無光標
break;
}
case 2:
{ LcdWc(0x0e); //開顯示有光標但不閃爍
break;
}
case 3:
{ LcdWc(0x0f); //開顯示有光標且閃爍
break;
}
default:
break;
}
}
void ClrLcd() //定義清屏函數(shù)
{ LcdWc(0x01);
}
// 正常讀寫操作之前檢測LCD控制器狀態(tài)
void WaitIdle() //測試LCD忙碌狀態(tài)標志函數(shù)
{ uchar tmp;
DPORT=0xff; //檢測LCD忙標志,若忙則輸出為1,否則為0
RS=0;
RW=1;
E=1;
_nop_();
for(;;)
{
E=1; //忙時則等待
_nop_();
_nop_();
tmp=DPORT;
tmp&=0x80;
if( tmp==0)
break;
E=0;
}
E=0; //E=0,執(zhí)行語句
}
void LcdWd(uchar c) //寫字符子程序
{ WaitIdle();
RS=1;
RW=0;
DPORT=c; //將待寫數(shù)據(jù)送到數(shù)據(jù)端口
E=1; //忙時則等待
_nop_();
_nop_();
E=0;
}
void LcdWc(uchar c) //送控制字子程序(檢測忙信號?
{ WaitIdle(); //調(diào)用WaitIdle函數(shù)
LcdWcn(c); //調(diào)用LcdWcn函數(shù)
}
void LcdWcn(uchar c) //送控制字子程序(不檢測忙信號)
{ RS=0;
RW=0;
DPORT=c; //將待寫數(shù)據(jù)送到數(shù)據(jù)端口
E=1; //忙時則等待
_nop_();
_nop_();
E=0;
}
void LcdPos(uchar xPos,uchar yPos) //設(shè)置第(xPos,yPos)個字符的DDRAM地址
{ unsigned char tmp;
xPos&=0x0f; //x位置范圍是0~15,因為顯示15列
yPos&=0x01; //y位置范圍是0~1,因為顯示2行
if(yPos==0) //顯示第一行
tmp=xPos;
else
tmp=xPos+0x40; //顯示第二行
tmp|=0x80;
LcdWc(tmp);
}
void RstLcd() //復(fù)位LCD控制器
{ mDelay(15); //如果使用12M或以下晶振,此數(shù)值不必改,如用24M晶振,須用30
LcdWc(0x38); //顯示模式設(shè)置
LcdWc(0x08); //顯示關(guān)閉
LcdWc(0x01); //顯示清屏
LcdWc(0x06); //顯示光標移動位置
LcdWc(0x0c); //顯示開及光標設(shè)置
}
void mDelay(uchar j) //延時,毫秒數(shù)由j決定
{ uint i=0;
for(;j>0;j--)
{ for(i=0;i<124;i++)
{;}
}
}
//============================
struct strtime //時、分、秒聲明函數(shù)
{
uchar hour;
uchar min;
uchar sec;
}time;
struct strdate //年、月、日聲明函數(shù)
{
uchar year;
uchar month;
uchar day;
}date;
struct strbell //(鬧鐘)時分聲明函數(shù)
{
uchar hour;
uchar min;
};
struct strbell idata belltime[34]; //設(shè)置響鈴次數(shù),可以響鈴34次
bit bellfla;
uchar week,reflash;
uchar buf[8];
code uchar monthday[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //月標志
uchar code weekday[7][4]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"}}; //星期標志
uchar code weekmon[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};
uchar code ID[]={"3105009720"}; //學(xué)號標志
uchar code menu[4][16]={ //菜單設(shè)置
{"1. SET TIME"},
{"2. SET DATE"},
{"3. SET ALARM"},
{"4. CANCEL ALARM"},
};
save() //保存語句
{
ClrLcd(); //清屏幕
WriteString("Saved !",4,0); //寫入"Saved !"
WriteString("Any Key Esc..",2,1); //寫入"Any Key Esc.."
getkey();
}
menudis(uchar num) //執(zhí)行菜單命令
{
ClrLcd();
WriteString("Select Menu",3,0);
WriteString(&menu[num][0],0,1);
}
//======================================
settime() //設(shè)置時間
{
uchar key,cru=0,max=2,xPOS=3;
buf[6]='s'-48;
ClrLcd();
LcdPos(4,0);
WriteString("Input Time",4,0);
buf[0]=time.hour/10; //設(shè)置時高位
buf[1]=time.hour%10; //設(shè)置時底位
buf[2]=time.min/10; //設(shè)置分高位
buf[3]=time.min%10; //設(shè)置分底位
buf[4]=time.sec/10; //設(shè)置秒高位
buf[5]=time.sec%10; //設(shè)置秒底位
//=============顯示位置
LcdPos(3,1);
LcdWd(buf[0]+48);
LcdPos(4,1);
LcdWd(buf[1]+48);
LcdPos(5,1);
LcdWd(':');
LcdWd(buf[2]+48);
LcdWd(buf[3]+48);
LcdPos(8,1);
LcdWd(':');
LcdWd(buf[4]+48);
LcdWd(buf[5]+48);
LcdPos(3,1);
SetCur(CurNoFlash);
while(key=getkey()) //時、分、秒加一
{
switch(key)
{
case 0: {;};break;
case 1:
{
if(cru==6)
{
time.hour=buf[0]*10+buf[1];
time.min=buf[2]*10+buf[3];
time.sec=buf[4]*10+buf[5];
save();
ClrLcd();
SetCur(NoCur);
return;
}
if((++buf[cru])>max)
{
buf[cru]=0;
}
LcdPos(xPOS,1);
LcdWd(buf[cru]+48);
LcdPos(xPOS,1);
}
break;
case 2: {
if(++cru>6) cru=0;
switch(cru)
{
case 0: {max=2;xPOS=3;};break;
case 1: {
xPOS=4;
if(buf[0]==2) max=4;
else max=9;
};break;
case 2: {max=5;xPOS=6;};break;
case 3: {max=9;xPOS=7;};break;
case 4: {max=5;xPOS=9;};break;
case 5: {max=9;xPOS=10;};break;
case 6: {max=9;xPOS=11;};break;
}
LcdPos(xPOS,1);
LcdWd(buf[cru]+48);
//xPOS--;
LcdPos(xPOS,1);
}break;
case 3: {
if(cru==0)
{cru=6;xPOS=11;}
else cru--;
switch(cru)
{
case 0: {max=2;xPOS=3;};break;
case 1: {
xPOS=4;
if(buf[0]==2) max=4;
else max=9;
};break;
case 2: {max=5;xPOS=6;};break;
case 3: {max=9;xPOS=7;};break;
case 4: {max=5;xPOS=9;};break;
case 5: {max=9;xPOS=10;};break;
}
LcdPos(xPOS,1);
LcdWd(buf[cru]+48);
//xPOS--;
LcdPos(xPOS,1);
}
break;
}
}
ClrLcd();
SetCur(NoCur);
}
//==========BELL==========設(shè)置鬧鐘
bellreflash(uchar num)
{
buf[0]=num/10;
buf[1]=num%10;
buf[2]=(belltime[num].hour&0x7f)/10; //設(shè)置時高位
buf[3]=(belltime[num].hour&0x7f)%10; //設(shè)置時傅孜?buf[4]=belltime[num].min/10; //設(shè)置分高位
buf[5]=belltime[num].min%10; //設(shè)置分底位
if(belltime[num].hour>100) buf[6]=1;
else buf[6]=0;
buf[7]='s'-48;
LcdPos(2,1); //顯示位置
LcdWd(buf[0]+48);
LcdWd(buf[1]+48);
LcdWd('#');
LcdWd(buf[2]+48);
LcdWd(buf[3]+48);
LcdWd(':');
LcdWd(buf[4]+48);
LcdWd(buf[5]+48);
LcdWd(' ');
LcdWd(buf[6]+48);
}
//===========BELL=============
setbell()
{
uchar key,num=0,cru,max=3,xp=2;
ClrLcd();
SetCur(CurNoFlash);
WriteString("Set Alamr Time",1,0); //寫入響鈴時間
bellreflash(num);
LcdPos(2,1);
while(key=getkey())
{
if(key==1)
{
if(cru==7)
{
if(num<34) //響鈴次數(shù)
{
belltime[num].hour=buf[2]*10+buf[3];
belltime[num].min=buf[4]*10+buf[5];
if(buf[6]) belltime[num].hour|=0x80; //響鈴時間到
ClrLcd();
WriteString("Bell ",0,0);
LcdWd(buf[0]+48);
LcdWd(buf[1]+48);
WriteString(" Saved!",9,0);
WriteString("Esc ? Esc key...",0,1);
buf[0]=num/10;
buf[1]=num%10;
if(getkey()==0) //清屏幕,直接退出
{
ClrLcd();
SetCur(NoCur);
return;
}
else //清屏幕,重設(shè)響鈴時間
{
ClrLcd();
WriteString("Set Alamr Time",1,0);
if(++num>33) num=0;
bellreflash(num);
cru=0;
xp=2;
max=3;
}
}
}
else
{
if(++buf[cru]>max)
{
buf[cru]=0; //可以確定鬧鐘時間
}
if(cru==0 || cru==1)
{
num=buf[0]*10+buf[1];
bellreflash(num);
}
else
LcdWd(buf[cru]+48);
}
}
else if(key==2)
{
if((++cru)>7)
cru=0;
switch (cru)
{
case 0:{max=3;xp=2;} break;
case 1:{max=9;xp=3;if(buf[0]==3) max=2;} break;
case 2:{max=2;xp=5;} break;
case 3:{max=9;xp=6;if(buf[2]==2) max=3;} break;
case 4:{max=5;xp=8;} break;
case 5:{max=9;xp=9;} break;
case 6:{max=1;xp=11;} break;
case 7:{xp=12;LcdPos(xp,1);LcdWd('s');} break;
}
}
else if(key==3)
{
if(cru==0) cru=7;
else cru--;
switch (cru)
{
case 0:{max=3;xp=2;} break;
case 1:{max=9;xp=3;} break;
case 2:{max=5;xp=5;} break;
case 3:{max=9;xp=6;} break;
case 4:{max=5;xp=8;} break;
case 5:{max=9;xp=9;} break;
case 6:{max=1;xp=11;} break;
case 7:{xp=12; LcdPos(xp,1);LcdWd('s');} break;
}
}
else break;
LcdPos(xp,1);
}
SetCur(NoCur);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -