电工技术|51单片机电子钟程序设计

   更新日期:2017-03-23     来源:建材之家    作者:水电之家    浏览:37    评论:0    
核心提示:硬件部分 基于51单片机、 ds1302时钟芯片、 ds18b20温度芯片、 以及1602液晶显示的 实时时间 和 实时温度显示 。同时可通过按键 设置 年、月、日、时、分、星期。并且可以设置闹钟 当闹钟时间到时 蜂鸣器持续发出 滴..声 同时led灯不停闪烁 且在一分钟内没有按指定停止按键 闹钟将自动停止 。。。软件部分#include <reg52.h>#define

电气施工图纸会审工作要点

推荐简介:1、要审查设计图纸是否符合相关规范或有关技术质量标准,设计是否合理,考虑经济承受能力和投资取得的回报,设计和选用的产品应是开放型的,便于有条件时系统扩展、互联和信息共享。 2、要根据工程的特点和使用功能,明确业主对其项目的定位和需求。应提供意见和建议与业主,及早协调明确要设置哪些系统,以便所设系统与主体工程同步进行,避免主体完工后再上系统,难于施工,造成对建筑主体结构的破坏,加大返工......
水电之家讯:硬件部分

基于51单片机、 ds1302时钟芯片、 ds18b20温度芯片、 以及1602液晶显示的 实时时间 和 实时温度显示 。同时可通过按键 设置 年、月、日、时、分、星期。并且可以设置闹钟 当闹钟时间到时 蜂鸣器持续发出 滴..声 同时LED灯不停闪烁 且在一分钟内没有按指定停止按键 闹钟将自动停止 。。。











软件部分

#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;



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); //显示"。"

}





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;

}



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;

}

}

水电之家为您提供最全面的管材,管件,水电,电线,电工,管材水电品牌的装修知识点和各种管材水电的导购与在线购买服务,拥有最便宜的管材水电价格和最优质的售后服务,每天都有秒杀的抢购活动哦!敬请登陆水电之家:http://shuidian.jc68.com/
小程序码
 
打赏
 
更多>文章标签:水电
更多>同类水电电工资讯
0相关评论

推荐图文更多...
点击排行更多...
水电商机信息更多...
水电电工圈更多...
最新视频更多...
推荐产品更多...
天花之家 | 木门之家 | 灯具之家 | 铁艺之家 | 幕墙之家 | 五金头条 | 楼梯头条 | 墙纸头条 | 壁纸头条 | 玻璃头条 | 老姚之家 | 灯饰之家 | 电气之家 | 全景头条 | 陶瓷之家 | 照明之家 | 防水之家 | 防盗之家 | 博一建材 | 卫浴之家 | 区快洞察 | 潜江建材 | 仙桃建材 | 恩施建材 | 随州建材 | 咸宁建材 | 黄冈建材 | 荆州建材 | 孝感建材 | 荆门建材 | 鄂州建材 | 襄樊建材 | 宜昌建材 | 十堰建材 | 黄石建材 | 长沙建材 | 湘西建材 | 娄底建材 | 怀化建材 | 永州建材 | 郴州建材 |
建材 | 720全景 | 企业之家 | 移动社区 | 关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图 | 排名推广 | 广告服务 | 积分换礼 | RSS订阅 | sitemap | 粤ICP备14017808号-1
(c)2015-2017 BO-YI.COM SYSTEM All Rights Reserved
Powered by 电工之家