1、DS1302硬件
2、数据写入和读取
3、数组的应用
4、程序
目录
1、DS1302 操作引脚 有CE、SCLCK、IO。
DS1302靠内部晶振,按固定频率运行。将年、月、日等数据写入制定的内存,之后将其读出并通过LDC显示出来。
内存地址:
在使用过程中还要比较STC51单片机和DS1302芯片的频率,判断是否需要用延时函数。
2、写入和读出:
数据的写入和读出,根据时序图操作。CE,SCLK相当于两个相互配合的开关,不同的开关关系对应不同的操作,输入输出的数据通过IO口写入或者读取。
写入时先写入一个存放地址,再输入数据。读取时输入一个读取地址,再定义一个变量,通过IO口上的高低电平将数据写入变量。
3、数组的应用。定义一个数组,用于存放年、月、日、时、分、秒等数据。
使用数据的好处有:
(1)减少定义变量。
(2)可以通过一个变量的++、——,来选择数组内的数据。方便操作选择时间数据 ,并进行调整。
4、程序设计。程序设计应该根据实现目的,分层次设计架构。
时钟程序分为两大部分:
(1)设置时钟
(2)显示时钟
设置时钟又分为:
(1)日期、时间位选择
(2)调整日期或时间
(3)设置位闪烁
闪烁通过定时器中断程序来辅助实现,日期、时间设置需要注意越界情况。
#include <REGX52.H>
#define uchar unsigned char //定义 unsigned char
#define DS1302_Second 0x80 //定义引脚,方便阅读和编程。
#define DS1302_Minute 0x82
#define DS1302_Hour 0x84
#define DS1302_Date 0x86
#define DS1302_Month 0x88
#define DS1302_Day 0x8A
#define DS1302_Year 0x8C
#define DS1302_Wp 0x8E
char DS1302_Time[]={22,6,12,20,02,33,7}; //用数组表示年月日时间,减少变量。0 年、1 月、2 日、3 时、4 分、5 秒、6 星期
sbit DS1302_SCLK=P3^6; //定义引脚 需要和原理图上的引脚对应
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
void DS1302_Init(void) //第一步初始化引脚。
{
DS1302_CE=0;
DS1302_SCLK=0;
}
void DS1302_WriteByte(uchar Command,Date) //写入分两步:1、写入存放地址;2、写入数据;
{
uchar i=0;
DS1302_CE=1; //打开写入“开关”
for(i=0;i<8;i++) //循环8次写入8个bit。
{
DS1302_IO=Command&(0x01<<i); //写入将要存放数据的地址
DS1302_SCLK=1; //上升沿写入
DS1302_SCLK=0;
}
for(i=0;i<8;i++) //写入数据
{
DS1302_IO=Date&(0x01<<i);
DS1302_SCLK=1;
DS1302_SCLK=0;
}
DS1302_CE=0;
}
uchar DS1302_Read(uchar Command) //读数据和写入数据不同,只需要给数据存储地址即可。
{
uchar i=0x00;
uchar Date=0x00;//定义一个变量被用于赋值
Command|=0x01; //将DS1302_** 0x8*指令转换为读指令
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_SCLK=0;
DS1302_IO=Command&(0x01<<i);
DS1302_SCLK=1;
}
for(i=0;i<8;i++)
{
DS1302_SCLK=1;
DS1302_SCLK=0;
if(DS1302_IO){Date|=(0x01<<i);} //和写入数据不同,需要定义一个变量承接数据。
//如果IO上数据为1则Date在这一位为1否则为0。
}
DS1302_CE=0;
DS1302_IO=0;
return Date; //返回数据
}
void DS1302_SetTime(void)
{
//DS1302_WriteByte(DS1302_Wp,0x00);
DS1302_WriteByte(DS1302_Year,DS1302_Time[0]/10*16+DS1302_Time[0]%10); //写入年并且十进制转BCD码
DS1302_WriteByte(DS1302_Month,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
DS1302_WriteByte(DS1302_Date,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
DS1302_WriteByte(DS1302_Hour,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
DS1302_WriteByte(DS1302_Minute,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
DS1302_WriteByte(DS1302_Second,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
DS1302_WriteByte(DS1302_Day,DS1302_Time[6]/10*16+DS1302_Time[6]%10);
//DS1302_WriteByte(DS1302_Wp,0x80);
}
void DS1302_ReadTime()
{
uchar Temp;
Temp=DS1302_Read(DS1302_Year);
DS1302_Time[0]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Month);
DS1302_Time[1]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Date);
DS1302_Time[2]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Hour);
DS1302_Time[3]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Minute);
DS1302_Time[4]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Second);
DS1302_Time[5]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Day);
DS1302_Time[6]=Temp/16*10+Temp%16;
}
DS1302_IO=0; //读取后将IO设置为0,否则读出的数据会出错