×
单片机 > 单片机程序设计 > 详情

基于51单片机的多功能时钟温度计 DS1302+LCD1602

发布时间:2024-06-01 发布时间:
|

本设计是由STC89C52单片机为控制核心,具有在线编程功能,低功耗;时钟电路由DS1302提供,它是一种高性能、低功耗的时钟电路,工作电压为3V~5V;所以采用DS1302作为本设计的日历芯片;显示部份使用LCD1602B液晶模块进行数字显示,1602B液晶模块可以显示2行16个字符,有8位数据总线D0—D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。该模块也可以只用D4-D7作为四位数据分两次传送,这样就可以节省MCU的I/O口资源,系统主要由晶振电路、复位电路、时钟电路部分、中央处理单元、晶显示部分组成。

电路原理图如下:


制作出来的实物图如下:


Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)

单片机源程序如下:

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define LCDIO P0

sbit rs=P2^0;

sbit rd=P2^1;

sbit lcden=P2^2;

sbit acc0=ACC^0; //移位时的第0位

sbit acc7=ACC^7; //移位时用的第7位

sbit ct=P2^3;

sbit speaker=P3^5;

sbit DQ=P2^5;//ds18b20与单片机连接口

int djs11=0,js,dsmin=0,dshour=0;


uchar second,minute,hour,day,month,year,week,count=0;

uchar ReadValue,num,time;

uint tvalue;//温度值

uchar tflag;

uchar code table[]={" 2000-00-00 FRI"};

uchar code table1[]={" 00:00:00 "};

uchar code table2[]= "THUFRISATSUNMONTUEWES";

char szdata[8];

char szdata1[8];

uchar data disdata[5];

sbit DATA=P3^3; //时钟数据接口

sbit RST=P3^4;

sbit SCLK=P3^2;

sbit menu=P2^7; //菜单

sbit add=P2^6; //加一

sbit dec=P2^4;

sbit set=P2^3 ; //减一

sbit djs=P3^6;

void miaobiao();

void yx();

void delayms(int x)

{

char i;

while(x--)

{

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

}

}

void delay(uint z)

{

uint x,y;

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

for(y=110;y>0;y--);

}

void delay1(uint z)

{

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

}

void write_com(uchar com)

{

rs=0;

rd=0;

lcden=0;

LCDIO=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}


void write_date(uchar date)

{

rs=1;

rd=0;

lcden=0;

LCDIO=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}


void init()

{

uchar num;

lcden=0;


write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80);

delay(5);

write_com(0x80);

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

{

write_date(table[num]);

delay(5);

}

write_com(0x80+0x40);

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

{

write_date(table1[num]);

delay(5);

}


}


void Write1302(uchar dat)

{

uchar i;

SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备

delay1(2); //稍微等待,使硬件做好准备

for(i=0;i<8;i++) //连续写8个二进制位数据

{

DATA=dat&0x01; //取出dat的第0位数据写入1302

delay(2); //稍微等待,使硬件做好准备

SCLK=1; //上升沿写入数据

delay1(2); //稍微等待,使硬件做好准备

SCLK=0; //重新拉低SCLK,形成脉冲

dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位

}

}


void WriteSet1302(uchar Cmd,uchar dat)

{

RST=0; //禁止数据传递

SCLK=0; //确保写数居前SCLK被拉低

RST=1; //启动数据传输

delay1(2); //稍微等待,使硬件做好准备

Write1302(Cmd); //写入命令字

Write1302(dat); //写数据

SCLK=1; //将时钟电平置于已知状态

RST=0; //禁止数据传递

}


uchar Read1302(void)

{

uchar i,dat;

delay(2); //稍微等待,使硬件做好准备

for(i=0;i<8;i++) //连续读8个二进制位数据

{

dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位

if(DATA==1) //如果读出的数据是1

dat|=0x80; //将1取出,写在dat的最高位

SCLK=1; //将SCLK置于高电平,为下降沿读出

delay1(2); //稍微等待

SCLK=0; //拉低SCLK,形成脉冲下降沿

delay1(2); //稍微等待

}

return dat; //将读出的数据返回

}


uchar ReadSet1302(uchar Cmd)

{

uchar dat;

RST=0; //拉低RST

SCLK=0; //确保写数居前SCLK被拉低

RST=1; //启动数据传输

Write1302(Cmd); //写入命令字

dat=Read1302(); //读出数据

SCLK=1; //将时钟电平置于已知状态

RST=0; //禁止数据传递

return dat; //将读出的数据返回

}

void Init_DS1302(void)

{

WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令

WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值

WriteSet1302(0x82,((12/10)<<4|(12%10))); //根据写分寄存器命令字,写入分的初始值

WriteSet1302(0x84,((11/10)<<4|(11%10))); //根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((25/10)<<4|(25%10))); //根据写日寄存器命令字,写入日的初始值

WriteSet1302(0x88,((1/10)<<4|(1%10))); //根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((13/10)<<4|(13%10))); //nian

WriteSet1302(0x8a,((1/10)<<4|(1%10)));

}


void DisplaySecond(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0xc7);

write_date(0x30+i);

write_date(0x30+j);

}

void DisplayMinute(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0xc4);

write_date(0x30+i);

write_date(0x30+j);

}

void DisplayHour(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0xc1);

write_date(0x30+i);

write_date(0x30+j);

}


void DisplayDay(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0x89);

write_date(0x30+i);

write_date(0x30+j);

}


void DisplayMonth(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0x86);

write_date(0x30+i);

write_date(0x30+j);

}


void DisplayYear(uchar x)

{

uchar i,j;

i=x/10;

j=x%10;

write_com(0x83);

write_date(0x30+i);

write_date(0x30+j);

}

void DisplayWeek(uchar x)

{ uchar i;

x=x*3;

write_com(0x8c);

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

{

write_date(table2[x]);

x++;

}

}


void read_date(void)

{

ReadValue = ReadSet1302(0x81);

second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

ReadValue = ReadSet1302(0x83);

minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

ReadValue = ReadSet1302(0x85);

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
51单片机多功能时钟温度计DS1302LCD1602

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
采用AT89C2051的数字可调稳压电源单片机源程序