|
以簡易數(shù)字鐘為例 演示LCD1602的綜合運(yùn)用 程序+仿真+詳細(xì)注釋
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
-
- sbit RS=P3^5; //寄存器選擇位,將RS位定義為P2.0引腳
- //sbit RW=P2^1; //讀寫選擇位,將RW位定義為P2.1引腳
- sbit E=P3^4; //使能信號(hào)位,將E位定義為P2.2引腳
- //sbit BF=P0^7; //忙碌標(biāo)志位,將BF位定義為P0.7引腳
-
- uchar code table[]="2018-06-04 WEEK1"; //初始化液晶顯示 1602
- uchar code table1[]="TIME: 08:01:44";
- uchar count,s1num;
- char second,minute,hour,day,month,year,week;
- sbit s1=P2^3; //功能鍵
- sbit s2=P2^4; //加鍵
- sbit s3=P2^5; //減鍵
- sbit s4=P2^6; //保存并退出
- void delay(uchar i) // 延時(shí)函數(shù)
- {
- uchar j;
- while(i--)
- for(j=110;j>0;j--);
- }
- //uchar BusyTest(void) // 查忙程序
- //{
- // bit result;
- // RS=0; //RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
- // RW=1;
- // E=1; //高脈沖寫數(shù)據(jù)
- // delay(4); //延時(shí),給硬件反應(yīng)時(shí)間
- // result=BF; //將忙碌標(biāo)志電平賦給
- // E=0; //將E恢復(fù)低電平
- // return result;
- //}
- void WriteInstruction(uchar dictate) //寫命令操作
- {
- // while(BusyTest()==1); //如果忙就等待 查忙指令
- RS=0; //RS和R/W同時(shí)為低電平時(shí),可以寫入指令
- // RW=0;
- E=0; //E置低電平(根據(jù)指令表,寫指令時(shí),E為高脈沖,
- delay(2); //延時(shí),給硬件反應(yīng)時(shí)間
- P0=dictate; //將數(shù)據(jù)送入P0口,即寫入指令或地址
- delay(4);
- E=1; //寫入脈沖
- delay(4);
- E=0;
- }
- void WriteData(uchar y) //寫數(shù)據(jù)操作
- {
- // while(BusyTest()==1);
- RS=1; //RS為高電平,RW為低電平時(shí),可以寫入數(shù)據(jù)
- // RW=0;
- E=0; //E置低電平(根據(jù)指令表,寫指令時(shí),E為高脈沖,
- P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
- delay(4);
- E=1;
- delay(4);
- E=0;
- }
- void LcdInitiate(void) //設(shè)定初始液晶屏顯示數(shù)據(jù)
- {
- uchar num;
- second=44;
- minute=1;
- hour=8; //設(shè)定顯示時(shí)間為08-01-44
- week=1;
- day=4;
- month=6;
- year=18; //設(shè)定初始年月日
- count=0;
- s1num=0;
- E=0;
- delay(15); //延時(shí)15ms,首次寫指令時(shí)應(yīng)給LCD一段較長的反應(yīng)時(shí)間
- WriteInstruction(0x38); //16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口 0011 1000
- delay(5);
- WriteInstruction(0x0c); //顯示開,無光標(biāo),光標(biāo)不閃爍 0000 1100
- delay(5);
- WriteInstruction(0x06); //光標(biāo)自動(dòng)右移,字符不移 0000 0110
- delay(5);
- WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
- delay(5);
- WriteInstruction(0x80); //設(shè)置數(shù)據(jù)地址指針
- for(num=0;num<16;num++) //設(shè)置第一行的16個(gè)顯示位·
- {
- WriteData(table[num]);
- delay(5);
- }
- WriteInstruction(0x80+0x40); //將液晶屏的數(shù)據(jù)指針移到第二行第一個(gè)字處
- for(num=0;num<14;num++) //設(shè)置第二行的14個(gè)顯示位
- {
- WriteData(table1[num]);
- delay(5);
- }
- TMOD=0x01; //定時(shí)器中斷初始化 方式1
- TH0=(65536-50000)/256; //取模 /*方式1低位使用了八位
- TL0=(65536-50000)%256; //求余 故最大數(shù)值為2^8=256
- EA=1; //開總中斷
- ET0=1; //開內(nèi)部定時(shí)器0中斷
- TR0=1; //啟動(dòng)定時(shí)器
- }
- /* 時(shí)間日期計(jì)算與換算函數(shù)和寫入輸出函數(shù) */
- void write_nyr(uchar add,uchar date)
- {
- uchar i,j;
- i=date/10;
- j=date%10;
- WriteInstruction(0x80+add);
- WriteData(0x30+i);
- WriteData(0x30+j);
- }
- void write_sfm(uchar add,uchar date)
- {
- uchar i,j;
- i=date/10;
- j=date%10;
- WriteInstruction(0x80+0x40+add);
- WriteData(0x30+i);
- WriteData(0x30+j);
- }
- void write_week(uchar add,uchar date)
- {
- WriteInstruction(0x80+add);
- WriteData(0x30+date);
- }
- bit leap_year()
- {
- int leap;
- if((year%4==0&&year%100!=0)||year%400==0)
- leap=1;//是閏年
- else
- leap=0;//非閏年
- return leap;
- }
- /* 功能鍵判別函數(shù) */
- void keyscan()
- {
- if(s1==0) //第一個(gè)鍵是否按下
- {
- delay(5);
- if(s1==0)
- {
- while(!s1);
- s1num++;
- if(s1num>7)
- s1num=1;
- if(s1num==1)//第一個(gè)鍵被按一次
- {
- TR0=0;
- WriteInstruction(0x80+0x40+13);
- WriteInstruction(0x0f);
- }
- if(s1num==2)
- {
- WriteInstruction(0x80+0x40+10);
- }
- if(s1num==3)
- {
- WriteInstruction(0x80+0x40+7);
- }
- if(s1num==4)
- {
- WriteInstruction(0x80+9);
- }
- if(s1num==5)
- {
- WriteInstruction(0x80+6);
- }
- if(s1num==6)
- {
- WriteInstruction(0x80+3);
- }
- if(s1num==7)
- {
- WriteInstruction(0x80+15);
- }
- }
- }
- if(s1num!=0) //如果功能鍵被按下
- {
- if(s2==0) //第二個(gè)按下
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- if(s1num==1) //第一個(gè)鍵被按一次,秒鐘加一
- {
- second++;
- if(second==60)
- second=0;
- write_sfm(12,second);
- WriteInstruction(0x80+0x40+13);
- }
- if(s1num==2) //第一個(gè)鍵被按二次,分鐘加一
- {
- minute++;
- if(minute==60)
- minute=0;
- write_sfm(9,minute);
- WriteInstruction(0x80+0x40+10);
- }
- if(s1num==3) //第一個(gè)鍵被按三次,時(shí)鐘加一
- {
- hour++;
- if(hour==24)
- hour=0;
- write_sfm(6,hour);
- WriteInstruction(0x80+0x40+7);
- }
- if(s1num==4) //第一個(gè)鍵被按四次,日期加一
- {
- day++;
- if(day==32)
- day=1;
- write_nyr(8,day);
- WriteInstruction(0x80+9);
- }
- if(s1num==5) //第一個(gè)鍵被按五次,月加一
- {
- month++;
- if(month==13)
- month=1;
- write_nyr(5,month);
- WriteInstruction(0x80+6);
- }
- if(s1num==6) //年加一
- {
- year++;
- if(year==99)
- year=0;
- write_nyr(2,year);
- WriteInstruction(0x80+3);
- }
- if(s1num==7) //星期加一
- {
- week++;
- if(week==8)
- week=1;
- write_week(15,week);
- WriteInstruction(0x80+15);
- }
- }
- }
- if(s3==0) //第三個(gè)鍵被按下
- {
- delay(5);
- if(s3==0)
- {
- while(!s3);
- if(s1num==1)//秒減一
- {
- second--;
- if(second==-1)
- second=59;
- write_sfm(12,second);
- WriteInstruction(0x80+0x40+13);
- }
- if(s1num==2) //分減一
- {
- minute--;
- if(minute==-1)
- minute=59;
- write_sfm(9,minute);
- WriteInstruction(0x80+0x40+10);
- }
- if(s1num==3) //時(shí)減一
- {
- hour--;
- if(hour==-1)
- hour=23;
- write_sfm(6,hour);
- WriteInstruction(0x80+0x40+7);
- }
- if(s1num==4) //日減一
- {
- day--;
- if(day==0)
- day=31;
- write_nyr(8,day);
- WriteInstruction(0x80+9);
- }
- if(s1num==5) //月減一
- {
- month--;
- if(month==0)
- month=12;
- write_nyr(5,month);
- WriteInstruction(0x80+6);
- }
- if(s1num==6) //年減一
- {
- year--;
- if(year==-1)
- year=99;
- write_nyr(2,year);
- WriteInstruction(0x80+3);
- }
- if(s1num==7) //日期減一
- {
- week--;
- if(week==0)
- week=7;
- write_week(15,week);
- WriteInstruction(0x80+15);
- }
- }
- }
- if(s4==0) //保存并退出
- {
- s1num=0;
- WriteInstruction(0x0c);
- TR0=1;
- }
- }
- }
- void main(void)
- {
- uchar k=0;
- LcdInitiate(); //調(diào)用LCD初始化函數(shù)
- while(1)
- {
- keyscan();
- k=1;
- }
- }
- void timer0() interrupt 1
- {
- count++;
- if(count==13)
- {
- count=0;
- second++;
- if(second==60) //秒計(jì)滿60,秒歸0,分+1
- {
- second=0;
- minute++;
- if(minute==60) //分計(jì)滿60,分歸0,時(shí)+1
- {
- minute=0;
- hour++;
- if(hour==24) //時(shí)計(jì)滿24,時(shí)歸0,星期+1,日+1
- {
- hour=0;
- week++;
- day++;
- if(week==8)
- week=1; //星期計(jì)滿7,星期歸1
- if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)//大月三十一天
- {
- if(day==32) //大月天數(shù)計(jì)滿31,日歸1,月+1
- {
- day=1;
- month++;
- }
- }
- if(month==4||month==6||month==9||month==11) //小月三十天
- {
- if(day==31) //小月天數(shù)計(jì)滿30,日歸1,月+1
- {
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
20161111144-李作鑫-LCD顯示器.rar
(81.24 KB, 下載次數(shù): 46)
2018-7-27 07:19 上傳
點(diǎn)擊文件名下載附件
|
|