目录
1.DS1302时钟:数码管上显示电子时钟时分秒,格式为“XX XX XX”
SPI:
写时序:
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302, 数据输入从低位(位0)开始。(先写低位)
读时序:
在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。(先读低位,读取后将IO设置为0,否则读出的数据会出错)
DS1302:
DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM指示决定采用24或12小时格式。
DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:①RES复位②I/O数据线③SCLK串行时钟。
时钟/RAM的读/写数据以一个字节或多达 31个字节的字符组方式通信。DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。DS1302由 DS1202改进而来增加了以下的特性:双电源管脚用于主电源和备份电源供应,Vcc1为可编程涓流充电电源,附加七个字节存储器。实时时钟具有能计算2100年之前的秒、分、时、日、星期、月、年的能力,还有闰年调整的能力;31个8位暂存数据存储RAM宽范围;工作电压2.0~5.5V;可选工业级温度范围-40~+85℃;读/写时钟或RAM数据时有两种传送方式单字节传送和多字节传送字符组方式。
从DS1302中读取写入的时钟数据均为BCD码格式,使用时需转换为我们习惯转换为10进制。在处理DS1302读取的数据时,取高低位使用除16和取余16,并非之前的除10和取余10。这是因为写入进DS1302时是BCD码, 读取出的数据也是BCD码,而BCD码即是4位表示一个十进制数,类似于一个字节的十六进制数据的高4位和低4位一样,所以这里是除16和取余16。
/*
2位DEC/BCD相互转化:
DEC=BCD/16*10+BCD%16;
BCD=DEC/10*16+DEC%10;
*/
当该寄存器最高位WP为1时,DS1302只能读不能写,所以要在往DS1302写数据前确保WP为0。
写保护的控制寄存器的位7是写保护位,前7位(位0至位6)被强制为0且读取时总是读0. 在任 何对时钟或RAM的写操作以前,位7必须为 0。当为高时,写保护位禁止任何寄存器的写操作。初始加电状态未定义.。因此,在试图写器件之前应该清除WP位。
1.DS1302时钟:数码管上显示电子时钟时分秒,格式为“XX XX XX”
DS1302函数
#include <REGX52.H>
sbit DS1302_IO=P3^4;
sbit CE=P3^5;
sbit SCLK=P3^6;
//.h文件需将时间数组设置为外部全局变量
unsigned char DS1302_Time[]={22,10,15,17,18,30};//时间数组,索引0~5分别为年、月、日、时、分、秒 需要在.h文件extern声明外部可调用数组
void DS1302_Init(void)//DS1302初始化
{
CE=0;
SCLK=0;
}
void DS1302_WriteByte(unsigned char Command,Byte)//DS1302写一个字节,命令地址,数据
{
unsigned char i;
CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=Command&(0x01<<i);//先写低位
SCLK=1;
SCLK=0;
}
for(i=0;i<8;i++)
{
DS1302_IO=Byte&(0x01<<i);
SCLK=1;
SCLK=0;
}
CE=0;
}
unsigned char DS1302_ReadByte(unsigned char Command)//DS1302读一个字节,命令地址 返回数据值
{
unsigned char i,Byte=0x00;
CE=1;
for(i=0;i<8;i++)
{
SCLK=0;
DS1302_IO=Command&(0x01<<i);
SCLK=1;
}
for(i=0;i<8;i++)
{
SCLK=0;
if(DS1302_IO)Byte|=(0x01<<i);
SCLK=1;
}
CE=0;
SCLK=0;
DS1302_IO=0;//读取后将IO设置为0,否则读出的数据会出错
return Byte;
}
void DS1302_SetTime(void)//DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中
{
DS1302_WriteByte(0x8e,0x00);//关闭写保护
DS1302_WriteByte(0x8c,DS1302_Time[0]/10*16+DS1302_Time[0]%10);//DEC转BCD
DS1302_WriteByte(0x88,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
DS1302_WriteByte(0x86,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
DS1302_WriteByte(0x84,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
DS1302_WriteByte(0x82,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
DS1302_WriteByte(0x80,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
DS1302_WriteByte(0x8e,0x80);//打开写保护,打开后无法重新写入,根据实况可以注释掉
}
void DS1302_ReadTime(void)// DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中
{
unsigned char temp;
temp=DS1302_ReadByte(0x8d);
DS1302_Time[0]=temp/16*10+temp%16;//BCD转DEC
temp=DS1302_ReadByte(0x89);
DS1302_Time[1]=temp/16*10+temp%16;
temp=DS1302_ReadByte(0x87);
DS1302_Time[2]=temp/16*10+temp%16;
temp=DS1302_ReadByte(0x85);
DS1302_Time[3]=temp/16*10+temp%16;
temp=DS1302_ReadByte(0x83);
DS1302_Time[4]=temp/16*10+temp%16;
temp=DS1302_ReadByte(0x81);
DS1302_Time[5]=temp/16*10+temp%16;
}
主函数
#include <REGX52.H>
#include "DS1302.h"
#include "shumaguan.h"
void main()
{
DS1302_Init();
DS1302_SetTime();
while(1)
{
DS1302_ReadTime();
shumaguan(1,DS1302_Time[3]/10);
shumaguan(2,DS1302_Time[3]%10);
shumaguan(4,DS1302_Time[4]/10);
shumaguan(5,DS1302_Time[4]%10);
shumaguan(7,DS1302_Time[5]/10);
shumaguan(8,DS1302_Time[5]%10);
}
}