1、寄存器表
注意:
(1)ds1302.h中提供的寄存器地址是写地址,读寄存器时需要将地址加一
(2)
#define ds1302_control_addr 0x8Ee //写保护命令字单元地址
对应上图倒数第二行:
BIT7 = 0(取消写保护)、BIT7 = 1(上写保护)
(3) 读一次寄存器后需要增加一条写指令(不知道为什么):
curtime[i] = Ds1302_Single_Byte_Read(read_addr[i]);
Ds1302_Single_Byte_Write(0x00, 0x00);
(4)在提供的ds1302.c中使用到的函数为:
/********************************************************************/
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);
2、DS1302相关知识(from datasheet ):
X1、X2:32.768KHZ晶振
SCLK:串行时钟
CE:复位脚,在数据读写期间必须为高
I/O:数据
两电源引脚关系为备用电源,Vcc1为主电源
CLK I/O经常与I2C总线接在一个引脚上,但DS1302并不是I2C总线,是一种三线式总线
3、DS1302驱动分析(比赛提供)
驱动步骤:
(1)CE = 1
(2)在上升沿按位传输地址字
(3)读取 / 写入相应地址的数据
(4)CE = 0
附:驱动文件ds1302.c
/********************************************************************/
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr & 0xFE;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/
Write_Ds1302_Byte(dat); /*写入数据:dat*/
RST_CLR; /*停止DS1302总线*/
}
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp;
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr | 0x01;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/
RST_CLR; /*停止DS1302总线*/
return temp;
}
4、设定 / 读取时间
(1)设定时间
uchar settime[6] = {1,11,22,17,20,0};
uchar write_addr[6] = {0x8C,0x88,0x86,0x84,0x82,0x80};
uchar read_addr[6] = {0x8d,0x89,0x87,0x85,0x83,0x81};
void DS1302_settime(uchar stime[]) //输入十进制数字
{
uchar temptime[6];
int i;
for(i = 0;i < 6;i++) //按寄存器格式整理输入数据
{
temptime[i] = ((stime[i]/10)<<4)+(stime[i]%10);
}
Ds1302_Single_Byte_Write(ds1302_control_addr, 0x00); //取消写保护
for(i=0;i<6;i++)
{
Ds1302_Single_Byte_Write(write_addr[i], temptime[i]);//设置时间
}
Ds1302_Single_Byte_Write(ds1302_control_addr, 0x80); //上写保护
}
注意:为了方便起见,将用到的寄存器地址位放入数组,取值参照ds1302.h,read_addr = write_addr + 1
(2)获取时间
uchar curtime[6];
void gettime() //输出十进制数字
{
int i;
for(i=0;i<6;i++)
{
curtime[i] = Ds1302_Single_Byte_Read(read_addr[i]);
Ds1302_Single_Byte_Write(0x00, 0x00);
curtime[i] = ((curtime[i] & 0xf0)>>4)*10+(curtime[i] & 0x0f);
}
}
附:测试程序
void main()
{
cls_buzz();
UartInit();
DS1302_settime(settime);
Delay100ms(100);
gettime();
sendtime(curtime);
while(1);
}
void sendtime(char dat[])
{
int i;
for(i=0;i<6;i++)
{
SBUF = dat[i];
while(!TI);
TI = 0;
}
}