#include<reg52.h>
#include<intrins.h>// 包括‘空’ 操作
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P1^1;
sbit IO=P1^2;
sbit RST=P1^3;
#define ds1302_sec_add 0x80// 定义秒数据地址
#define ds1302_min_add 0x82
#define ds1302_hour_add 0x84
#define ds1302_day_add 0x86
#define ds1302_month_add 0x88
#define ds1302_week_add 0x8a
#define ds1302_year_add 0x8c
#define ds1302_control_add 0x8e
#define ds1302_charger_add 0x90
extern uchar
time_buf1[8];// 空年月日时分秒周
extern uchar time_buf[8];// 空
/************************************************************
向DS1302写入一个数据
************************************************************/
//void Ds1302_Write_Byte(uchar add,uchar d);
/************************************************************
从DS1302读出一个数据
************************************************************/
//uchar Ds1302_Read_Byte(uchar add);
/***********************************************************
向DS1302写入时钟数据(初始化时间日期)
************************************************************/
//void Ds1302_Write_Time(void);
/************************************************************
从DS1302读出时钟数据
************************************************************/
//void Ds1302_Read_Time(void);
/************************************************************
DS1302初始化
************************************************************/
//void Ds1302_Init(void);
/*********************************************************************/
uchar time_buf1[8]={20,15,12,26,13,22,2,6};//年月日时分秒周
uchar time_buf[8];
/*******************************************************
向DS1302写入一个字节数据
********************************************************/
void Ds1302_Write_Byte(uchar addr,uchar d)
{
uchar i;
// SCLK=0;
// RST=0;
RST=1;// 传输开始
// 写入地址
addr=addr&0xfe;// 最低位置零 ,RD=1.WE=0,故为写入状态
for(i=0;i<8;i++)
{
if(addr&0x01)
IO=1;
else
IO=0;
SCLK=1;
SCLK=0;
addr=addr>>1;
}
//写入数据
for(i=0;i<8;i++)
{
if(d&0x01)
IO=1;
else
IO=0;
SCLK=1;
SCLK=0;
d=d>>1;
}
RST=0;// 停止DS1302总线
}
/*************************************************
从DS1302读出一个字节的数据
*************************************************/
uchar Ds1302_Read_Byte(uchar addr)
{
uchar i,temp;
RST=1;
// 写入地址
addr=addr|0x01;// 最低位置为1,RD=1读,WR=0写,故选取高电平
for(i=0;i<8;i++)
{
if(addr&0x01)
IO=1;
else
IO=0;
SCLK=1;
SCLK=0;
addr=addr>>1;
}
//读数据
for(i=0;i<8;i++)
{
temp=temp>>1; // 最高位置为0
if(IO) // 如果此时IO口高电平,则temp最高位1
temp|=0x80;
else
temp&=0x7f;//否则temp最高位0 ,,7次右移之后变成最低位
SCLK=1;
SCLK=0;
}
RST=0;// 停止总线
return temp;
}
/*************************************************
向DS1302写入时钟数据 初始化时间日期
*************************************************/
void Ds1302_Write_Time(void)
{
uchar i,tmp;
for(i=0;i<8;i++)
{
tmp=time_buf1[i]/10; //BCD处理,得到压缩的BCD码,4位二进制表示1位十进制数
time_buf[i]=time_buf1[i]%10; //初始化时采用16进制数,可不用BCD处理???(待定)
time_buf[i]=time_buf[i]+tmp*16;
}
Ds1302_Write_Byte(ds1302_control_add,0x00); //关闭写保护
Ds1302_Write_Byte(ds1302_sec_add,0x80); //暂停
// Ds1302_Write_Byte(ds1302_charge_add,0xa9); //涓流充电
Ds1302_Write_Byte(ds1302_year_add,time_buf[1]); //年
Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);
Ds1302_Write_Byte(ds1302_day_add,time_buf[3]);
Ds1302_Write_Byte(ds1302_week_add,time_buf[7]);
Ds1302_Write_Byte(ds1302_hour_add,time_buf[4]);
Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);
Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);
Ds1302_Write_Byte(ds1302_week_add,time_buf[7]);
Ds1302_Write_Byte(ds1302_control_add,0x80); //打开写保护
}
/*******************************************************************
从DS1302读出时钟数据
********************************************************************/
void Ds1302_Read_Time(void)
{
uchar i,tmp;
time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);
time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);
time_buf[3]=Ds1302_Read_Byte(ds1302_day_add);
time_buf[4]=Ds1302_Read_Byte(ds1302_hour_add);
time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);
time_buf[6]=(Ds1302_Read_Byte(ds1302_sec_add))&0x7f;
time_buf[7]=Ds1302_Read_Byte(ds1302_week_add);
for(i=0;i<8;i++)
{
//BCD处理
tmp=time_buf[i]/16;
time_buf1[i]=time_buf[i]%16;
time_buf1[i]=time_buf1[i]+tmp*10;
}
}
/****************************************************
DS1302初始化
*****************************************************/
void Ds1302_Init(void)
{
RST=0;
SCLK=0;
Ds1302_Write_Byte(ds1302_sec_add,0x00);
}
/********************************************************
数码管显示时钟
内容:DS1302实时时钟数码管显示,时间和日期切换显示,按下按键,循环切换
时间格式xx-xx-xx
日期格式xx-xx-xx
周秒格式-x- xx
*********************************************************/
// #include<reg52.h>
#define Key P3 //定义按键端口
#define Data P0 //定义数据端口
sbit du=P2^1;
sbit we=P2^2;
bit ReadTimeFlag; //定义读时间标志
uchar code table_du[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code table_we[]=(0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f);
uchar TempData[8];// 存储显示值的全局变量
void delay(uint z);
void display(uchar FirstBit,uchar Num);
uchar KeyScan(void);
void Init_Timer0(void);
/************************************
主函数
*************************************/
void main(void)
{
uchar num,displaynum;
Init_Timer0();
Ds1302_Init();
Ds1302_Write_Time();
while(1)
{
num=KeyScan();
if(num==1)
{
displaynum++;
if(displaynum==3)
displaynum=0;
}
if(ReadTimeFlag==1)
{
ReadTimeFlag=0;
Ds1302_Read_Time();
if(displaynum==0) //显示时间
{
TempData[0]=table_du[time_buf1[4]/10]; //时
TempData[1]=table_du[time_buf1[4]%10];
TempData[2]=0x40;
TempData[3]=table_du[time_buf1[5]/10]; //分
TempData[4]=table_du[time_buf1[5]%10];
TempData[5]=0x40;
TempData[6]=table_du[time_buf1[6]/10]; //秒
TempData[7]=table_du[time_buf1[6]%10];
}
else if(displaynum==1)// 显示日期
{
TempData[0]=table_du[time_buf1[1]/10];//年
TempData[1]=table_du[time_buf1[1]%10];
TempData[2]=0x40;
TempData[3]=table_du[time_buf1[2]/10];//月
TempData[4]=table_du[time_buf1[2]%10];
TempData[5]=0x40;
TempData[6]=table_du[time_buf1[3]/10];//日
TempData[7]=table_du[time_buf1[3]%10];
}
else if(displaynum==2)// 显示周秒
{
TempData[0]=0x40;
TempData[1]=table_du[time_buf1[7]%10];
TempData[2]=0x40;
TempData[3]=0;
TempData[4]=0;
TempData[5]=0;
TempData[6]=table_du[time_buf1[6]/10];
TempData[7]=table_du[time_buf1[6]%10];
}
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Display(uchar FirstBit,uchar Num)
{
static unsigned char p=0;
Data=0; //消影
du=1;
du=0;
Data=table_we[p+FirstBit];
we=1;
we=0;
Data=TempData[p];
du=1;
du=0;
p++;
if(p==Num)
p=0;
}
/*************************************
定时器初始化子程序
*************************************/
void Init_Timer0(void)
{
TMOD|=0x01; //使用模式1,16位定时器,使用“|”符号可以在使用多个定时器时不受影响
//TH0=(65536-50000)/256;
// TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
/**********************************************
定时器中断子程序
*******************************************/
void Timer0(void) interrupt 1
{
static unsigned int num;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
Display(0,8);//调用数码管显示,第1位开始显示,共8位
num++;
if(num==50)
{
num=0;
ReadTimeFlag=1;
}
}
/*******************************************
按键扫描函数,返回扫描键值
******************************************/
uchar KeyScan()
{
uchar keyvalue;
if(Key!=0xff)
{
delay(10);
if(Key!=0xff)
{
keyvalue=Key;
while(Key!=0xff);
switch(keyvalue)
{
case 0xfe:return 1;break;
case 0xfd:return 2;break;
case 0xfb:return 3;break;
case 0xf7:return 4;break;
case 0xef:return 5;break;
case 0xdf:return 6;break;
case 0xbf:return 7;break;
case 0x7f:return 8;break;
default:return 0;break;
}
}
}
return 0;
}
一周热门 更多>