51单片机带闹钟可调时间的电子时钟程序设计

来源:本站
导读:目前正在解读《51单片机带闹钟可调时间的电子时钟程序设计》的相关信息,《51单片机带闹钟可调时间的电子时钟程序设计》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《51单片机带闹钟可调时间的电子时钟程序设计》的详细说明。
简介:基于51单片机、 ds1302时钟芯片、 ds18b20温度芯片、 以及1602液晶显示的实时时间 和 实时温度显示 。同时可通过按键 设置 年、月、日、时、分、星期。并且可以设置闹钟 当闹钟时间到时 蜂鸣器持续发出 滴..声 同时led灯不停闪烁 且在一分钟内没有按指定停止按键 闹钟将自动停止 。

硬件部分

51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计51单片机带闹钟可调时间的电子时钟程序设计

软件部分

#include <reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit spk=P1^7;

sbit led=P1^5;

sbit DQ=P1^0;

sbit RS=P2^4;

sbit RW=P2^5;

sbit EN=P2^6;

sbit key1=P2^0;

sbit key2=P2^1;

sbit key3=P2^2;

sbit key4=P2^3;

sbit IO=P3^6;

sbit RST=P3^7;

sbit SCLK=P3^5;

uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

int nian,xing,yue,ri,shi,fen,miao;

uchar num,temp,c,d,time[7],a,b,aa,bb,ns,ng,ys,yg,rs,rg,ss,sg,fs,fg,ms,mg,flag;

/*******************1602************************/

void delay(int z)

{

int x,y;

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

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

}

void write_com(uchar com) //写命令

{

RS=0;

P0=com;

delay(5);

EN=1;

delay(5);

EN=0;

}

void write_data(uchar date) //写数据

{

RS=1;

P0=date;

delay(5);

EN=1;

delay(5);

EN=0;

}

void init() //初始化

{

RW=0;

EN=0;

write_com(0x38); //显示模式设置

write_com(0x0c); //开显示 不显示光标 不闪

write_com(0x06);//写一个字符 地址指针 光标 加一 整屏不移动

write_com(0x01); //显示清零

write_com(0x80+0x04);

write_data('2');

write_com(0x80+0x05);

write_data('0');

write_com(0x80+0x00);

write_data('c');

write_com(0x80+0x01);

write_data('a');

write_com(0x80+0x02);

write_data('i');

write_com(0x80+0x4e);

write_data(0xdf);

write_com(0x80+0x4f);

write_data('C');

write_com(0x80+0x4b);

write_data(0x2e); //显示"。"

}

/**************DS18B20****************/

void delay1(unsigned int t)//延时函数

{

while(t--);

}

void init1()//初始化

{

uchar n=0;

DQ=1; //DQ复位

delay1(8);

DQ=0; //主机将DQ拉低

delay1(80); //大于480us的延时

DQ=1;

delay1(5); //延时15~60us

n=DQ;

delay1(5); //若n=0初始成功 n=1初始失败(可设置返回值查看n是否为1)

}

void write_byte(uchar dat) //写入一个字节

{

uint i;

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

{

DQ=0;

DQ=dat&0x01;

delay1(12);

DQ=1;

dat>>=1;

}

delay1(4);

}

uchar read_byte() //读入一个字节

{

uint k=0;

uchar value=0;

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

{

DQ=0;

value>>=1;

DQ=1;

if(DQ)

value|=0x80;

delay1(4);

}

return value;

}

uchar read_temp() //读取温度函数

{

uchar a=0,b=0;

init1();

write_byte(0xcc);

write_byte(0x44);

delay1(200);

init1();

write_byte(0xcc);

write_byte(0xbe);

a=read_byte();

b=read_byte();

c=b;

d=a;

b<<=4;

b+=(a&0xf0)>>4;

return b;

}

/***********************1302**********************/

void wirte_byte1(uchar date) //写入一个字节

{

uchar i;

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

{

IO=date&0x01;

SCLK=0;

SCLK=1;

date=date>>1;

}

}

uchar read_byte1() //读一个字节

{

uchar dat,i;

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

{

dat=dat>>1;

SCLK=0;

if(IO)

dat=dat|0x80;

SCLK=1;

}

return(dat);

}

void write_ds1302(uchar add,uchar date) //将数据写入1302中

{

RST=0;

SCLK=0;

RST=1;

wirte_byte1(add);

wirte_byte1(date);

RST=0;

SCLK=1;

}

uchar read_ds1302(uchar add) //读出1302中数据

{

uchar temp;

RST=0;

SCLK=0;

RST=1;

wirte_byte1(add);

temp=read_byte1();

RST=0;

SCLK=0;

return (temp);

}

uchar huan_BCD(uint z) //将数据 转换成BCD

{

uint a,b;

a=z/10;

b=z%10;

a=a&0xff;

b=b&0xff;

a<<=4;

a=a|b;

return (a);

}

void xian_shi() //液晶显示函数

{

if(b==0&a==0)

{

ms=time[0]/16;

mg=time[0]%16;

fs=time[1]/16;

fg=time[1]%16;

fen=fs*10+fg;

ss=time[2]/16;

sg=time[2]%16;

shi=ss*10+sg;

rs=time[3]/16;

rg=time[3]%16;

ri=rs*10+rg;

ys=time[4]/16;

yg=time[4]%16;

yue=ys*10+yg;

ns=time[6]/16;

ng=time[6]%16;

nian=ns*10+ng;

xing=time[5];

}

if(a==1|b==1)

{

ss=shi/10;

sg=shi%10;

write_com(0x80+0x41);

write_data(0xff);

write_com(0x80+0x40);

write_data(table[ss]);

write_com(0x80+0x41);

write_data(table[sg]);

}

if(a==2|b==2)

{

fs=fen/10;

fg=fen%10;

write_com(0x80+0x44);

write_data(0xff);

write_com(0x80+0x43);

write_data(table[fs]);

write_com(0x80+0x44);

write_data(table[fg]);

}

if(a==3)

{

rs=ri/10;

rg=ri%10;

write_com(0x80+0x0d);

write_data(0xff);

write_com(0x80+0x0c);

write_data(table[rs]);

write_com(0x80+0x0d);

write_data(table[rg]);

}

if(a==4)

{

ys=yue/10;

yg=yue%10;

write_com(0x80+0x0a);

write_data(0xff);

write_com(0x80+0x09);

write_data(table[ys]);

write_com(0x80+0x0a);

write_data(table[yg]);

}

if(a==5)

{

ns=nian/10;

ng=nian%10;

write_com(0x80+0x07);

write_data(0xff);

write_com(0x80+0x06);

write_data(table[ns]);

write_com(0x80+0x07);

write_data(table[ng]);

}

if(a==6)

{

write_com(0x80+0x0f);

write_data(0xff);

write_com(0x80+0x0f);

write_data(table[xing]);

}

write_com(0x80+0x06); //在液晶第一行第七八位显示 年

write_data(table[ns]);

write_com(0x80+0x07);

write_data(table[ng]);

write_com(0x80+0x08);

write_data('-');

write_com(0x80+0x09); //在液晶第一行第十十一位显示 月

write_data(table[ys]);

write_com(0x80+0x0a);

write_data(table[yg]);

write_com(0x80+0x0b);

write_data('-');

write_com(0x80+0x0c); //在液晶第一行第十三 十四位显示 日

write_data(table[rs]);

write_com(0x80+0x0d);

write_data(table[rg]);

write_com(0x80+0x0f); //在液晶第一行第十七位显示 星期

write_data(table[xing]);

write_com(0x80+0x40); //在液晶第二行第二三位显示 时

write_data(table[ss]);

write_com(0x80+0x41);

write_data(table[sg]);

write_com(0x80+0x42);

write_data(':');

write_com(0x80+0x43); //在液晶第二行第五六位显示 分

write_data(table[fs]);

write_com(0x80+0x44);

write_data(table[fg]);

write_com(0x80+0x45);

write_data(':');

write_com(0x80+0x46); //在液晶第二行第八九位显示 秒

write_data(table[ms]);

write_com(0x80+0x47);

write_data(table[mg]);

}

void keyscan() //按键设置函数 可任意设置年月日时分秒星期的数值

{

if(key4!=0)

{

if(key1==0) //key1按键 选择需设置的位

{

if(key1==0)

{

a++;

delay(1);

}

while(!key1)

{

delay(1);

}

}

if(a!=0)

{

if(key2==0) //key2按键 可将需设置的数 调大

{

if(a==1)

{

shi++;

if(shi>=24)

{

shi=0;

}

}

if(a==2)

{

fen++;

if(fen>=60)

{

fen=0;

}

}

if(a==3)

{

ri++;

if(ri>=32)

{

ri=1;

}

}

if(a==4)

{

yue++;

if(yue>=12)

{

yue=1;

}

}

if(a==5)

{

nian++;

if(nian>=99)

{

nian=0;

}

}

if(a==6)

{

xing++;

if(xing>=8)

{

xing=1;

}

}

}

if(key3==0) //key3按键 可将需设置的数 调小

{

if(a==1)

{

shi--;

if(shi<0)

{

shi=23;

}

}

if(a==2)

{

fen--;

if(fen<0)

{

fen=59;

}

}

if(a==3)

{

ri--;

if(ri<1)

{

ri=31;

}

}

if(a==4)

{

yue--;

if(yue<1)

{

yue=12;

}

}

if(a==5)

{

nian--;

if(nian<0)

{

nian=99;

}

}

if(a==6)

{

xing--;

if(xing<1)

{

xing=7;

}

}

}

if(a==7) //当按下key1 7次后 将个数据写入1302

{

a=0;

write_ds1302(0x8e,0x00); //WP=0 写操作

write_ds1302(0x80,0x00);//0x80是写秒数据

write_ds1302(0x82,huan_BCD(fen));//0x82是写分数据

write_ds1302(0x84,huan_BCD(shi));//0x84是写时数据

write_ds1302(0x86,huan_BCD(ri));//0x84是写日数据

write_ds1302(0x88,huan_BCD(yue));//0x84是写月数据

write_ds1302(0x8a,huan_BCD(xing));//0x84是写星期数据

write_ds1302(0x8c,huan_BCD(nian));//0x84是写年数据

write_ds1302(0x8e,0x80); //WP=1 写保护

}

}

}

}

void naozhong() //通过按键设置闹钟 时 分

{

if(key1!=0)

{

if(key4==0)

{

if(key4==0)

{

b++;

delay(1);

}

while(!key4)

{

delay(1);

}

}

if(b!=0)

{

if(key2==0) //key2按键 可将需设置的数 调大

{

if(b==1)

{

shi++;

if(shi>=24)

{

shi=0;

}

}

if(b==2)

{

fen++;

if(fen>=60)

{

fen=0;

}

}

}

if(key3==0) //key3按键 可将需设置的数 调小

{

if(b==1)

{

shi--;

if(shi<0)

{

shi=23;

}

}

if(b==2)

{

fen--;

if(fen<0)

{

fen=59;

}

}

}

aa=huan_BCD(shi); //将设置的时钟 赋值给aa

bb=huan_BCD(fen);//将设置的分钟 赋值给bb

if(b==3) //当按下key4 3次后 闹钟设置完成

{

b=0;

}

}

}

}

void main()

{

uint i,temp;

init();

TMOD=0x10;

EA=1;

TH1=(65536-51200)/256;

TL1=(65536-51200)%256;

ET1=1;

while(1)

{

temp=0x81; //读的初始地址

for(i=0;i<7;i++) //分别把秒分时日月年星期数据读出分7次读好一次地址加2" temp+=2;"

{

time[i]=read_ds1302(temp);

temp+=2;

}

if(bb==time[1]&aa==time[2]&!time[0]) //如果读出来的时钟 分钟与1302读出来的值相等且读出来的秒钟为零时 进入中断

{

TR1=1;

flag=1; //标志位设置为1

}

if(key3==0) //进入闹钟后 可由key3按下 停止中断标志位置零 允许调时闹钟设置按键动作 停止闹铃

{

led=1;

spk=1;

flag=0;

TR1=0;

}

if(flag!=1) //当进入闹钟中断后 调时与设置闹钟的按键 无效

{

naozhong();

keyscan();

}

xian_shi();

temp=read_temp();

write_com(0x80+0x49);

write_data(table[temp/10]); //在液晶第二行第十位显示温度的十位

write_com(0x80+0x4a);

write_data(table[temp%10]); //在液晶第二行第十一位显示温度的个位

write_com(0x80+0x4c);

write_data(table[(d&0x0f)*625/1000]); //在液晶第二行第十三位显示温度的小数点后一位

write_com(0x80+0x4d);

write_data(table[(d&0x0f)*625/100%10]); //在液晶第二行第十四位显示温度的小数点后二位

}

}

void timer1() interrupt 3 //定时器

{

uint t;

TH1=(65536-50000)/256;

TL1=(65536-50000)%256;

t++;

spk=0; //蜂鸣器 发出 滴答 声

led=!led; //发光二极管 不停闪烁

delay1(10);

if(t==1120) //约1分钟后 闹钟自动停止标志位

{

led=1;

spk=1;

t=0;

TR1=0;

flag=0;

}

}

提醒:《51单片机带闹钟可调时间的电子时钟程序设计》最后刷新时间 2024-03-14 01:18:49,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《51单片机带闹钟可调时间的电子时钟程序设计》该内容的真实性请自行鉴别。