89c51单片机1602液晶显示时钟程序

发布日期:2022-12-20
89c51单片机1602液晶显示时钟程序

电工优优今天要和大家分享的89c51单片机1602液晶显示时钟程序相关信息,接下来我将从8051单片机堆栈容量不能超过多少字节这几个方面来介绍。

一款AT89C51单片机1602液晶显示时钟程序,功能主要有:温度、时间、日期、星期显示以及调节。有多级菜单显示。第一级菜单调节时间、日期。第二级菜单显示自定义信息。

#includereg52.h

#includeintrins.h

#define uchar unsigned char

#define uint unsigned int

sbit DQ=P2^1;

sbit light=P2^7;

sbit k1=P1^0;

sbit k2=P1^1;

sbit k3=P1^2;

sbit k4=P1^3;

sbit k5=P1^4;

sbit LED1=P1^3;

sbit LED2=P1^4;

sbit DS1302_CE=P3^5;

sbit DS1302_IO=P3^6;

sbit DS1302_SCLK=P3^7;

sbit LCD1602_RS=P2^4;

sbit LCD1602_RW=P2^5;

sbit LCD1602_EN=P2^6;

extern uchar wendu[4];

extern void get_wendu();

extern void LCD1602_init();

extern void LCD1602_wcmd(uchar cmd);

extern void LCD1602_wdat(uchar dat);

extern void LCD1602_pos(uchar x,bit y); //定义显示位置,x为列,y为行,0上1下

extern void LCD1602_dischar(uchar x,bit y,uchar dat); //在指定位置显示字符

extern void LCD1602_prints(uchar x,bit y,uchar *p); //显示字符串

extern uchar dt[7];

extern void set_time();

extern void get_time();

extern void DS1302_init();

uchar dt[7];

void DS1302_write_byte(uchar dat)

{

char i;

for(i=0;i

{

DS1302_SCLK = 0;

_nop_();

_nop_();

dat >>= 1;

DS1302_IO = CY;

DS1302_SCLK=1;

_nop_();

_nop_();

}

}

uchar DS1302_read_byte()

{

uchar i;

uchar dat = 0;

for(i=0;i

{

DS1302_SCLK = 0;

_nop_();

_nop_();

dat >>= 1;

if(DS1302_IO) dat |= 0x80;

DS1302_SCLK =1;

_nop_();

_nop_();

}

return dat;

}

void DS1302_write(uchar address,uchar dat)

{

DS1302_CE=0;

_nop_();

_nop_();

DS1302_SCLK=0;

_nop_();

_nop_();

DS1302_CE=1;

_nop_();

_nop_();

DS1302_write_byte(address);

DS1302_write_byte(dat);

DS1302_SCLK=1;

DS1302_CE=0;

}

uchar DS1302_read(uchar address)

{

uchar dat;

DS1302_CE=0;

_nop_();

_nop_();

DS1302_SCLK=0;

_nop_();

_nop_();

DS1302_CE=1;

_nop_();

_nop_();

DS1302_write_byte(address);

dat =DS1302_read_byte();

DS1302_SCLK=1;

DS1302_CE=0;

dat=dat/16*10+dat;

return dat;

}

void DS1302_init()

{

DS1302_write(0x8e,0x00);

DS1302_write(0x80,0x00);

DS1302_write(0x82,0x00);

DS1302_write(0x84,0x12);

DS1302_write(0x86,0x10);

DS1302_write(0x88,0x11);

DS1302_write(0x8a,0x06);

DS1302_write(0x8c,0x12);

DS1302_write(0x8e,0x80);

}

void set_time()

{

uchar i,j=0x80;

for(i=0;i

{

dt=dt/10*16+dt;

}

DS1302_write(0x8e,0x00);

DS1302_write(0x80,0x00);

for(i=0;i

{

DS1302_write(j,dt);

j+=2;

}

DS1302_write(0x8e,0x80);

}

void get_time()

{

dt[0] =DS1302_read(0x81);

dt[1] =DS1302_read(0x83);

dt[2] =DS1302_read(0x85);

dt[3] =DS1302_read(0x87);

dt[4] =DS1302_read(0x89);

dt[5] =DS1302_read(0x8b);

dt[6] =DS1302_read(0x8d);

}

void chaongdiaon() //充电

{

DS1302_write(0x8e,0x00);

_nop_();

_nop_();

DS1302_write(0x90, 0xa6); //使能充电 用一个二极管 用4k电阻

DS1302_write(0x8e,0x80);

_nop_();

_nop_();

}

uchar code self_char[]={

0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, //年

0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x01, //月

0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00, //日

0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, //温度标志— —摄氏度

0x00,0x04,0x0E,0x1F,0x0E,0x04,0x00,0x00, //符号◆

0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, //全开

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //

};

bit lcd_busy()

{

bit result;

LCD1602_RS=0;

LCD1602_RW=1;

LCD1602_EN=1;

_nop_();

_nop_();

_nop_();

_nop_();

result = (bit)(P0&0x80);

LCD1602_EN=0;

return(result);

}

void LCD1602_wcmd(uchar cmd)

{

while(lcd_busy());

LCD1602_RS=0;

LCD1602_RW=0;

_nop_();

_nop_();

LCD1602_EN=1;

_nop_();

_nop_();

_nop_();

_nop_();

P0=cmd;

_nop_();

_nop_();

_nop_();

_nop_();

LCD1602_EN=0;

}

void LCD1602_wdat(uchar dat)

{

while(lcd_busy());

LCD1602_RS=1;

LCD1602_RW=0;

LCD1602_EN=1;

_nop_();

_nop_();

_nop_();

_nop_();

P0=dat;

_nop_();

_nop_();

_nop_();

_nop_();

LCD1602_EN=0;

}

void LCD1602_pos(uchar x,bit y) //指定坐标,x为列,0~15,y为行,0为第一行,1为第二行。

{

if(y)LCD1602_wcmd(x|0xc0);

else LCD1602_wcmd(x|0x80);

}

void LCD1602_dischar(uchar x,bit y,uchar dat) //指定位置显示一个字符

{

LCD1602_pos(x,y);

LCD1602_wdat(dat);

}

void LCD1602_prints(uchar x,bit y,uchar *p) //指定位置显示字符串

{

LCD1602_pos(x,y);

while((*p) != '\0') {LCD1602_wdat(*p);p++;}

}

void LCD1602_init()

{

uchar i;

LCD1602_wcmd(0x40);

for(i=0;i

{

LCD1602_wdat(self_char);

}

LCD1602_wcmd(0x38);

LCD1602_wcmd(0x38);

LCD1602_wcmd(0x0c);

LCD1602_wcmd(0x06);

LCD1602_wcmd(0x01);

}

uchar wendu[4];

void delay_18b20(uchar i)

{

int j;

for(j=0;j

}

uchar init_18b20()

{

uchar i;

DQ=0;

delay_18b20(30);

DQ=1;

delay_18b20(3);

i=DQ;

delay_18b20(20);

return(i);

}

uchar read_18b20_bit()

{

uchar i;

DQ=0;

DQ=1;

for(i=0;i

return(DQ);

}

void write_18b20_bit(unsigned xbit)

{

DQ=0;

if(xbit==1)

DQ=1;

delay_18b20(5);

DQ=1;

}

uchar read_18b20_byte()

{

uchar i,j,value;

j=1;

value=0;

for(i=0;i

{

if(read_18b20_bit())

{

value=value+(j

}

delay_18b20(6);

}

return(value);

}

void write_18b20_byte(uchar x)

{

uchar i,j;

for(i=0;i

{

j=x>>i;

j=j&0x01;

write_18b20_bit(j);

delay_18b20(5);

}

}

void get_wendu()

{

uchar a,b;

float get_temp;

int temp1,temp2;

init_18b20();

write_18b20_byte(0xcc);

write_18b20_byte(0x44);

init_18b20();

write_18b20_byte(0xcc);

write_18b20_byte(0xbe);

a=read_18b20_byte(); //低8位

b=read_18b20_byte(); //高8位

temp1=b;

temp1=temp1

temp1=temp1|a;

if(b&0xfc)

{wendu[0]=1;temp1=~temp1+1;} //0正1负

else

wendu[0]=0;

get_temp=temp1*0.0625;

temp2=get_temp*10+0.5;

wendu[1]=temp200/100;

wendu[2]=temp2000/10;

wendu[3]=temp2000;

}

uchar mode=0,OK=0;

uchar dis1[16],dis2[16];

//uchar IRCOM[7],IRCODE=0;

uchar NUM1,NUM2;

uchar count;

bit L=0,select=0,DIS_EN=1,SHAN;

void delay(uint i)

{

uchar j;

while(i-- !=0)

{

for(j=0;j

}

}

void delay1(uchar i)

{

uchar j;

while(i--)

{for(j=0;j

}

void get_dis()

{

dis1[0]='2';

dis1[1]='0';

dis1[2]=0x30+dt[6]/10;

dis1[3]=0x30+dt[6];

dis1[4]=0;

dis1[5]=0x30+dt[4]/10;

dis1[6]=0x30+dt[4];

dis1[7]=1;

dis1[8]=0x30+dt[3]/10;

dis1[9]=0x30+dt[3];

dis1[10]=2;

dis1[11]=' ';

dis1[12]=' ';

switch(dt[5])

{

case 1: {

dis1[13]='M';

dis1[14]='o';

dis1[15]='n';

}

break;

case 2: {

dis1[13]='T';

dis1[14]='u';

dis1[15]='e';

}

break;

case 3: {

dis1[13]='W';

dis1[14]='e';

dis1[15]='d';

}

break;

case 4: {

dis1[13]='T';

dis1[14]='h';

dis1[15]='u';

}

break;

case 5: {

dis1[13]='F';

dis1[14]='r';

dis1[15]='i';

}

break;

case 6: {

dis1[13]='S';

dis1[14]='a';

dis1[15]='t';

}

break;

case 7: {

dis1[13]='S';

dis1[14]='u';

dis1[15]='n';

}

break;

}

dis2[0]=' ';

dis2[1]=0x30+dt[2]/10;

dis2[2]=0x30+dt[2];

dis2[3]=':';

dis2[4]=0x30+dt[1]/10;

dis2[5]=0x30+dt[1];

dis2[6]=':';

dis2[7]=0x30+dt[0]/10;

dis2[8]=0x30+dt[0];

dis2[9]=' ';

if(wendu[0]==1)

dis2[10]=0x2d;

else

dis2[10]=' ';

dis2[11]=0x30+wendu[1];

dis2[12]=0x30+wendu[2];

dis2[13]='.';

dis2[14]=0x30+wendu[3];

dis2[15]=3;

}

void keyscan()

{

if(k1==0)

{

delay(10);

if(k1==0)

{

while(!k1);

mode++;

if(mode==1 && OK==0)

LCD1602_wcmd(0x01);

if(mode==2 && OK==0)

{

mode=0;

select=0;

}

if(select==0 && OK==1)

{

if(mode==7)

mode=1;

}

if(select==1 && OK==1)

{

if(mode==6)

mode=1;

}

}

}

if(k2==0)

{

delay(10);

if(k2==0)

{

while(!k2);

if(mode==1 && OK==0)

{select=~select;LCD1602_wcmd(0x01);}

NUM1++;

}

}

if(k3==0)

{

delay(10);

if(k3==0)

{

while(!k3);

if(mode==1 && OK==0)

{select=~select;LCD1602_wcmd(0x01);}

NUM2++;

}

}

if(k4==0)

{

delay(10);

if(k4==0)

{

while(!k4);

if(mode==0)

light=~light;

if(mode !=0)

{

LCD1602_wcmd(0x01);

OK++;

NUM1=0;

NUM2=0;

if(OK==2)

{

LCD1602_wcmd(0x01);

set_time();

// set_alarm();

mode=0;

select=0;

OK=0;

}

}

}

}

if(k5==0)

{

delay(100);

if(k5==0)

{

while(!k5);

DS1302_init();

}

}

}

void display()

{

get_wendu();

get_dis();

if(mode==0) //正常模式

{

uchar i;

LED1=1;

get_time();

// get_alarm();

LCD1602_pos(0,0);

for(i=0;i

LCD1602_wdat(dis1);

LCD1602_pos(0,1);

for(i=0;i

LCD1602_wdat(dis2);

}

if(mode==1&&OK==0) //菜单模式

{

LCD1602_prints(1,0,1.Set Time);

LCD1602_prints(1,1,2.About...);

if(select)

LCD1602_dischar(0,1,4);

else

LCD1602_dischar(0,0,4);

}

if(OK==1&&select==0) //调日期模式

{

uchar i;

LCD1602_pos(0,0);

for(i=0;i

LCD1602_wdat(dis1);

LCD1602_pos(0,1);

for(i=0;i

LCD1602_wdat(dis2);

LCD1602_prints(10,1,Set...);

if(SHAN==1) LCD1602_prints(10,1,Set. );

if(mode==1) //调分模式,秒位清零

{

dt[0]=0;

LCD1602_dischar(7,1,0x30+dt[0]/10);

LCD1602_dischar(8,1,0x30+dt[0]);

if(NUM1!=0)

{

dt[1]++;

if(dt[1]==60)

dt[1]=0;

LCD1602_dischar(4,1,0x30+dt[1]/10);

LCD1602_dischar(5,1,0x30+dt[1]);

NUM1=0;

}

if(NUM2!=0)

{

dt[1]--;

if(dt[1]==-1)

dt[1]=59;

LCD1602_dischar(4,1,0x30+dt[1]/10);

LCD1602_dischar(5,1,0x30+dt[1]);

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(5,1,5);

}

else

if(mode==2) //调时模式

{

if(NUM1!=0)

{

dt[2]++;

if(dt[2]==24)

dt[2]=0;

LCD1602_dischar(1,1,0x30+dt[2]/10);

LCD1602_dischar(2,1,0x30+dt[2]);

NUM1=0;

}

if(NUM2!=0)

{

dt[2]--;

if(dt[2]==-1)

dt[2]=23;

LCD1602_dischar(1,1,0x30+dt[2]/10);

LCD1602_dischar(2,1,0x30+dt[2]);

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(2,1,5);

}

if(mode==3) //调星期状态

{

if(NUM1!=0)

{

dt[5]++;

if(dt[5]==8)

dt[5]=1;

switch(dt[5])

{

case 1: LCD1602_prints(13,0,Mon);break;

case 2: LCD1602_prints(13,0,Tue);break;

case 3: LCD1602_prints(13,0,Wed);break;

case 4: LCD1602_prints(13,0,Thu);break;

case 5: LCD1602_prints(13,0,Fri);break;

case 6: LCD1602_prints(13,0,Sat);break;

case 7: LCD1602_prints(13,0,Sun);break;

}

NUM1=0;

}

if(NUM2!=0)

{

dt[5]--;

if(dt[5]==0)

dt[5]=7;

switch(dt[5])

{

case 1: LCD1602_prints(13,0,Mon);break;

case 2: LCD1602_prints(13,0,Tue);break;

case 3: LCD1602_prints(13,0,Wed);break;

case 4: LCD1602_prints(13,0,Thu);break;

case 5: LCD1602_prints(13,0,Fri);break;

case 6: LCD1602_prints(13,0,Sat);break;

case 7: LCD1602_prints(13,0,Sun);break;

}

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(15,0,5);

}

if(mode==4) //调日模式

{

if(NUM1!=0)

{

dt[3]++;

if(dt[3]==32)

dt[3]=1;

LCD1602_dischar(8,0,0x30+dt[3]/10);

LCD1602_dischar(9,0,0x30+dt[3]);

NUM1=0;

}

if(NUM2!=0)

{

dt[3]--;

if(dt[3]==0)

dt[3]=31;

LCD1602_dischar(8,0,0x30+dt[3]/10);

LCD1602_dischar(9,0,0x30+dt[3]);

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(9,0,5);

}

if(mode==5) //调月模式

{

if(NUM1!=0)

{

dt[4]++;

if(dt[4]==13)

dt[4]=1;

LCD1602_dischar(5,0,0x30+dt[4]/10);

LCD1602_dischar(6,0,0x30+dt[4]);

NUM1=0;

}

if(NUM2!=0)

{

dt[4]--;

if(dt[4]==0)

dt[4]=12;

LCD1602_dischar(5,0,0x30+dt[4]/10);

LCD1602_dischar(6,0,0x30+dt[4]);

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(6,0,5);

}

if(mode==6) //调年模式

{

if(NUM1!=0)

{

dt[6]++;

if(dt[6]==100)

dt[6]=0;

LCD1602_dischar(2,0,0x30+dt[6]/10);

LCD1602_dischar(3,0,0x30+dt[6]);

NUM1=0;

}

if(NUM2!=0)

{

dt[6]--;

if(dt[6]==-1)

dt[6]=99;

LCD1602_dischar(2,0,0x30+dt[6]/10);

LCD1602_dischar(3,0,0x30+dt[6]);

NUM2=0;

}

if(SHAN==1) LCD1602_dischar(3,0,5);

}

}

if(OK==1&&select==1) //调闹铃模式

{

LCD1602_prints(0,0, Birthday gift );

LCD1602_prints(0,1, --by HJL);

delay(2000);

LCD1602_wcmd(0x01);

LCD1602_prints(0,0,2013-12-04 Is );

LCD1602_prints(0,1,LiYunL birthday!);

delay(2000);

LCD1602_wcmd(0x01);

LCD1602_prints(0,0,Friends together);

LCD1602_prints(0,1,for life... );

delay(2000);

LCD1602_wcmd(0x01);

mode=1 ;

OK=0;

}

}

void diy()

{

LCD1602_init();

delay(1);

LCD1602_prints(0,0, Digital Clock );

LCD1602_prints(0,1,v1.1.0 --by HJL);

delay(1000);

LCD1602_wcmd(0x01);

}

void main()

{

IT0=1; //外部中断0为下降沿触发

EX0=1; //

TMOD=0x01;

TH0=0x3C; //50ms

TL0=0xB0;

EA=1;

ET0=1;

TR0=1;

get_wendu();

diy();

chaongdiaon();

while(1)

{

P1=0xff;

keyscan();

display();

}

}

void timer0() interrupt 1

{

TH0=0x3C;

TL0=0xB0;

count++;

if(count==10)

{

count=0;

SHAN=~SHAN;

}

}

以上就是"电工优优"为大家介绍的8051单片机堆栈容量不能超过多少字节的相关信息,想了解更多"89c51单片机1602液晶显示时钟程序,8051单片机堆栈容量不能超过多少字节"相关知识,请收藏电工无忧吧。