//一通过实验板测试通过
//朱世民
#include<reg51.h>
unsigned char time[3]={0x57,0x36,0x12}; //秒,分,时寄存器初始值
unsigned char code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
//0~~9段码 abcdefgh,共阳
/*************************ds1302与at89s52引脚连接********************/
unsigned char i,k,n,addr,kk,s;
sbit T_RST=P3^7;
sbit T_CLK=P3^5;
sbit T_IO=P3^6;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit k1=P3^2;
sbit k2=P3^4;
/***********************延时程序=a*2us**************************************/
void delay(unsigned int a)
{
while(a--);
}
/****************************************************
// DS1302?
/******************DS1302:写入操作(上升沿)*********************/
void write_byte(unsigned char ucode)
{
unsigned char i;
ACC=ucode;
T_RST=1;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=0;
T_CLK=1;
ACC=ACC>>1;
}
}
/******************DS1302:读取操作(下降沿)*****************/
unsigned char read_byte(void)
{
unsigned char i;
T_RST=1;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
T_IO=1;
T_CLK = 1;
T_CLK = 0;
ACC7 = T_IO;
}
return(ACC);
}
/******************DS1302:写入数据(先送地址,再写数据)***************************/
void write_1302(unsigned char addr,unsigned char ucode)
{
T_RST=0; //停止工作
T_CLK=0;
T_RST=1; //重新工作
write_byte(addr); //写入地址
delay(3);
write_byte(ucode);
T_RST=0;
T_CLK=1;
}
/******************DS1302:读取数据(先送地址,再读数据)**************************/
unsigned char read_1302(unsigned char addr)
{
unsigned char ucode;
T_RST=0; //停止工作
T_CLK=0;
T_RST=1; //重新工作
write_byte(addr); //写入地址
delay(1);
ucode=read_byte();
T_RST=0;
T_CLK=1; //停止工作
return(ucode);
}
/***********************显示程序**********************************************/
/* 动态扫描条件(单个LED在1秒内): count >=50次 //点亮次数 */
/* time >=2ms //持续时间 */
/* DS1302秒,分,时寄存器是BCD码形式: 用16求商和余进行"高4位"和"低4位"分离 */
/* 0x00,0x10,0x30,0x40,0x60,0x70 : 位选 */
/****************************************************************************/
void disp()
{ unsigned char m;
/* m=time[0];
P0=tab[m%16]; //取低4位BCD码
P2=0x7f; //显示秒(个位);
delay(500); //持续2ms
P2=0xff; //消影
P0=tab[m/16]; //取高4位BCD码:显示秒(十位);
P2=0xbf;
delay(500);
P2=0xff;*/
m=time[1];
P0=tab[m%16]; //第4个数码管:显示分(个位)
P2=0xf7;
delay(500);
P2=0xff;
P0=tab[m/16]; //第5个数码管:显示分(十位)
P2=0xfb;
delay(500);
P2=0xff;
m=time[2];
P0=tab[m%16]; //第7个数码管:显示时(个位)
P2=0xfd;
delay(500);
P2=0xff;
P0=tab[m/16]; //第8个数码管:显示时(十位)
P2=0xfe;
delay(500);
P2=0xff;
}
//========初始化
void init()
{
addr=0x80;
write_1302(0x8e,0x00); //WP=0 写操作
write_1302(0x90,0xaa); //开启涓流充电 10101010
for(i=0;i<3;i++) // 写操作,8位初值
{
write_1302(addr,time[i]);
addr+=2;
}
write_1302(0x8e,0x80); //WP=1 写保护
}
//====移位选择按钮===========
void testk1()
{k1=1;
if(!k1)
{disp();
if(!k1)
{while(!k1)disp();
if(++k>4)k=0;//移位标志
}
}
}
//=======加一键=================
void testk2()
{k2=1;
if(!k2)
{disp();disp();disp();
if(!k2)
{
switch(k)
{case 1:n=time[1];//
n&=0xf0;//保留高四位;
if(++kk>9)kk=0; //
time[1]=n|kk;break;//分的个加一
case 2:n=time[1];n&=0x0f; if(++kk>5)kk=0; time[1]=n+kk*16;break;//分的十位加1
case 3:n=time[2];n&=0xf0; if(++kk>9)kk=0; time[2]=n|kk;break;//时的个位加一
case 4:n=time[2];n&=0x0f; if(++kk>2)kk=0; time[2]=n+kk*16; break;//时十位加1
default:break;
}
init(); //写进1302去
}
}
}
/************************主程序**********************************************/
void main(void)
{ k=0;
init();
while(1)
{
disp();
testk1();
if(k!=0)
{testk2();}
else
{addr=0x81;
for(i=0;i<3;i++)
{
time[i]=read_1302(addr);
addr+=2;
}
}
}
}