52单片机 时钟 音乐 秒表 程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define bit(x)(1<<x)
unsigned int a[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x80}; unsigned char c=-1; //调时间用的
unsigned char b[12]={0};
unsigned char d[6]={0,0,5,1,9,1}; //调闹钟用的
unsigned char f=0;
unsigned char e[4]={0};
uchar u=0; //音乐用
uchar Count; //同上
#include<intrins.h>
#define wr_second 0x80
#define wr_minute 0x82
#define wr_hour 0x84
#define rd_second 0x81
#define rd_minute 0x83
#define rd_hour 0x85
//
#define wr_day 0x86
#define rd_day 0x87
#define wr_month 0x88
#define rd_month 0x89
#define wr_year 0x8c
#define rd_year 0x8d
//
#define write_protect 0x8e
sbit CLK=P1^0; //实时时钟时钟线引脚
sbit DIO=P1^1; //实时时钟数据线引脚
sbit RST =P1^2; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
//
sbit return0=P3^3;
sbit left=P3^4 ;
sbit stop=P3^5;
sbit up=P1^6;
sbit yinyue=P1^7;
sbit fiction=P3^2;
sbit Speak =P1^4; // 风频器nb
//
uchar s,m,h,day,mon,year;
uchar q=0; // 中断用
uchar clock=0;
void delay(unsigned ms)
{
unsigned i,j;
for(i=0;i<ms;i++)
for(j=0;j<150;j++);
}
void show(int x,int y)
{
P2=~bit(x);
P0=a[y];
delay(1);
}
//时间
//////////////////////////////////////////////////////////////////////////////////////////////// //////// //写
void DS1302_wr(uchar addr,uchar dat) //addr: DS1302地址, dat 要写的数据{
unsigned char i,temp;
RST = 0;
CLK = 0;
RST = 1;
//ACC=addr;
// 地址,命令
for(i=8;i>0;i--)
{ CLK = 0;
temp=addr;
DIO=(bit)(temp&0x01) ;
addr=addr>>1;
CLK=1;
}
for(i=8;i>0;i--)
{
CLK = 0;
temp=dat;
DIO=(bit)(temp&0x01);
dat >>= 1;
CLK=1;
}
RST=0;
}
// 读
unsigned char DS1302_rd(unsigned char addr)
{
unsigned char i,temp,dat1,dat2;
RST = 0;
CLK = 0;
RST = 1;
// 地址,命令
for(i=8;i>0;i--)
{
CLK = 0;
temp=addr;
DIO=(bit)(temp&0x01);
addr>>=1;
CLK=1;
}
for(i=8;i>0;i--)
{
ACC7=DIO;
CLK=1;
ACC>>=1;
CLK=0;
}
RST=0;
dat1=ACC;
dat2=dat1/16;
dat1=dat1%16;
dat1=dat1+dat2*10;
return(dat1);
}
void intial(void) // ds1302初始化{
DS1302_wr(write_protect,0x00);
//DS1302_wr(wr_second,0x56);
//DS1302_wr(wr_minute,0x34);
//DS1302_wr(wr_hour,0x12);
//DS1302_wr(wr_day, 0x07);
// DS1302_wr(wr_month,0x12);
//DS1302_wr(wr_year,0x11);
// DS1302_wr(write_protect,0x80);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void show_b() //时间日期数码管显示数
{
//uchar i;
b[0]=s%10;
b[1]=s/10;
b[2]=m%10;
b[3]=m/10;
b[4]=h%10;
b[5]=h/10;
//
b[6]=day%10;
b[7]=day/10;
b[8]=mon%10;
b[9]=mon/10;
b[10]=year%10;
b[11]=year/10;
}
void show_time() //显示时间函数
{
show_b();
show(0,b[0]);
show(1,b[1]);
show(2,10);
show(3,b[2]);
show(4,b[3]);
show(5,10);
show(6,b[4]);
show(7,b[5]);
}
void show_day() //显示日期函数
{
show_b();
show(0,b[6]);
show(1,b[7]);
show(2,b[8]);
show(3,b[9]);
show(4,b[10]);
show(5,b[11]);
show(6,0);
show(7,2);
}
/////////////////////////////////////////////////////////////////////////////////////
void ddd(void) //从ds1302读出时、分、秒及日期{
s=DS1302_rd(rd_second);
m=DS1302_rd(rd_minute);
h=DS1302_rd(rd_hour);
day=DS1302_rd(rd_day);
mon=DS1302_rd(rd_month);
year=DS1302_rd(rd_year);
}
//////////////////////////////////////////////////////////////////////////////////////
void int_init(void) //开中断
{
EA=1; //全局中断开
EX0=1; //外部中断0开
EX1=1; //外部中断1开
IT0=1; //边沿触发,为0则为低电平触发
IT1=1; //边沿触发,为0则为低电平触发
ET1=1; // 计数器1开
}
void init_time() //中断初始化
{
TMOD=0x10;
TR1=1; // TCON
}
/////////
/*void int0_Key() interrupt 0 using 1
{
u++; //q功能键转化
}*/
void fictions()
{
if(fiction==0)
{
while(fiction==0);
q++;
}
}
void int1_Key() interrupt 2 using 2
{
clock=0; //关闹钟
}
/////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// void clock_out() //闹钟程序
{
while(clock)
{
Speak=1;
delay(1);
Speak=0;
delay(1);
}
}
void move() // 调小数点
{
if(left==0)
{
while(left==0);
c++;
if(c==7) c=-1;
}
}
void move_time() //调时间
{
move();
if(up==0)
{
uchar a;
while(up==0);
switch(c)
{
//case -1: break;
case 0: a=s%10+s/10*16;
a=a+0x01;
if(a>=96)
a=a-0x60;
DS1302_wr(wr_second,a);break;
case 1: a=s%10+s/10*16;
a=a+0x10;
if(a>=96)
a=a-0x60;
DS1302_wr(wr_second,a);break;
//case 2: break;
case 3: a=m%10+m/10*16;
a=a+0x01;
if(a>=96)
a=a-0x60;
DS1302_wr(wr_minute,a);break;
case 4: a=m%10+m/10*16;
a=a+0x10;
if(a>=96)
a=a-0x60;
DS1302_wr(wr_minute,a);break;
//case 5: break;
case 6: a=h%10+h/10*16;
a=a+0x01;
if(a>=36)
a=0x00;
DS1302_wr(wr_hour,a);break;
/*case 7: a=h%10+h/10*16;
a=a+0x10;
if((a&0xf0)>=32)
a=0x00+b[4];
DS1302_wr(wr_hour,a);break; */ default : break;
}
}
show_time();
}
void move_day() //调日期{
move();
if(up==0)
{
uchar a;
while(up==0);
switch(c)
{
//case -1: break;
case 0: a=day%10+day/10*16;
a=a+0x01;
if(a>49)
a=0x01;
DS1302_wr(wr_day,a);break;
case 1: /* a=day%10+day/10*16;
a=a+0x10;
if(a>=65)
a=a-0x30;
DS1302_wr(wr_day,a);break;*/
c=c+1;
case 2: a=mon%10+mon/10*16;
a=a+0x01;
if(a>18)
a=0x01;
DS1302_wr(wr_month,a);break;
case 3: /* a=mon%10+mon/10*16;
a=a+0x10;
if(a>=34)
a=a-0x10;
DS1302_wr(wr_month,a);break;*/
c=c+1;
case 4: a=year%10+year/10*16;
a=a+0x01;
if(a>153)
a=0x00;
DS1302_wr(wr_year,a);break;
case 5: a=year%10+year/10*16;
a=a+0x10;
if(a>153)
a=a-0x90;
DS1302_wr(wr_year,a);break;
/*case 7: a=h%10+h/10*16;
a=a+0x10;
if((a&0xf0)>=32)
a=0x00+b[4];
DS1302_wr(wr_hour,a);break;*/ default : break;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void show_naozhong()
{
show(0,d[0]);
show(1,d[1]);
show(2,10);
show(3,d[2]);
show(4,d[3]);
show(5,10);
show(6,d[4]);
show(7,d[5]);
}
void move_naozhong()
{
move();
if(up==0)
{
while(up==0);
switch(c)
{
//case -1: break;
case 0: d[0]++;
if(d[0]==10) d[0]=0;break;
case 1: d[1]++;
if(d[1]>=6) d[1]=0;break;
//case 2: break;
case 3: d[2]++;
if(d[2]==10) d[2]=0;break;
case 4: d[3]++;
if(d[3]>=6) d[3]=0;break;
//case 5: break;
case 6: d[4]++;
if(d[4]==10)
{
d[4]=0;
d[5]++;
}
break;
default : break;
}
}
}
uchar counter=0;
void init_inttime() interrupt 3
{
TH1=0xfc;
TL1=0x0B;
counter++;
if (counter==10)
{
counter=0;
e[0]++;
if(e[0]==10)
{
e[0]=0;
e[1]++;
if(e[1]==10)
{
e[1]=0;
e[2]++;
if(e[2]==10)
{
e[2]=0;
e[3]++;
if(e[3]==6)
e[3]=0;
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char code SONG[] ={ //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20, 0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20, 0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20, 0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20, 0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10, 0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20, 0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20, 0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20, 0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80, 0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20, 0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20, 0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10, 0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
};
void Time0_Init()
{
TMOD = 0x01;
IE = 0x82;
TH0 = 0xDC;
TL0 = 0x00;
}
void Time0_Int() interrupt 1
{
TH0 = 0xDC;
TL0 = 0x00;
Count++; //长度加1
}
void Delay_xMs(uint x)
{
uint i,j;
for(i=0; i<x; i++)
{
for(j=0; j<3; j++);
}
}
void Play_Song(uchar i)
{
uchar Temp1,Temp2;
uint Addr;
Count = 0; //中断计数器清0
Addr = i ;
while(u)
{
Temp1 = SONG[Addr++];
if (Temp1 == 0xFF) //休止符
{
TR0 = 0; // 停止计数
Delay_xMs(100);
}
else if (Temp1 == 0x00) //歌曲结束符
{
u=0;
}
else
{
Temp2 = SONG[Addr++];
TR0 = 1;
while(1)
{
Speak = ~Speak;
Delay_xMs(Temp1);
if(Temp2 == Count)
{
Count = 0;
break;
}
}
}
}
}
void change()
{
if(yinyue==0)
{
while(yinyue==0);
u++;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////// void main()
{
intial();
int_init();
while(1)
{
ddd(); //显示时间
if(q%3==0)
{
show_time();
move_time();
}
if(q%3==1) //显示日期
{
show_day();
move_day();
}
if(q%3==2) //闹钟调试
{
show_naozhong();
move_naozhong();
}
if(u%2==1) //音乐功能
{
Time0_Init(); //定时器0中断初始化
Play_Song(0); //为祝你平安
}
show(c,11); //小数点显示
fictions(); //功能键扫描
change();
if(h==(d[5]*10+d[4])&&m==(d[3]*10+d[2])&&s==(d[1]*10+d[0])) clock=1;
clock_out();
}
}。