以简易数字钟为例 演示LCD1602的综合运用 程序+仿真+详细注释
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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)
|