|
#include<reg51.h>
#define uint8 unsigned char
#define uint16 unsigned int
sbit RST=P1^7;
sbit SDA=P3^5;
sbit SCK=P1^6;
uint8 LedBitCnt; //LedBitCnt控制数码管的位选
uint8 ms2_flag; //2ms数码管动态扫描时标消息
uint8 ms10_flag,ms500_flag;
uint8 ms2_cnt,ms10_cnt,count,s1num;
uint8 dis_buff[8]={0};
uint8 shi=12,fen=23,miao=56;
uint8 code SegTab[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40,0x00};
sbit ADDR0 = P2^0;//74hc138的输入控制端A
sbit ADDR1 = P2^1;//74hc138的输入控制端B
sbit ADDR2 = P2^2;//74hc138的输入控制端C
sbit adjust=P3^2;
sbit add=P3^3;
sbit sub=P3^4;
//常数宏
#define DS1302_SECOND_WRITE 0x80//写时钟芯片的寄存器位置
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_SECOND_READ 0x81//读时钟芯片的寄存器位置
#define DS1302_MINUTE_READ 0x83
#define DS1302_HOUR_READ 0x85
void reset_ds1302(void)
{
RST=0;
SCK=0;
RST=1;
}
/****************************
*名称:write_ds1302_byte
*说明:无
*功能: 写入8bit数据
*调用: 无
*输入:dat:要写入的数据
*输出:无
*****************************/
void write_ds1302_byte(uint8 dat)
{
uint8 i;
SCK=0;//初始化时钟线置为0
for(i=0;i<8;i++)//开始传输8个字节的数据
{
SDA=dat&0x01;//取最低位,注意DS1302的数据
//和地址都是从最低位开始传输的
SCK=1;//时钟线拉高,制造上升沿,SDA数据被传输
SCK=0; //时钟线拉低,为下个上升沿做准备
dat>>=1;//数据右移一位,准备传输的下一位
}
}
/****************************
*名称:read_ds1302_byte
*说明:无
*功能: 读取8bit数据
*调用: 无
*输入:dat:读取的数据
*输出:无
*****************************/
uint8 read_ds1302_byte(void)
{
uint8 i ,dat=0;
for (i=0;i<8;i++)
{
dat >>=1;
if(SDA)
dat|=0x80;
SCK=1;
SCK=0;//制造下降沿
}
return dat;
}
/****************************
*名称:write_ds1302
*说明:先写地址,后写数据
*功能:向addr相应地址中写一个字节的数据
*调用: write_ds1302_byte()
*输入:addr:要写入的控制字,dat:要写入的数据
*输出:无
*****************************/
void write_ds1302(uint8 addr,uint8 dat)
{
reset_ds1302();
write_ds1302_byte(addr);
write_ds1302_byte((dat/10)<<4|(dat%10));
//将10进制转化为压缩的BCD码,传输时为BCD码
SCK=1;//时钟线拉高
RST=0;//读取结束,CE置0,结束数据的传输
}
/****************************
*名称:uint8 read_ds1302
*说明:先写地址,后读数据
*功能: 从addr相应地址中读取一个字节的数据
*调用: write_ds1302_byte(),read_ds1302_byte()
*输入:addr:要写入的控制字
*输出:dat:要写入的数据
*****************************/
uint8 read_ds1302(uint8 addr)
{
uint8 dat,datH,datL,temp=0;
reset_ds1302();
write_ds1302_byte(addr);
dat=read_ds1302_byte();
SCK=1;
RST=0;
datH=dat/16; //将压缩的BCD码转换为十进制相当于左移4位
datL=dat%16;
temp=datH*10+datL;
return temp;//返回得到的时间/日期
}
/****************************
*名称:void Init_DS1302
*说明:给1302写一个初始值
*功能:
*调用: write_ds1302()
*输入:无
*输出:无
*****************************/
void Init_DS1302(void)
{
write_ds1302(0x8e,0x00);//写保护关
write_ds1302(DS1302_SECOND_WRITE,40);
write_ds1302(DS1302_MINUTE_WRITE,59);
write_ds1302(DS1302_HOUR_WRITE,23);//初始24小时模式
write_ds1302(0x8e,0x80);//写保护开
}
void init()
{
TMOD=0x01;
TH1=0xf8;
TL1=0xcd;
ET0=1;
TR1=1;
ET1=1;
}
void time_to_disbuff(void)
{
dis_buff[7]=miao%10;
dis_buff[6]=miao/10;
dis_buff[5]=10;
dis_buff[4]=fen%10;
dis_buff[3]=fen/10;
dis_buff[2]=10;
dis_buff[1]=shi%10;
dis_buff[0]=shi/10;
}
void disp()
{
P0=SegTab[dis_buff[LedBitCnt]];
switch(LedBitCnt)
{
case 0:
ADDR0=0;ADDR1=0;ADDR2=0;
break;
case 1:
ADDR0=1;ADDR1=0;ADDR2=0;
break;
case 2:
ADDR0=0;ADDR1=1;ADDR2=0;
break;
case 3:
ADDR0=1;ADDR1=1;ADDR2=0;
break;
case 4:
ADDR0=0;ADDR1=0;ADDR2=1;
break;
case 5:
ADDR0=1;ADDR1=0;ADDR2=1;
break;
case 6:
ADDR0=0;ADDR1=1;ADDR2=1;
break;
case 7:
ADDR0=1;ADDR1=1;ADDR2=1;
break;
}
}
void main()
{
Init_DS1302();
init();
EA=1;
while(1)
{
miao=read_ds1302(DS1302_SECOND_READ);
fen=read_ds1302(DS1302_MINUTE_READ);
shi=read_ds1302(DS1302_HOUR_READ);
if(ms2_flag)
{
ms2_flag=0;
LedBitCnt++;
if(LedBitCnt>7)
{
LedBitCnt=0;
}
time_to_disbuff();
disp();
}
}
}
void timer1() interrupt 3 //定时1ms
{
TH1=0xf8;
TL1=0xcd;
ms2_flag=1; //用于数码管显示
ms2_cnt++;
if(ms2_cnt>=5)
{
ms2_cnt=0;
ms10_flag=1;//用于键扫描
if(++ms10_cnt>=50)
{
ms10_cnt=0;
ms500_flag=~ms500_flag;
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|