基于单片机的多功能电子钟设计Proteus仿真程序.docx

上传人:b****1 文档编号:335909 上传时间:2023-04-29 格式:DOCX 页数:24 大小:44.34KB
下载 相关 举报
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第1页
第1页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第2页
第2页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第3页
第3页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第4页
第4页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第5页
第5页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第6页
第6页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第7页
第7页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第8页
第8页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第9页
第9页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第10页
第10页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第11页
第11页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第12页
第12页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第13页
第13页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第14页
第14页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第15页
第15页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第16页
第16页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第17页
第17页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第18页
第18页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第19页
第19页 / 共24页
基于单片机的多功能电子钟设计Proteus仿真程序.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于单片机的多功能电子钟设计Proteus仿真程序.docx

《基于单片机的多功能电子钟设计Proteus仿真程序.docx》由会员分享,可在线阅读,更多相关《基于单片机的多功能电子钟设计Proteus仿真程序.docx(24页珍藏版)》请在冰点文库上搜索。

基于单片机的多功能电子钟设计Proteus仿真程序.docx

基于单片机的多功能电子钟设计Proteus仿真程序

#include

#defineucharunsignedchar

#defineuintunsignedint

#definelcddataP0

#definereadalarmsecond0xc7  //定义从DS1302中读闹钟秒值的命令字节.

#definewritealarmsecond0xc6  //定义往DS1302中写闹钟秒值的命令字节.

#definereadalarmminute0xc5  //定义从DS1302中读闹钟分值的命令字节.

#definewritealarmminute0xc4  //定义往DS1302中写闹钟分值的命令字节.

#definereadalarmhour0xc3    //定义从DS1302中读闹钟小时值的命令字节.

#definewritealarmhour0xc2  //定义往DS1302中写闹钟小时值的命令字节.

sbitlcdrs=P2^0;  //LCD数据/命令选择端(H/L)

sbitlcdrw=P2^1;  //LCD读/写选择端(H/L)

sbitlcden=P2^2;  //LCD使能控制

sbitDQ=P3^4;

sbitbeep=P2^3;    //蜂鸣器控制端

sbitkmenu=P3^0;  //功能键

sbitkup=P3^1;   //增大键

sbitkdown=P3^2;   //减小键

sbitkalarm=P3^3; //闹钟查看键

sbitdsclk=P1^1;  //ds1302的时钟信号端

sbitdsdata=P1^0; //ds1302的数据I/O端

sbitdsrst=P1^2;  //ds1302的复位端

sbitACC7=ACC^7;  //定义累加器的最高和最低位。

sbitACC0=ACC^0;

bitflagalarm,flagseta,flagset;//分别定义闹钟响标志位,闹钟设置标志位,

//和时间设置标志位.

ucharkmenunum,s,m,h;  //功能键被按次数的计数器.

charsecond,minute,hour,year,month,day,week;

ucharinittime[7]={0x00,0x00,0x16,0x01,0x05,0x07,0x11};  //初始化后设置为:

//11年5月1日星期日,16点0分0秒,

//从左往右的数据依次是,秒,分,时,日,月,星期,年。

ucharcodet1[]="20 - -   ";  //液晶固定显示部分。

ucharcodet2[]=" :

 :

   ";

ucharcodet3[]="CLOCKALARM:

";

//各函数声明.

voiddelay(uintz); //毫秒级延时函数。

voiddi();      //蜂鸣器发声函数。

voidwritecom(ucharcom); //液晶写命令函数。

voidwritedata(uchardat);  //液晶写数据函数。

voidwritetime(ucharadd,chardat);//液晶刷新时分秒。

voidwritenyr(ucharadd,chardat);//液晶刷新日期。

voidwriteweek(charweek);//液晶星期几显示函数。

voidkeyscan();//键盘扫描函数。

voiddswritebyte(uchard);//往DS1302写入一个字节。

uchardsreadbyte();//从DS1302读出一个字节。

voiddswrite(ucharadd,uchardat);//向DS1302的指定地址写入一个字节。

uchardsread(ucharadd);  //从DS1302的指定地址读出一个字节.

voidinit1302time(uchar*pClock);//DS1302时间初始化函数.

voidinit();  //初始化函数。

ds18b20_delay(ucharxus);   //延时xus

voidwrite_onechar(uchardat);    //向18B20写一字节

ucharread_onechar();    //从18B20读一字节

uintread_wendu();     //DS18B20读温度

voidwendu_desplay(uintdat);//温度值送液晶显示函数

voiddelay(uintz) //毫秒级延时函数。

{

uintx,y;

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

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

}

ds18b20_delay(ucharxus)   //延时xus

{

while(xus--);  

}

/**********************ds18b20***********************/

voidds18b20_init()        //DS18B20初始化

{

ucharx=0;

DQ=1;

ds18b20_delay(8);

DQ=0;

ds18b20_delay(80);

DQ=1;

ds18b20_delay(14);

x=DQ;

ds18b20_delay(20);  

}

voidwrite_onechar(uchardat)    //写一字节

{

uchari;

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

{

DQ=0;

if(dat&0x01==0x01)

DQ=1;

else

DQ=0;

ds18b20_delay(5);

DQ=1;

ds18b20_delay

(1);

dat>>=1;

}

}

ucharread_onechar()    //读一字节

{

ucharvalue=0,i;

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

{

value>>=1;

DQ=0;

ds18b20_delay

(1);

DQ=1;

if(DQ==1)

value|=0x80;  

else

value&=0x7f;

ds18b20_delay(4);

}

returnvalue;

}

uintread_wendu()     //DS18B20读温度     

{

uchara=0,b=0;

uintwen=0x0000;

ds18b20_init();      //初始化

write_onechar(0xcc);  //跳过读序号列号的操作

write_onechar(0x44);  //启动温度转换

ds18b20_delay(150);    

ds18b20_init();      //初始化

write_onechar(0xcc);  //跳过读序号列号的操作

write_onechar(0xbe);  //读取温度寄存器等(共可读9个寄存器)前两个就是温度

ds18b20_delay(150);

b=read_onechar();    //读取温度值低位

a=read_onechar();    //读取温度值高位

wen=a;

wen=(wen<<8)|b;

returnwen;

}

voidwendu_desplay(uintdat)       //温度转换后送显示

{

floattemp;

unsignedchartemp_shi,temp_ge,temp_shu;

temp=dat*0.625;            //dat*0.0625*10

temp_shi=temp/100;      //取十位 temp除不用定义类型

temp_ge=((uint)temp)%100/10;//取个位 temp求模要定义类型,为16位,故定义uint

temp_shu=((uint)temp)%100%10;//取小数

writecom(0x80+0x40+10);      //送显示

writedata(0x30+temp_shi);

writedata(0x30+temp_ge);

writedata(0x2e); 

writedata(0x30+temp_shu);

writedata(0xdf);         //温度符号

writedata(0x43);  

}

voiddi()      //蜂鸣器发声函数。

{

beep=0;

delay(100);

beep=1;

}

voidwritecom(ucharcom) //液晶写命令函数。

{

lcden=0;

lcdrw=0;

lcdrs=0;

lcddata=com;

delay(3);

lcden=1;

delay(3);

lcden=0;  

}

voidwritedata(uchardat)  //液晶写数据函数。

{

lcden=0;

lcdrw=0;

lcdrs=1;

lcddata=dat;

delay(3);

lcden=1;

delay(3);

lcden=0;

}

voidwritetime(ucharadd,chardat)//液晶刷新时分秒。

{           //0为时的开始位置,3为分,6为秒。

charshi,ge;

shi=dat/10;

ge=dat%10;

writecom(0x80+0x40+add);

writedata(0x30+shi);

writedata(0x30+ge);

}

voidwritenyr(ucharadd,chardat)//液晶刷新日期。

{            //2为年,5为月,8为日。

charshi,ge;

shi=dat/10;

ge=dat%10;

writecom(0x80+add);

writedata(0x30+shi);

writedata(0x30+ge);

}

voidwriteweek(charweek)//液晶星期几显示函数。

{

writecom(0x80+12);

switch(week)

{

case1:

writedata('M');delay(5);

writedata('O');delay(5);

writedata('N');

break;

case2:

writedata('T');delay(5);

writedata('U');delay(5);

writedata('E');

break;

case3:

writedata('W');delay(5);

writedata('E');delay(5);

writedata('D');

break;

case4:

  writedata('T');delay(5);

writedata('H');delay(5);

writedata('U');

break;

case5:

  writedata('F');delay(5);

writedata('R');delay(5);

writedata('I');

break;

case6:

  writedata('S');delay(5);

writedata('A');delay(5);

writedata('T');

break;

case7:

  writedata('S');delay(5);

writedata('U');delay(5);

writedata('N');

break;

}

}

voidkeyscan()//键盘扫描函数。

{

uchari;

if(flagalarm==1)//如果闹钟在响,任意键停止闹钟响。

{

if((kmenu==0)||(kup==0)||(kdown==0)||(kalarm==0))

{

delay(4);

if((kmenu==0)||(kup==0)||(kdown==0)||(kalarm==0))

{

while(!

(kmenu&&kup&&kdown&&kalarm));

di();

flagalarm=0;//清除闹钟标志。

  

}

}

}

if(kmenu==0) //检测功能键。

{

delay(4);

if(kmenu==0)

{

kmenunum++;//记录功能键按下次数。

if(flagseta==1)//检测是否在进行闹钟设置。

      

if(kmenunum==4)

kmenunum=1;//因为进行闹钟设置时,只调节

//时分秒,所以,kmenunum只能等于1,2,3。

flagset=1;//设置标志位,表示在进行各种时间设置。

while(!

kmenu);

di();

switch(kmenunum) //定位光标闪烁点。

{

case1:

writecom(0x80+0x40+7);//秒闪烁。

writecom(0x0f);//开光标闪烁。

break;

case2:

writecom(0x80+0x40+4);//分闪烁。

break;

case3:

writecom(0x80+0x40+1);//时闪烁。

break;

case4:

writecom(0x80+12);  //星期闪烁.

break;

case5:

writecom(0x80+9); //日闪烁.

break;

case6:

writecom(0x80+6);  //月闪烁.

break;

case7:

writecom(0x80+3);  //年闪烁.

break;

case8:

kmenunum=0;

writecom(0x0c);//取消光标闪烁。

flagset=0;    //取消时间调节标志。

dswrite(0x8e,0x00);   /*允许写操作*/

dswrite(0x80,second/10*16+second%10);//退出时间设置功能时,往DS1302

dswrite(0x82,minute/10*16+minute%10);//中保存所有时间变量的值。

dswrite(0x84,hour/10*16+hour%10);

dswrite(0x8a,week/10*16+week%10);

dswrite(0x86,day/10*16+day%10);

dswrite(0x88,month/10*16+month%10);

dswrite(0x8c,year/10*16+year%10);

dswrite(0x8e,0x80);   /*禁止写操作*/

break;

}            

}

}

if(kmenunum!

=0)  //只有当功能键按下时,才检测增大,减小键.

{

if(kup==0)

{

delay

(2);

if(kup==0)

{

while(!

kup);

di();

switch(kmenunum) //根据功能键被按下的次数,调节相应数值。

{

case1:

second++;

if(second==60)

second=0;

writetime(7,second);

writecom(0x80+0x40+7);//因为,上面送液晶显示

break;  //一次,光标后移一位,所以要将光标复位.  

case2:

  minute++;

if(minute==60)

minute=0;

writetime(4,minute);

writecom(0x80+0x40+4);

break;

case3:

  hour++;

if(hour==24)

hour=0;

writetime(1,hour);

writecom(0x80+0x40+1);

break;

case4:

  week++;

if(week==8)

week=1;

writeweek(week);

writecom(0x80+12);

break;

case5:

  day++;

if(day==32)

day=1;

writenyr(9,day);

writecom(0x80+9);

break;

case6:

  month++;

if(month==13)

month=1;

writenyr(6,month);

writecom(0x80+6);

break;

case7:

  year++;

if(year==100)

year=0;

writenyr(3,year);

writecom(0x80+3);

break;

}  

}

}

if(kdown==0)

{

delay

(2);

if(kdown==0)

{

while(!

kdown);

di();

switch(kmenunum) //根据功能键被按次数调节相应数值.

{

case1:

  second--;

if(second==-1)

second=59;

writetime(7,second);

writecom(0x80+0x40+7);

break;

case2:

  minute--;

if(minute==-1)

minute=59;

writetime(4,minute);

writecom(0x80+0x40+4);

break;

case3:

  hour--;

if(hour==-1)

hour=23;

writetime(1,hour);

writecom(0x80+0x40+1);

break;

case4:

  week--;

if(week==0)

week=7;

writeweek(week);

writecom(0x80+12);

break;

case5:

  day--;

if(day==0)

day=31;

writenyr(9,day);

writecom(0x80+9);

break;

case6:

  month--;

if(month==0)

month=12;

writenyr(6,month);

writecom(0x80+6);

break;

case7:

  year--;

if(year==-1)

year=99;

writenyr(3,year);

writecom(0x80+3);

break;

}

}

}    

}

if(kalarm==0)//检测闹钟调节键是否按下,此条if语句与if(kmenunum!

=0)

{       //在同一个层次。

delay

(2);

if(kalarm==0)

{

flagseta=~flagseta;

while(!

kalarm);

di();

if(flagseta==0)  //此时,退出闹钟设置,保存各相关数值。

{

flagset=0;//清除时间设置标志,在if(kalarm==0)这个if语句

writecom(0x80+0x40);//中,不用flagset=1这条语句来设置

//flagset标志位,因为,如果进行了闹钟时间的设置

//,就会执行前面if(kmenunum==0)语句中的flagset=1这条语句。

writedata('');//清除液晶上的“Ri”闹钟调节标志。

//writedata('');

/*for(i=0;i<13;i++)

{

writedata(t3[i]);

}*/

writecom(0x0c);  //取消光标闪烁。

dswrite(0x8e,0x00);   /*允许写操作*/

dswrite(writealarmsecond,second/10*16+second%10);//往DS1302中保存闹钟的时分秒值。

dswrite(writealarmminute,minute/10*16+minute%10);

dswrite(writealarmhour,hour/10*16+hour%10);

dswrite(0x8e,0x80);   /*禁止写操作*/

}

else //进入闹钟设置。

{

s=dsread(readalarmsecond)/16*10+dsread(readalarmsecond)%16;  //读取DS1302中闹钟的原始时间,转化为十进制数存进s,m,h保存,用以后面判断闹钟时间是否到达。

m=dsread(readalarmminute)/16*10+dsread(readalarmminute)%16;

h=dsread(readalarmhour)/16*10+dsread(readalarmhour)%16;

second=s; //把闹钟时间的十进制数据传送给变量second,minute,hour,用以调节其值。

 

minute=m;

hour=h;        

writecom(0x80+0x40);

writedata('C');//液晶显示闹钟调节标志。

//writedata('L');

writecom(0x80+0x40+3);

writetime(1,hour);//送液晶显示闹钟时间。

writetime(4,minute);

writetime(7,second);          

}

}

}       

}

voiddswritebyte(uchard)//往DS1302写入一个字节。

{

uchari;

ACC=d;

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

{

dsdata=ACC0;

dsclk=1;   //为什么这里时钟先为1后为0,因为dsclk初始化为0,而,每次循环最后,都将其置0,这样就形成一个从0开始的上升沿,恰好满足ds1302写数据在上升沿,但是,时钟必须从0开始的要求.

dsclk=0;  

ACC=ACC>>1;

}         

}

uchardsreadbyte()//从DS1302读出一个

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

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2