52單片機是STC公司生產(chǎn)的一種低功耗、高性能CMOS8位微控制器,具有8K字節(jié)系統(tǒng)可編程Flash存儲器。STC89C52使用經(jīng)典的MCS-51內(nèi)核,但是做了很多的改進使得芯片具有傳統(tǒng)51單片機不具備的功能。在單芯片上,擁有靈巧的8 位CPU 和在系統(tǒng)可編程Flash,使得STC89C52為眾多嵌入式控制應(yīng)用系統(tǒng)提供高靈活、超有效的解決方案。
52單片機結(jié)合可以對年、月、日、周、時、分、秒進行計時,且具有閏年補償?shù)裙δ艿膁DS1302時鐘芯片做出的電子鬧鐘會有什么火花呢?奉上基于52單片機與ds1302時鐘芯片的電子鬧鐘C程序,讓大家親身體驗。
52單片機與ds1302時鐘芯片的電子鬧鐘C程序
#include《reg52.h》
#define w_second 0x80 //秒寫入地址
#define w_minute 0x82 //分寫入地址
#define w_hour 0x84 //時寫入地址
#define w_day 0x86 //日寫入地址
#define w_month 0x88 //月寫入地址
#define w_week 0x8a //星期寫入地址
#define w_year 0x8c //年寫入地址
#define r_second 0x81 //秒讀出地址
#define r_minute 0x83 //分讀出地址
#define r_hour 0x85 //時讀出地址
#define r_day 0x87 //日讀出地址
#define r_month 0x89 //月讀出地址
#define r_week 0x8b //星期讀出地址
#define r_year 0x8d //年讀出地址
#define w_wp 0x8e //指令寫允許端地址
#define uchar unsigned char
uchar table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//7段數(shù)碼管編碼
uchar second; // 秒指針
uchar minute; // 分指針
uchar hour; // 時指針
uchar day; // 日指針
uchar month; // 月指針
uchar week; // 星期指針
uchar year; // 年指針
uchar cc;
uchar h_clock,m_clock,h,m;
sbit change=P1^0; // 選擇按鈕
sbit ok=P1^2; // 確定更改按鈕
sbit crrect=P1^1; // 更改按鈕
sbit look=P1^3; // 時間和年月日查看切換按鈕
sbit clock=P1^4; //鬧鐘設(shè)定
sbit ce=P3^2; // ds1302 片選端
sbit sclk=P3^0; // ds1302 時控端
sbit io=P3^1; // ds1302 串口端
sbit clock_beef=P3^7; //蜂鳴器控制端
sbit clock_button=P1^5; //鬧鐘啟停按鈕
void write_ds1302(uchar addr,uchar dat) //寫程序
{ uchar i,temp;
ce=0;sclk=0;ce=1;
for(i=0;i《8;i++)
{ sclk=0;
temp=addr;
io=(bit)(temp&0x01); //每一次只傳送一位數(shù)據(jù)
addr》》=1;
sclk=1;
}
for(i=0;i《8;i++)
{ sclk=0;
temp=dat;
io=(bit)(temp&0x01);
dat》》=1;
sclk=1;
}
ce=0;
}
uchar read_ds1302(uchar addr) //讀程序
{ uchar i,temp;
ce=0;sclk=0;ce=1;
for(i=0;i《8;i++)
{ sclk=0;
temp=addr;
io=(bit)(temp&0x01);
addr》》=1;
sclk=1;
}
for(i=0;i《8;i++)
{ temp》》=1;
sclk=0;
if(io) temp=temp|0x80;
else temp=temp&0x7f;
sclk=1;
}
return temp;
}
void set_ds1302() //初始化ds1302
{ write_ds1302(w_wp,0x00);
write_ds1302(w_second,second);
write_ds1302(w_minute,minute);
write_ds1302(w_hour,hour);
write_ds1302(w_day,day);
write_ds1302(w_month,month);
write_ds1302(w_week,week);
write_ds1302(w_year,year);
write_ds1302(w_wp,0x80);
}
void view1() //時間顯示
{ uchar i;
P0=table[second]; //秒顯示
P2=0x01;
for(i=0;i《=123;i++);
P2=0;
P0=table[second/16];
P2=0x02;
for(i=0;i《=123;i++);
P2=0;
P0=table[minute]-0x80; //分顯示,(-0x80表示dp點亮)
P2=0x04;
for(i=0;i《=123;i++);
P2=0;
P0=table[minute/16];
P2=0x08;
for(i=0;i《=123;i++);
P2=0;
P0=table[hour]-0x80;//時顯示
P2=0x10;
for(i=0;i《=123;i++);
P2=0;
P0=table[hour/16];
P2=0x20;
for(i=0;i《=123;i++);
P2=0;
}
void view2() //日期顯示
{ uchar i;
P2=0;
P0=table[week]; //星期顯示
P2=0x01;
for(i=0;i《=123;i++);
P2=0;
P0=table[week/16];
P2=0x02;
for(i=0;i《=123;i++);
P2=0;
P0=table[day]-0x80; //日顯示
P2=0x04;
for(i=0;i《=123;i++);
P2=0;
P0=table[day/16];
P2=0x08;
for(i=0;i《=123;i++);
P2=0;
P0=table[month]-0x80;//月顯示
P2=0x10;
for(i=0;i《=123;i++);
P2=0;
P0=table[month/16];
P2=0x20;
for(i=0;i《=123;i++);
P2=0;
P0=table[year]-0x80; //年顯示
P2=0x40;
for(i=0;i《=123;i++);
P2=0;
P0=table[year/16];
P2=0x80;
for(i=0;i《=123;i++);
P2=0;
}
void view3() //鬧鐘設(shè)定程序
{ uchar i;
P0=table[m];
P2=0x01;
for(i=0;i《=123;i++);
P2=0;
P0=table[m/16];
P2=0x02;
for(i=0;i《=123;i++);
P2=0;
P0=table[h]-0x80;
P2=0x04;
for(i=0;i《=123;i++);
P2=0;
P0=table[h/16];
P2=0x08;
for(i=0;i《=123;i++);
P2=0;
}
void beep() //蜂鳴器啟動程序
{ int i;
clock_beef=~clock_beef;
for(i=1;i《=50;i++)
{ second=read_ds1302(r_second);
minute=read_ds1302(r_minute);
hour=read_ds1302(r_hour);
view1();
}
}
void display1() //讀秒,分,時程序
{ second=read_ds1302(r_second);
minute=read_ds1302(r_minute);
hour=read_ds1302(r_hour);
view1();
if((h_clock==read_ds1302(r_hour)) &&
?。╩_clock==read_ds1302(r_minute)) && (~clock_button)) //判斷時分,且鬧鐘是否開啟
{ while(~clock_button)
{ beep();
}
clock_beef=0;
}
}
void display2() //讀星期,日,月,年程序
{ week=read_ds1302(r_week);
day=read_ds1302(r_day);
month=read_ds1302(r_month);
year=read_ds1302(r_year);
view2();
if((h_clock==read_ds1302(r_hour)) &&
?。╩_clock==read_ds1302(r_minute)) && (~clock_button))
{ while(~clock_button)
{ beep();
}
clock_beef=0;
}
}
void crrect_ds1302(uchar cc) //更改程序
{
while(~crrect);
switch(cc)
{
case 1: if(read_ds1302(r_minute)==0x59)
minute=0x00;
else { if(read_ds1302
(r_minute)==9) { minute=read_ds1302
?。╮_minute)/16;minute=(minute+1)*16;}
else
minute=read_ds1302(r_minute)+1;
}
set_ds1302();
break;
case 2: if(read_ds1302(r_hour)==0x23)
hour=0x00;
else { if(read_ds1302(r_hour)
《0x20)
{ if
?。╮ead_ds1302(r_hour)==9) {hour=read_ds1302
?。╮_hour)/16;hour=(hour+1)*16;}
else hour=read_ds1302(r_hour)+1;
}
else
hour=read_ds1302(r_hour)+1;
}
set_ds1302();
break;
case 3: if(read_ds1302(r_week)==0x07)
week=0x01;
else week=read_ds1302(r_week)+1;
set_ds1302();
break;
case 4: if(read_ds1302(r_day)==0x31)
day=0x01;
else { if(read_ds1302
(r_day)==9) { day=read_ds1302(r_day)/16;day=(day+1)
*16;}
else
day=read_ds1302(r_day)+1;
}
set_ds1302();
break;
case 5: if(read_ds1302(r_month)==0x12)
month=0x01;
else { if(read_ds1302
?。╮_month)==9) { month=read_ds1302
?。╮_month)/16;month=(month+1)*16;}
else
month=read_ds1302(r_month)+1;
}
set_ds1302();
break;
case 6: if(read_ds1302(r_year)==0x99)
year=0x00;
else { if(read_ds1302
?。╮_year)==9) { year=read_ds1302(r_year)/16;year=(year
+1)*16;}
else
year=read_ds1302(r_year)+1;
}
set_ds1302();
break;
default:{;}
}
}
void change_ds1302() //更改設(shè)定選擇
{ uchar i;
cc=0;
while(ok)
{ if(cc==6) cc=0;
cc++;
while(change&&ok)
{ if(i==320) i=0;
else i++;
switch(cc)
{
case 1: if(i《160) minute=read_ds1302
(r_minute);
else {minute=0xaa; year=read_ds1302
?。╮_year);}
view1();
break;
case 2: if(i《160) hour=read_ds1302(r_hour);
else {hour=0xaa; minute=read_ds1302
?。╮_minute);}
view1();
break;
case 3: if(i《160)
week=read_ds1302(r_week);
else {week=0xaa;hour=read_ds1302
(r_hour);}
view2();
break;
case 4: if(i《160) day=read_ds1302
?。╮_day);
else {day=0xaa; week=read_ds1302
(r_week);}
view2();
break;
case 5: if(i《160)
month=read_ds1302(r_month);
else {month=0xaa; day=read_ds1302
?。╮_day);}
view2();
break;
case 6: if(i《160)
year=read_ds1302(r_year);
else {year=0xaa; month=read_ds1302
?。╮_month);}
view2();
break;
default: {;}
}
if(~crrect) crrect_ds1302(cc);
}
while( ~change );
}
}
void crrect_clock(uchar i) //設(shè)定定時程序
{ switch(i)
{ case 0: if(m_clock==0x59) m_clock=0x00;
else { if(m_clock==9) {
m_clock=m_clock/16;m_clock=(m_clock+1)*16;}
else
m_clock=m_clock+1;
}
break;
case 1: if(h_clock==0x23)
h_clock=0x00;
else { if(h_clock《0x20)
{ if
?。╤_clock==9) {h_clock=h_clock/16;h_clock=(h_clock+1)
*16;}
else h_clock=h_clock+1;
}
else
h_clock=h_clock+1;
}
break;
default:{;}
}
}
void set_clock() //分、時設(shè)定選擇程序
{ uchar i,j;
while(ok)
{ while(clock && ok)
{ if(j==320) j=0;
else j++;
switch(i)
{
case 0: if(j《160) m=m_clock;
else {m=0xaa; h=h_clock;}
view3();
break;
case 1: if(j《160) h=h_clock;
else {h=0xaa; m=m_clock;}
view3();
break;
default:{;}
}
if(~crrect) {while
(~crrect);crrect_clock(i);}
}
while(~clock);
if(i==0) i++;
else i=0;
}
}
void main()
{ uchar i;
cc=0;m_clock=0x00;h_clock=0x00;clock_beef=0;
second=0x15;
minute=0x58;
hour=0x18;
day=0x18;
month=0x07;
week=0x01;
year=0x11;
set_ds1302(); //初始化ds1302
while(1)
{ if(~look) { i=~i;while(~look);}
if(i==0) display1();
if(i) display2();
if(~change) { while(~change);change_ds1302();}
if(~clock) { while(~clock);set_clock();}
}
}
評論
查看更多