1个(#ifndef LCD_H #define LCD_H ),2个(#include<reg52.h> #include<lcd.h>)

1个(#ifndef LCD_H #define LCD_H ),2个(#include<reg52.h> #include<lcd.h>),第1张

两个宏是告诉编译器如果LCD_H还没有被定义就编译这个文件,由于编译器跑过这个文件之后,LCD_H是会被定义的,故后面都不会再被编到这是防止这个文件被多个C档包含时被重复编译而出错

生成HEX主要是用C51的编译器,好久不用了,忘记叫什么名字了,要在Tool里勾上生成Hex文件然后编译一下就生成了

236 显示模块的设计

本设计中由于要对时间、温度进行显示,所以选择液晶显示屏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端和P20,R/W端和P21, E 端和P22相连,当RS=0时,对LCD1602写入指令;当RS=1时,对LCD1602写入数据。当R/W端接高电平时芯片处于读数据状态,反之处于写数据状态,E端为使能信号端。当R/W为高电平,E端也为高电平,RS为低电平时,液晶显示屏显示需要显示的示数。图211为1602液晶显示屏与单片机的硬件连接图。

图211 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=tem00625;

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); //设置液晶工作模式 意思:162行显示,57点阵,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=Decimal10+(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)/1016+(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)/1016+(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)/1016+(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);

}

以上就是关于1个(#ifndef LCD_H #define LCD_H ),2个(#include<reg52.h> #include<lcd.h>)全部的内容,包括:1个(#ifndef LCD_H #define LCD_H ),2个(#include<reg52.h> #include<lcd.h>)、基于DS1302与AT89C51的实时日历时钟的LCD显示程序你还有么还有图的、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9850751.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存