基于51单片机的ds1302与LM016L液晶时钟设计.docx

上传人:b****8 文档编号:10330096 上传时间:2023-02-10 格式:DOCX 页数:16 大小:119.43KB
下载 相关 举报
基于51单片机的ds1302与LM016L液晶时钟设计.docx_第1页
第1页 / 共16页
基于51单片机的ds1302与LM016L液晶时钟设计.docx_第2页
第2页 / 共16页
基于51单片机的ds1302与LM016L液晶时钟设计.docx_第3页
第3页 / 共16页
基于51单片机的ds1302与LM016L液晶时钟设计.docx_第4页
第4页 / 共16页
基于51单片机的ds1302与LM016L液晶时钟设计.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

基于51单片机的ds1302与LM016L液晶时钟设计.docx

《基于51单片机的ds1302与LM016L液晶时钟设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的ds1302与LM016L液晶时钟设计.docx(16页珍藏版)》请在冰豆网上搜索。

基于51单片机的ds1302与LM016L液晶时钟设计.docx

基于51单片机的ds1302与LM016L液晶时钟设计

基于51单片机的时钟设计

一.基本功能

利用AT89c51作为主控器与时钟芯片DS1302组成一个时钟系统,并由LM016L液晶显示。

二.硬件设计

图1.总设计图

1.单片机最小系统

1.1选用AT89C51的引脚功能

图2.AT89C51

XTAL1:

单芯片系统时钟的反向放大器输入端。

XTAL2:

系统时钟的反向放大器输出端,一般在设计上只要在XTAL1和XTAL2上接上一只石英震荡晶体系统就可以工作了,此外可以在两引脚与地之间加入20PF的小电容,可以使系统更稳定,避免噪音干扰而死机。

RESET:

重置引脚,高电平动作,当要对晶体重置时,只要对此引脚电平提升至高电平并保持两个及其周期以上的时间便能完成系统重置的各项动作,使得内部特殊功能寄存器内容均被设成已知状态。

1.2复位电路

如图所示,当按下按键时,就能完成整个系统的复位,使得程序从新运行。

图3.复位电路

1.3时钟电路

时钟电路用于产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进行工作。

在AT89C51芯片内部有一个高增益反相放大器,其输入端为芯片引脚X1,输出端为引脚X2,在芯片的外部跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡器。

此电路采用12MHz的石英晶体。

图4.时钟电路

2.时钟芯片部分

2.1DS1302引脚说明

图.5

1)Vcc1:

后备电源,VCC2:

主电源。

在主电源关闭的情况下,也能保持时钟的连续运行。

DS1302由Vcc1或Vcc2两者中的较大者供电。

当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。

当Vcc2小于Vcc1时,DS1302由Vcc1供电。

2)X1、X2:

振荡源,外接32.768kHz晶振。

3)RST:

复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。

RST输入有两种功能:

首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。

当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。

如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电运行时,在Vcc>2.0V之前,RST必须保持低电平。

只有在SCLK为低电平时,才能将RST置为高电平。

4)I/O为串行数据输入输出端(双向)。

5)SCLK为时钟输入端。

2.2时钟电路

图.6

3.LM016L液晶

图7.LM016L引脚图

LM016L与1602使用方法相同。

引脚说明:

引脚

符号

功能说明

1

VSS

一般接地

2

VDD

接电源(+5V)

3

V0

液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。

4

RS

RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。

5

R/W

R/W为读写信号线,高电平

(1)时进行读操作,低电平(0)时进行写操作。

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位(最高位)(也是busyflang)

电路接口说明:

AT889C51的P0口作为数据的输出端,P3.5和P3.6,P3.7作为控制信号的输出端。

三.软件设计

3.1编程语言及编程软件的选择

本设计选择C语言作为编程语言。

C语言虽然执行效率没有汇编语言高,但语言简洁,使用方便,灵活,运算丰富,表达化类型多样化,数据结构类型丰富,具有结构化的控制语句,程序设计自由度大,有很好的可重用性,可移植性等特点。

而汇编语言使用起来并没有这么方便。

本设计选用了Keil作为编程软件,.KeilC51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。

在开发大型软件时更能体现高级语言的优势。

  

3.2时间的显示

ML016L和1602一样,都是两行十六列的液晶显示屏。

通过程序对ML016L进行初始化后,通过写指令和写数据的操作就可以再液晶屏上显示出对应的数据,而时钟数据则是从DS1302获取。

这样可以显示出时间。

四.程序

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitrs=P2^0;//1602命令\数据选择端

sbite=P2^1;//1602使能端

sbitsck=P3^6;//DS1302

sbitio=P3^7;//DS1302数据端

sbitrst=P3^5;//DS1302CE端RST的功能

uinttemp;//定义整型的温度数据

floatf_temp;

ucharcodenum[]="0123456789";//定义浮点型的温度数据

ucharcodenian[]="20--";

ucharcodeshi[]=":

:

";

ucharread_add[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//DS1302读数据地址端

ucharwrite_add[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//DS1302写数据地址端

uchartime_data[]={11,1,12,5,18,00,00};//设置初始时间

uchardisp[14];//定义数组

voiddelayms(uintz)//毫秒级延时函数

{

uinti,j;

for(i=z;i>0;i--)

for(j=120;j>0;j--);

}

voiddelayus(uinttime)//微秒级延时函数

{

while(time--);

}

//1602液晶

voidwrite_com(ucharcom)//写指令函数

{

rs=0;

P0=com;

delayms(5);

e=1;

delayms(5);

e=0;

}

voidwrite_data(uchardate)//写数据函数

{

rs=1;

P0=date;

delayms(5);

e=1;

delayms(5);

e=0;

}

voidinit()//液晶初始化函数

{

ucharnum;

write_com(0x38);

write_com(0x06);

write_com(0x0c);

write_com(0x01);

write_com(0x80+0x40);

for(num=0;num<8;num++)

{

write_data(shi[num]);

delayms

(1);

}

write_com(0x80);

for(num=0;num<10;num++)

{

write_data(nian[num]);

delayms

(1);

}

}

//DS1302

voidwrite_ds1302_byte(uchardat)//写一个字节函数

{

uchari;

for(i=0;i<8;i++)

{

sck=0;

io=dat&0x01;

dat=dat>>1;

sck=1;

}

}

voidwrite_ds1302(ucharadd,uchardat)//写一个地址和数据函数

{

rst=0;

_nop_();

sck=0;

_nop_();

rst=1;

_nop_();

write_ds1302_byte(add);

write_ds1302_byte(dat);

rst=0;

_nop_();

io=1;

sck=1;

}

ucharread_ds1302(ucharadd)//读地址函数

{

uchari,value;

rst=0;

_nop_();

sck=0;

_nop_();

rst=1;

_nop_();

write_ds1302_byte(add);

for(i=0;i<8;i++)

{

value=value>>1;

sck=0;

if(io)

value=value|0x80;

sck=1;

}

rst=0;

_nop_();

sck=0;

_nop_();

sck=1;

io=0;

returnvalue;

}

voidread_rtc(void)//读时钟函数

{

uchari;

for(i=0;i<7;i++)

{

time_data[i]=read_ds1302(read_add[i]);

}

}

voidz(void)//周

{

write_com(0x80+0x40+9);

switch(disp[2])

{

case1:

write_data('M');

delayms(5);

write_data('o');

delayms(5);

write_data('n');

break;

case2:

write_data('T');

delayms(5);

write_data('u');

delayms(5);

write_data('e');

break;

case3:

write_data('W');

delayms(5);

write_data('e');

delayms(5);

write_data('n');

break;

case4:

write_data('T');

delayms(5);

write_data('h');

delayms(5);

write_data('u');

break;

case5:

write_data('F');

delayms(5);

write_data('r');

delayms(5);

write_data('i');

break;

case6:

write_data('S');

delayms(5);

write_data('a');

delayms(5);

write_data('t');

break;

case7:

write_data('S');

delayms(5);

write_data('u');

delayms(5);

write_data('n');

break;

}

}

voidtime_change(void)//时钟处理函数

{

disp[0]=time_data[0]%16;//年

disp[1]=time_data[0]/16;

disp[2]=time_data[1]%16;//周

disp[3]=time_data[1]/16;

disp[4]=time_data[2]%16;//月

disp[5]=time_data[2]/16;

disp[6]=time_data[3]%16;//日

disp[7]=time_data[3]/16;

disp[8]=time_data[4]%16;//时

disp[9]=time_data[4]/16;

disp[10]=time_data[5]%16;//分

disp[11]=time_data[5]/16;

disp[12]=time_data[6]%16;//秒

disp[13]=time_data[6]/16;

}

voiddisplay()//时钟显示函数

{

write_com(0x80+2);//年

write_data(0x30+disp[1]);

write_data(0x30+disp[0]);

z();//周

write_com(0x80+5);//月

write_data(0x30+disp[5]);

write_data(0x30+disp[4]);

write_com(0x80+8);//日

write_data(0x30+disp[7]);

write_data(0x30+disp[6]);

write_com(0x80+0x40);//时

write_data(0x30+disp[9]);

write_data(0x30+disp[8]);

write_com(0x80+0x40+3);//分

write_data(0x30+disp[11]);

write_data(0x30+disp[10]);

write_com(0x80+0x40+6);//秒

write_data(0x30+disp[13]);

write_data(0x30+disp[12]);

/*write_com(0x80+0x40+9);

write_data(0x30+disp[2]);*/

}

voidmain()

{

uchari;

init();

write_com(0x80+14);

write_data('.');

//set_rtc();

while

(1)

{

read_rtc();

display();

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1