标题:
基于时钟芯片1302的c语言程序
[打印本页]
作者:
hutians
时间:
2015-2-10 17:52
标题:
基于时钟芯片1302的c语言程序
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//**************寄存器宏定义*******************************
#define write_miao 0x80
#define write_fen 0x82
#define write_shi 0x84
#define read_miao 0x81
#define read_fen 0x83
#define read_shi 0x85
#define write_protect 0x8e
//*********************************************************
sbit ACC_7=ACC^7; //管脚定义
sbit sclk=P3^5; //ds1302时钟信号
sbit dio=P3^6; //ds1302数据信号
sbit ce=P3^7; //ds1302片选
//*********************************************************
sbit wei=P2^0;
sbit duan=P2^1;
sbit k1=P1^0;
sbit k2=P1^1;
uchar table[]={0x3f,0x06,0x5b,0x4f, //0,1,2,3
0x66,0x6d,0x7d,0x07, //4,5,6,7
0x7f,0x6f,0x40,0x00}; //8,9,-,空格
uchar wela[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar num,num1,num2,shi,fen,miao,m,s;
char guo0,guo1,guo2;
/********************地址、数据发送子程序*******************/
void write1302(uchar addr,dat)
{
uchar i,temp;
ce=0; //ce引脚为低,数据传送中止
sclk=0; //清零时钟总线
ce=1; //ce引脚为高,逻辑控制有效
//发送地址
for(i=8;i>0;i--) //循环8次移位
{
sclk=0;
temp=addr;
dio=(bit)(temp&0x01);//每次传输低字节
addr>>=1; //右移一位
sclk=1;
}
//发送数据
for(i=8;i>0;i++)
{
sclk=0;
temp=dat;
dio=(bit)(temp&0x01);
dat>>=1;
sclk=1;
}
ce=0;
}
/******************数据读取子程序*******************/
uchar read1302(uchar addr)
{
uchar i,temp,dat1; // dat2,
ce=0;
sclk=0;
ce=1;
//发送地址
for(i=8;i>0;i--)
{
sclk=0;
temp=addr;
dio=(bit)(temp&0x01);//每次传输低字节
addr>>=1;
sclk=1;
}
//读取数据
for(i=8;i>0;i--)
{
ACC_7=dio;
sclk=1;
ACC>>=1;
sclk=0;
}
ce=0;
dat1=ACC;
return(dat1);
}
/*****************初始化ds1302**********************/
void initial()
{
TMOD=0x01;
TH1=(65536-56074)/256; // 11.05768M.
TL1=(65536-56074)%256;
EA=1; // 打开中断允许
ET1=1; // 开起计数器0
EX0=1;
}
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void display(uchar duan_i,uchar wela_i)
{
duan=1;
P0=table[duan_i];
duan=0;
wei=1;
P0=wela[wela_i];
wei=0;
delay(1);
P0=0;
}
void display_1()
{
display(shi/16,0);
display(shi%16,1);
display(10,2);
display(fen/16,3);
display(fen%16,4);
display(10,5);
display(miao/16,6);
display(miao%16,7);
}
void display_2()
{
while(m==3&&num2%2!=0)
{
display(11,0);
display(11,1);
display(10,2);
display(fen/16,3);
display(fen%16,4);
display(10,5);
display(miao/16,6);
display(miao%16,7);
}
while(m==1&&num2%2!=0)
{
display(shi/16,0);
display(shi%16,1);
display(10,2);
display(fen/16,3);
display(fen%16,4);
display(10,5);
display(11,6);
display(11,7);
}
while(m==2&&num2%2!=0)
{
display(shi/16,0);
display(shi%16,1);
display(10,2);
display(11,3);
display(11,4);
display(10,5);
display(miao/16,6);
display(miao%16,7);
}
while(num2%2==0)display_1();
}
char fun_1(uchar u)
{
u=u/16*10+u%16; //将十六进制转化为十进制
u++;
s=0;
u>=60?u=0:u;
u=u/10*16+u%10; //将十进制转化为十六进制BCD
return u;
}
void keyboard()
{
if(k1==0)
delay(5);
if(k1==0)
{
if(TR1=1,m++,m==4)
{
m=0;
TR1=0;
}
while(!k1)display_1();
}
if(m!=0)
{
if(k2==0)
{
if(delay(5),s=1,m==1&&s!=0)
{
miao=fun_1(miao);
write1302(write_protect,0x00);
write1302(write_miao,miao);
write1302(write_protect,0x80);
}
if(m==2&&s!=0)
{ fen=fun_1(fen);
write1302(write_protect,0x00);
write1302(write_fen,fen);
write1302(write_protect,0x80);
}
if(m==3&&s!=0)
{
shi=shi/16*10+shi%16;
shi++;
shi>=24?shi=0:shi;
shi=shi/10*16+shi%10;
write1302(write_protect,0x00);
write1302(write_shi,shi);
write1302(write_protect,0x80);
}
while(!k2)display_1();
}
}
}
void main()
{
initial();
while(1)
{
shi=read1302(read_shi);
fen=read1302(read_fen);
miao=read1302(read_miao);
keyboard();
/* if(m!=0)
{
write1302(write_protect,0x00); //禁止写保护
write1302(write_shi,shi);
write1302(write_fen,fen);
write1302(write_miao,miao);
write1302(write_protect,0x80); //允许写保护
} */
m!=0?display_2():display_1();
}
}
void time_1() interrupt 3
{
if(TH1=(65536-56074)/256,TL1=(65536-56074)%256,num1++,num1==20)
{
num1=0;
num2++;
}
}
说实话,我对这个程序不是很满意,因为这个程序在设置部分还有不足,比如说在设置的时候秒还在走;如果说要在设置的时候让时候不走,那么就得每时每刻都往1302中写入秒,但是写的时间又太长,从而导致了常亮部分也出现了闪烁的现象:
/* if(m!=0)
{
write1302(write_protect,0x00); //禁止写保护
write1302(write_shi,shi);
write1302(write_fen,fen);
write1302(write_miao,miao);
write1302(write_protect,0x80); //允许写保护
} */
我不知道为什么写的时间会有那么长,以致于出现了闪烁现象,之后我为了消除这个现象,就用了这个结构:
if(k2==0)
{
if(delay(5),s=1,m==1&&s!=0)
{
miao=fun_1(miao);
write1302(write_protect,0x00);
write1302(write_miao,miao);
write1302(write_protect,0x80);
}
但这个结构有不足之处,简单的说就是只有在做加法时才能读写入,其他时间都不会读写入。正因为这样才消除了闪烁,但是这个方法却带来了新的问题,由于这个程序只有在做加法时才能读写入所以在不读写入的时间里时间一直在走。
用1302做的时钟最吸引人眼球的就是在断电的时候不影响时间的进行,不过这需要备用电源的支持!
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1