DS1302时钟 本帖最后由 邹建兴 于 2016-1-1 22:14 编辑
#include <STC12C5A60S2.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include "1302.h"
sbit DS=P1^2 ; //串行数据输入 8
sbit SH_CP =P1^0 ; //移位时钟脉冲输入4
sbit ST_CP =P1^1 ; //输出锁存器控制脉冲 12
sbit led1=P1^7;
sbit led2=P1^6;
sbit led3=P1^5;
sbit led4=P1^4;
sbit led5=P1^3;
sbit led=P3^6;
sbit key1=P3^0;
sbit key2=P3^4;
sbit key3=P3^5;
char shi,fen,xing,num=0,flag=1;
uint aa;
uchar code Tab[]={0x20,0x79,0x44,0x50,0x19,0x12,0x02,0x78,
0x00,0x10,0x08,0x03,0x26,0x41,0x06,0x0E};
uchar code Tab1[]={0x5F,0x06,0x3B,0x2F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x59,0x3E,0x79,0x71};
void Delay1ms(uint a) //@24.576MHz
{
unsigned char i, j;
while(--a)
{
_nop_();
_nop_();
i = 12;
j = 168;
do
{
while (--j);
} while (--i);
}
}
void yiwei(uchar a) //595移位
{
uchar j,temp ;
temp=a; //把数据赋给temp
SH_CP=0 ; //时钟线置低随时可以给ds赋值
ST_CP=0; //把8位数据寄存器打开
for(j=0;j<8;j++)
{
temp<<=1; //数据左移1位,每次数据的高位移出
DS=CY ; //移出的数据在PSW中的CY中
_nop_();
SH_CP=1 ; //时钟上升沿把数据存到8位数据寄存器中
_nop_();
SH_CP=0 ;//时钟线置低随时可以给ds赋值
}
ST_CP=1;//把8位数据寄存器关闭并输出数据到d0-d7
ST_CP=0;
}
void xianshi(uchar shii,uchar fenn,xingg)
{
uchar a,b,c,d,e,f,g,h;
a=shii;
b=a/16;
c=a&0x0f;
d=fenn;
e=d/16;
f=d&0x0f;
g=xingg;
h=(g&0x0f)%16;
yiwei(Tab);
led1=0;
Delay1ms(2);
led1=1;
yiwei(Tab[c]);
led2=0;
Delay1ms(2);
led2=1;
yiwei(Tab[e]);
led3=0;
Delay1ms(2);
led3=1;
yiwei(Tab[f]);
led4=0;
Delay1ms(2);
led4=1;
yiwei(Tab1[h]);
led5=0;
Delay1ms(2);
led5=1;
}
void jianpan()//键盘扫描
{
uchar a=20;
if(key1==0)//功能键
{
TR0=0;
flag=0;
while(a--);
while(!key1)
{
switch(num)
{
case 0:
xianshi(shi,fen,xing);
break;
case 1:
xianshi(0,0,xing);
break;
case 2:
xianshi(0,fen,0);
break;
case 3:
xianshi(shi,0,0);
break;
default:
break;
}
}
num++;
}
switch(num)
{
case 1:
xianshi(0,0,xing);
break;
case 2:
xianshi(0,fen,0);
break;
case 3:
xianshi(shi,0,0);
break;
case 4:
TR0=1;
num=0;
flag=1;
default:
break;
}
if(flag==0)
{
if(key2==0)//数据加键
{
while(a--);
while(!key2)
{
switch(num)
{
case 0:
xianshi(shi,fen,xing);
break;
case 1:
xianshi(0,0,xing);
break;
case 2:
xianshi(0,fen,0);
break;
case 3:
xianshi(shi,0,0);
break;
default:
break;
}
}
switch(num)
{
case 1:
xianshi(0,0,xing);
xing++;
if(xing>=8)
xing=1;
break;
case 2:
xianshi(0,fen,0);
fen++;
if(fen%16>=10)
{
fen=fen+6;
if(fen/16>=6)
fen=0;
}
break;
case 3:
xianshi(shi,0,0);
shi++;
if(shi%16>=10)
shi=shi+6;
if((shi/16>=2)&(shi%16>=4))
shi=0;
break;
default:
break;
}
DS1302_W1302(0x82,fen);
DS1302_W1302(0x84,shi);
DS1302_W1302(0x8a,xing);
}
if(key3==0)//数据减键
{
while(a--);
while(!key3)
{
switch(num)
{
case 0:
xianshi(shi,fen,xing);
break;
case 1:
xianshi(0,0,xing);
break;
case 2:
xianshi(0,fen,0);
break;
case 3:
xianshi(shi,0,0);
break;
default:
break;
}
}
switch(num)
{
case 1:
xianshi(0,0,xing);
xing--;
if(xing==0)
xing=7;
break;
case 2:
xianshi(0,fen,0);
fen--;
if(fen%16==15)
fen=fen-6;
if(fen<=-1)
fen=0x59;
break;
case 3:
xianshi(shi,0,0);
shi--;
if(shi%16==15)
shi=shi-6;
if(shi<=-1)
shi=0x23;
break;
default:
break;
}
DS1302_W1302(0x82,fen);
DS1302_W1302(0x84,shi);
DS1302_W1302(0x8a,xing);
}
}
}
void Timer0Init(void) //20??@12.000MHz
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0xE0;
TH0 = 0xB1;
TF0 = 0;
TR0 = 1;
ET0=1;
EA=1;
}
void main() //主程序
{
uchar a,b,c;
led1=1;
led2=1;
led3=1;
led4=1;
led5=1;
key1=1;
key2=1;
key3=1;
a=DS1302_R1302(0x81);
b=a/16;
c=a&0x0f;
if(b>=6|c>=10)
{
DS1302_W1302(0x80,0x01);
DS1302_W1302(0x82,0x20);
DS1302_W1302(0x84,0x12);
DS1302_W1302(0x8a,0x04);
}
Timer0Init();
while(1)
{
jianpan();
if(flag==1)
xianshi(shi,fen,xing);
}
}
void t0_() interrupt 1
{
TL0 = 0xE0;
TH0 = 0xB1;
aa++;
if(aa==5|aa==10|aa==20)
{
shi=DS1302_R1302(0x85);
fen=DS1302_R1302(0x83);
xing=DS1302_R1302(0x8b);
}
if(aa==25)
{
aa=0;
led=~led;
}
}//注意与原理图管脚有区别改一下就可以了。