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