#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;
}
#include<reg52.h>
#include <syssys.h>
/**********/
void write1302(unsigned char addr,dat)
{
unsigned char i,temp;
CE=0;
SCLK=0;
CE=1;
for(i=0;i<8;i++) //写入地址
{
SCLK=0;
temp=addr;
if(temp&0x01==0x01)
DIO=1;
else
DIO=0;
addr>>=1;
SCLK=1;
}
for(i=0;i<8;i++) //写入数据
{
SCLK=0;
temp=dat;
if(temp&0x01==0x01)
DIO=1;
else
DIO=0;
dat>>=1;
SCLK=1;
}
}
unsigned char read1302(unsigned char addr)
{
unsigned char i,temp,dat1,dat2;
CE=0;
SCLK=0;
CE=1;
for(i=8;i>0;i--)//写入读存储单元地址
{
SCLK =0;
temp =addr;
if(temp&0x01==0x01)
DIO=1;
else
DIO=0;
addr>>=1;
SCLK=1;
}
for(i=8;i>0;i--)//读数据
{
ACC_7=DIO;
SCLK=1;
ACC>>=1;
SCLK=0; //下降沿读出数据
}
CE=0;
dat1=ACC;
dat2=dat1/16;
dat1=dat1%16;
dat1=dat1+dat2*10;
return(ACC);
}
/////////////////////////////////////
void Initial(void)
{
write1302(write_protect,0x00);
write1302(write_second,0x55); //秒从55开始
write1302(write_minute,0x59); //分从59开始
write1302(write_hour,0x16); //赋值0x80,为12小时计时,但低五位为计时为,所以,显示只显示低五位,小时从11开始
write1302(write_day,0x23);
write1302(write_year,0x15); //15年
write1302(write_week,0x02);//周三
write1302(write_month,0x12);//10月
write1302(write_protect,0x80);
}
#ifndef __DS1302_H__
#define __DS1302_H__
#include <syssys.h>
#include <reg52.h>
#include<intrins.h>
/************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define write_second 0x80 //秒开始数存储,修改用(下同)
#define write_minute 0x82 //分开始数存储
#define write_hour 0x84 //时开始数存储,12小时计时,从0开始要写入0x80(12小时要判断上下午)。
#define read_second 0x81 //秒,显示要读这个存储器
#define read_minute 0x83 //分,显示要读这个存储器
#define read_hour 0x85 //时,显示要读这个存储器
#define write_day 0x86
#define read_day 0x87
#define write_month 0x88
#define read_month 0x89
#define write_week 0x8A
#define read_week 0x8B
#define write_year 0x8C
#define read_year 0x8D
#define write_protect 0x8E
/************************************************************/
sbit ACC_7=ACC^7;
sbit SCLK =P2^2;
sbit DIO =P2^3;
sbit CE =P2^1; //protus软件中的RST脚
/********************************/
void write1302(unsigned char addr,dat);
unsigned char read1302(unsigned char addr);
void Initial(void);
#endif
void main(void)
{
Lcd_Init();
LCD_Clear(WHITE);
BACK_COLOR=BLACK;;POINT_COLOR=WHITE;
Initial();
while(1)
{
key1scan();
miao=read1302(read_second);
fen=read1302(read_minute);
shi=read1302(read_hour);
ri=read1302(read_day);
nian=read1302(read_year);
yue=read1302(read_month);
week=read1302(read_week);
LCD_ShowString(0,0,"miao");LCD_Show2Num(40,0,miao,2);
LCD_ShowString(0,15,"fen");LCD_Show2Num(40,15,fen,2);
LCD_ShowString(0,31,"shi");LCD_Show2Num(40,31,shi,2);
LCD_ShowString(0,46,"ri");LCD_Show2Num(40,46,ri,2);
LCD_ShowString(0,61,"yue");LCD_Show2Num(40,61,yue,2);
LCD_ShowString(0,81,"week");LCD_Show2Num(40,81,week,2);
LCD_ShowString(0,97,"nian");LCD_Show2Num(40,97,nian,2);
}
}
一周热门 更多>