基于DS1302与AT89C51的实时日历时钟的LCD显示程序你还有么?还有图的

 我来答
天机老人巩哥
2011-10-17
知道答主
回答量:11
采纳率:0%
帮助的人:12.4万
展开全部
2.3.6 显示模块的设计
本设计中由于要对时间、温度进行显示,所以选择液晶显示屏1602模块作为输出。1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线。它可以显示两行,每行16个字符,采用单+5V电源供电,外围电路配置简单,价格便宜,具有很高的性价比。1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。管脚功能如表2-1所示。
表2-1 LCD1602引脚功能
引脚 符号 功能说明
1 VSS 一般接地
2 VDD 接电源(+5V)
3 V0 液晶显示器对比度调整端。
4 RS RS为寄存器选择。
5 R/W R/W为读写信号线。
6 E E(或EN)端为使能(enable)端,下降沿使能。
7 DB0 低4位三态、 双向数据总线 0位(最低位)
8 DB1 低4位三态、 双向数据总线 1位
9 DB2 低4位三态、 双向数据总线 2位
10 DB3 低4位三态、 双向数据总线 3位
11 DB4 高4位三态、 双向数据总线 4位
12 DB5 高4位三态、 双向数据总线 5位
13 DB6 高4位三态、 双向数据总线 6位
14 DB7 高4位三态、 双向数据总线 7位(最高位)
LCD1602主要管脚介绍:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生鬼影使用时可以通过一个10K的电位器调整对比度。RS为寄存器选择端,高电平时选择数据寄存器,低电平时选择指令寄存器。R/W为读写信号线端,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址;当RS为高电平R/W 为低电平时可以写入数据。E为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
将LCD1602的RS端和P2.0,R/W端和P2.1, E 端和P2.2相连,当RS=0时,对LCD1602写入指令;当RS=1时,对LCD1602写入数据。当R/W端接高电平时芯片处于读数据状态,反之处于写数据状态,E端为使能信号端。当R/W为高电平,E端也为高电平,RS为低电平时,液晶显示屏显示需要显示的示数。图2.11为1602液晶显示屏与单片机的硬件连接图。
图2.11 LCD液晶显示与单片机硬件连线图

附录二 部分程序说明
void delay(uint xms) //*******延时函数,有参函数*****//
{ uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
//******ds18b20芯片有关子程序******/
void DS18B20_init() //****初始化
{ uint i; tem_ds=0;
i=160; while(i>0) //给DS18B20单总线至少480uS的低电平信号
i--; tem_ds=1; //拉高15~60uS
i=8; while(i>0) i--;
}
void temwritebit(bit instruc_data) //*****写一位*******//
{ int time;
if(instruc_data)
{ tem_ds=0;
time=3; //延时14us
while(time>0)
time--;
tem_ds=1; //写"1"
time=8; //延时35us
while(time>0)
time--;
}
else
{
tem_ds=0; //写0
time=14; //延时62us
while(time>0)
time--;
}
tem_ds=1; //释放数据线
time++;time++;
}
bit temreadbit() //*********读一位*********//
{ uint i;
bit datbit;
tem_ds=0;
i++;
tem_ds=1;
i++;i++;
datbit=tem_ds; //读数据
i=10; //延时45 
while(i>0)
i--;
tem_ds=1;
return(datbit);
}
uchar temreadbyte() //********读字节*********//
{ uchar i,j,dat;
dat=0;
for(i=0;i<8;i++)
{ j=temreadbit() ;
dat=(j<<7)|(dat>>1);
}
return(dat);
}
void temwritebyte(uchar instru) //********写字节*********//
{ int i;
for(i=0;i<8;i++)
{temwritebit(instru&01);
instru>>=1;
}
}
uint get_tem() //********获取温度*******//
{ uchar tem_L,tem_H;
DS18B20_init();
delay(1);
temwritebyte(0xcc); //写跳过ROM指令;
temwritebyte(0xbe); //读数据
tem_L=temreadbyte();
tem_H=temreadbyte();
tem=tem_H<<8|tem_L;
f_tem=tem*0.0625;
tem=f_tem ;
return (tem);
}
//******液晶相关程序******/
write_1602com(uchar com) //****液晶写入指令函数****//
{ rs=0; //数据/指令选择置为指令
rw=0; //读写选择置为写
P0=com; //送入数据
delay(1);
en=1; //拉高使能端,为制造有效的下降沿做准备
delay(1);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
write_1602dat(uchar dat) //***液晶写入数据函数****//
{ rs=1; //数据指令选择置为数据
rw=0; //读写选择置为写
P0=dat; //送入数据
delay(1);
en=1; //en置高电平,为制造下降沿做准备
delay(1);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
lcd_init() //***液晶初始化函数****//
{ write_1602com(0x38); //设置液晶工作模式 意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x01); //清显示
write_1602com(0x06); //整屏不移动,光标自动右移
write_1602com(yh+1); //日历显示固定符号从第一行第1个位置之后开始显示
write_1602com(0x0c); //开显示不显示光标
for(a=0;a<14;a++)
{ write_1602dat(tab1[a]); //向液晶屏写日历显示的固定符号部分
delay(3);
}
write_1602com(er+2); //时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<8;a++)
{write_1602dat(tab2[a]); //写显示时间固定符号,两个冒号
delay(3);
}
}
/***************DS1302有关子函数********************/
void write_byte(uchar dat) //*******写一个字节*****//
{ ACC=dat;
RST=1;
for(a=8;a>0;a--)
{ IO=ACC0;
SCLK=0; /*在控制指令字输入后的下一个SCLK时钟的上升沿时*/
SCLK=1; /*数据被写入DS1302*/
ACC=ACC>>1;
}
}
uchar read_byte() //******读一个字节******//
{ RST=1;
for(a=8;a>0;a--)
{ ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return (ACC);
}
void write_1302(uchar add,uchar dat) //****向1302芯片写函数,指定写入地址,数据**//
{ RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
uchar read_1302(uchar add) //****从1302读数据函数,指定读取数据来源地址***//
{ uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd) //*****BCD码转十进制函数****//
{ uchar Decimal;
Decimal=bcd>>4; //BCD高四位表示十位,低四位个位,8421码;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
void ds1302_init() //***1302芯片初始化子函数(2010-01-07,12:00:00,week4)***//
{ RST=0;
SCLK=0;
write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据00
write_1302(0x82,0x00); //向DS1302内写分寄存器82H写入初始分数据00
write_1302(0x84,0x12); //向DS1302内写小时寄存器84H写入初始小时数据12
write_1302(0x8a,0x04); //向DS1302内写周寄存器8aH写入初始周数据4
write_1302(0x86,0x07); //向DS1302内写日期寄存器86H写入初始日期数据07
write_1302(0x88,0x01); //向DS1302内写月份寄存器88H写入初始月份数据01
write_1302(0x8c,0x10); //向DS1302内写年份寄存器8cH写入初始年份数据10
write_1302(0x8e,0x80); //打开写保护
}
void write_temp(uchar add,uchar dat) //****向LCD写温度数据,并指定显示位置****//
{ uchar gw,sw;
gw=dat%10; //取得个位数字
sw=dat/10; //取得十位数字
write_1602com(er+add); //er是头文件规定的值0x80+0x40
write_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码
write_1602dat(0xdf); //显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码
write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码
}

void write_sfm(uchar add,uchar dat) //向LCD写时分秒,有显示位置加显示数据,两个参数
{ uchar gw,sw;
gw=dat%10; //取得个位数字
sw=dat/10; //取得十位数字
write_1602com(er+add); //er是头文件规定的值0x80+0x40//年月日显示将er改为yh即可,其他相同;
write_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码
}
void write_week(uchar week) //****写星期函数*****//
{ write_1602com(yh+0x0c); //星期字符的显示位置
switch(week)
{ case 1:write_1602dat('M'); //星期数为1时,显示
write_1602dat('O');
write_1602dat('N');
break; //下面六种选择形式相同将括号中的字符相应修改就行了
}
}
void keyscan() //****************键盘扫描有关函数**********************
{ if(key1==0) //key1为功能键(设置键)
{delay(9); //延时,用于消抖动
if(key1==0) //延时后再次确认按键按下
{buzzer=0; //蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key1); //按键等待释放
key1n++;
if(key1n==9)
key1n=1; //设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环
switch(key1n)
{ case 1: TR0=0; //关闭定时器
write_1602com(er+0x09); //设置按键按动一次,秒位置显示光标
write_1602com(0x0f); //设置光标为闪烁
temp=(miao)/10*16+(miao)%10; //秒数据写入DS1302
write_1302(0x8e,0x00);
write_1302(0x80,0x80|temp); //miao
write_1302(0x8e,0x80);
break;
case 2: write_1602com(er+6); //按2次fen位置显示光标
write_1602com(0x0f); //下面case3~case7基本相同,改变地址就行了
case 8: write_1602com(0x0c); //按动到第8次,设置光标不闪烁
TR0=1;//打开定时器
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x00|temp);//miao数据写入DS1302
write_1302(0x8e,0x80);
break;
}
}
}
//------------------------------加键key2----------------------------
if(key1n!=0) //当key1按下以下。再按以下键才有效(按键次数不等于零)
{if(key2==0) //上调键
{delay(10);
if(key2==0)
{buzzer=0; //蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key2);
switch(key1n)
{ case 1:miao++; //设置键按动1次,调秒
if(miao==60)
miao=0;
write_sfm(0x08,miao);
temp=(miao)/10*16+(miao)%10; //十进制转换成DS1302要求的BCD码
write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); ;//向DS1302内写秒寄存器80H写入调整后的数据BCD码
write_1302(0x8e,0x80); //打开写保护
write_1602com(er+0x09); //因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
//下面case2~case7和case1相同将相应的地址改一下就行了。
}
}
}
下面的key3与加键key2形式基本相同;
}
}
void init() //定时器、计数器设置函数
{ TMOD=0x01; //指定定时/计数器的工作方式为1
TH0=0; //定时器T0的高四位=0
TL0=0; //定时器T0的低四位=0
EA=1; //系统允许有开放的中断
ET0=1; //允许T0中断
TR0=1; //开启中断,启动定时器
}
void main() //*********主函数********
{ lcd_init(); //调用液晶屏初始化子函数
ds1302_init(); //调用DS1302时钟的初始化子函数
init(); //调用定时计数器的设置子函数
buzzer=0; //蜂鸣器长响一次
delay(80);
buzzer=1;
while(1) //无限循环下面的语句:
{keyscan();} //调用键盘扫描子函数
}
Void timer0() interrupt 1 //取得并显示日历和时间
{ TH0=0; //重复初始值
TL0=0;
DS18B20_init();
delay(1);
temwritebyte(0xcc); //写跳过ROM指令;
temwritebyte(0x44); //启动温度转换;
flag=get_tem(); //将18b20运行返回的函数结果送到变量flag中,用于显示
//读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
miao = BCD_Decimal(read_1302(0x81));//下面分秒年月日形式相同,改变地址就可以了
//显示温度、秒、时、分数据:
write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示
write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数)
write_sfm(5,fen);//分,从第二行第5个字符后开始显示
write_sfm(2,shi);//小时,从第二行第2个字符后开始显示
//显示日、月、年数据:
write_nyr(9,ri);//日期,从第二行第9个字符后开始显示
write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
write_nyr(3,nian);//年,从第二行第3个字符后开始显示
write_week(week);
}
来自:求助得到的回答
威孚半导体技术
2024-08-19 广告
威孚(苏州)半导体技术有限公司是一家专注生产、研发、销售晶圆传输设备整机模块(EFEM/SORTER)及核心零部件的高科技半导体公司。公司核心团队均拥有多年半导体行业从业经验,其中技术团队成员博士、硕士学历占比80%以上,依托丰富的软件底层... 点击进入详情页
本回答由威孚半导体技术提供
435117580
2011-10-16 · TA获得超过767个赞
知道小有建树答主
回答量:569
采纳率:0%
帮助的人:435万
追问
啊,那个太高级了,我指希望简单一点的,只要有DS1302,DS18B20,MAX232,AT89C51,LCD1602模块的就行了
追答
还高级吗!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
hzh557
2011-10-16 · TA获得超过3398个赞
知道大有可为答主
回答量:2949
采纳率:70%
帮助的人:2525万
展开全部
可以到我博客去看看,有图有程序。http://blog.sina.com.cn/s/blog_534a5d500100bdqz.html
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式