基于stc89c52rc單片機的數(shù)字鐘設(shè)計程序
與數(shù)字中的數(shù)碼管顯示類似,
增加:
液晶初始化部分
寫命令部分
寫數(shù)據(jù)部分
********************************************************
#includereg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs = P2^6; //1602相應(yīng)
sbit rw = P2^5;
sbit ep = P2^7;
uchar hour,min,sec,k;
uchar key;
unsigned char lcdd[]="0123456789";
uchar key_code[] = {0xb7,0xbb,0xbd,0xbe};//鍵盤編碼,我只用到四個鍵。 你我的編碼可能不同 ,具體看電路如何連接。
void delay(uint z)
{
uint x,y;
for(z=x;x>0;x--)
for(y=100;y>0;y--);
}
bit lcd_bz()
{ // 測試LCD忙碌狀態(tài)
bit result;
rs = 0;
rw = 1;
ep = 1;
delay(5);
result = (bit)(P0 0x80);//判斷P0^7是一還是零.屏蔽掉其它位0x80.強制轉(zhuǎn)換位bit型數(shù)據(jù)。在返回給result。
ep = 0;
return result;
}
void lcd_cmd(uchar cmd)
{
while(lcd_bz());
rs = 0;//rs為1時寫入的是“數(shù)據(jù)”為0時寫入“指令”
rw = 0;//rw為1時“讀取”為0時“寫入”
ep = 0;//使能
delay(5);
P0 = cmd;
delay(5);
ep = 1;
delay(5);
ep = 0;
}
void lcd_data(uchar dat )//液晶寫數(shù)據(jù)
{
while(lcd_bz());
rs=1;
rw=0;
ep=0;
P0 = dat;
delay(5);
ep = 1;
delay(5);
ep = 0;
//return dat;
}
void lcd_init() //液晶寫命令
{
delay(15); //等待LCD電源穩(wěn)定
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x0c); //顯示開,關(guān)光標(biāo)
delay(10);
lcd_cmd(0x06); //移動光標(biāo)
delay(10);
lcd_cmd(0x01); //清除LCD的顯示內(nèi)容
delay(10);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
k++;
if(k==20)
{
k=0;
sec++;
}
if(sec>59)
{
min++;
sec=0;
}
if(min>59)
{
min=0;
hour++;
}
if(hour>23)
{
hour=0;
}
}
void disptime() //時間顯示函數(shù)
{
lcd_cmd(0x0c); //設(shè)置光標(biāo)不顯示、不閃爍
delay(20);
lcd_cmd(0x80); //起始顯示地址
delay(20);
lcd_data(lcdd[hour/10]);
delay(10);
lcd_data(lcdd[hour%10]);
delay(10);
lcd_data(':');
delay(12);
lcd_data(lcdd[min/10]);
delay(10);
lcd_data(lcdd[min%10]);
delay(12);
lcd_data(':');
delay(12);
lcd_data(lcdd[sec/10]);
delay(12);
lcd_data(lcdd[sec%10]);
delay(12);
lcd_data(' ');
delay(12);
}
uchar keyscan() //鍵盤掃描程序
{
uchar scan1, scan2, keycode, j;
P1 = 0xf0;
scan1 = P1;
if (scan1 != 0xf0)
//判鍵是否按下
{
delay(10); //延時10ms
scan1 = P1;
if (scan1 != 0xf0)
//二次判鍵是否按下
{
TR0=0; //如果有鍵按下 則定時器停止工作
P1 = 0x0f;
scan2 = P1;
keycode = scan1 | scan2; //組合成鍵掃描編碼
for (j = 0; j 4; j++)
{
if (keycode == key_code[j])
//查表得鍵值
{
key = j;
while(P1!= 0x0f) //松手有效 這里需要好好研究一下 可以用萬用表測量管腳電壓幫助理解
disptime();
return (key); //返回有效鍵值
}
}
}
}
else
P1 = 0xff;
return (key = 4); //返回?zé)o效碼
}
void Set_time(uchar key)
{
if(key==0||key==1||key==2)//若s1,s2,s3其中有鍵按下,則為真
{
if(key==0)
{
sec++;
if(sec>59)
{
sec=0;
}
}
else if(key==1)
{
min++;
if(min>59)
{
min=0;
}
}
else if(key==2)
{
hour++;
if(hour>23)
{
hour=0;
}
}
}
else if(key==3)
{
TR0=1; //按下退出鍵 定時器繼續(xù)工作
}
}
void sysint() //定時器初始化
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timeint() //初始化
{
hour=0;
min=0;
sec=0;
}
void main()
{
sysint() ;
timeint();
lcd_init();//函數(shù)調(diào)用
while(1)
{
keyscan();//調(diào)用鍵盤掃描,
Set_time(key);
disptime();
}
}
評論