时钟芯片DS1302程序
DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信实时时钟/日历电路。提供秒分时日星期月年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM指示决定采用24或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:1)RST 复位,2)SDA 数据线,3)SCK 串行时钟。时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。以下程序包含DS1302的主要操作以及数据存取功能。
Ds1302.h代码
#define DS1302_VT_SECOND 0 #define DS1302_VT_MINURE 1 #define DS1302_VT_HOUR 2 #define DS1302_VT_DATE 3 #define DS1302_VT_MONTH 4 #define DS1302_VT_DAY 5 #define DS1302_VT_YEAR 6 extern unsigned char Ds1302_Buff[7]; //秒分时日月周年2011-07-14 12:00:00 void Ds1302_Init(); void Ds1302_Read_RTC(void); void Ds1302_Set_RTC(void); unsigned char Ds1302_Read_Value(unsigned char valueType); void Ds1302_Set_Value(unsigned char valueType, unsigned char value);
Ds1302.c代码
#include "intrins.h" #include "Hardware.h" #include "Ds1302.h" sbit SCK = P1^3; //时钟 sbit SDA = P1^4; //数据 sbit RST = P1^5; // DS1302复位 unsigned char Ds1302_Buff[7]; //秒分时日月周年 code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位 code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; void Ds1302_Delay() { unsigned char t_delay = 100; while(t_delay--); } void Ds1302_Write_Byte(unsigned char temp) { unsigned char i; for (i=0; i<8; i++) //循环8次 写入数据 { SCK = 0; SDA = temp & 0x01; //每次传输低字节 temp >>= 1; //右移一位 SCK = 1; } } unsigned char Ds1302_Read_Byte() { unsigned char i, temp = 0x00; for (i=0; i<8; i++) //循环8次 读取数据 { temp >>= 1; //右移一位 SCK = 0; _nop_(); if(SDA) temp |= 0x80; //每次传输低字节 SCK = 1; } return temp; } void Ds1302_Prepare_IO() { RST = 0; Ds1302_Delay(); SCK = 0; _nop_(); RST = 1; Ds1302_Delay(); } void Ds1302_Write(unsigned char address, unsigned char dat) { Ds1302_Prepare_IO(); Ds1302_Write_Byte(address); //发送地址 Ds1302_Write_Byte(dat); //发送数据 RST = 0; //恢复 } unsigned char Ds1302_Read(unsigned char address) { unsigned char temp; Ds1302_Prepare_IO(); Ds1302_Write_Byte(address); temp = Ds1302_Read_Byte(); RST = 0; return temp; } void Ds1302_Read_RTC(void) //读取 日历 { unsigned char i, *p; p = read_rtc_address; //地址传递 for(i=0; i<7; i++) //分7次读取 秒分时日月周年 { Ds1302_Buff[i] = Ds1302_Read(*p); p++; } } void Ds1302_Set_RTC(void) //设定 日历 { unsigned char i, *p; Ds1302_Write(0x8E, 0X00); p = write_rtc_address; //传地址 for(i=0; i<7; i++) //7次写入 秒分时日月周年 { Ds1302_Write(*p, Ds1302_Buff[i]); p++; } Ds1302_Write(0x8E, 0x80); } void Ds1302_Init() { Ds1302_Write(0x8e, 0x00); //写保护控制字,允许写 Ds1302_Write(0x80, 0x00); //开启时钟 Ds1302_Write(0x90, 0x5c); //禁止充电 } unsigned char Ds1302_Read_Value(unsigned char valueType) { unsigned char temp = Ds1302_Buff[valueType]; unsigned char hour12; if (valueType == 2) { if (temp & 0x80) { // 12小时转24小时 hour12 = ((temp & 0x10) >> 4) * 10 + (temp & 0x0F); if (temp & 0x20) return (hour12 + 12) % 24; else return hour12;
} else return ((temp & 0x30) >> 4) * 10 + (temp & 0x0F); } else return (temp >> 4) * 10 + (temp & 0x0F); } void Ds1302_Set_Value(unsigned char valueType, unsigned char value) { unsigned char highBits = value / 10; highBits <<= 4; if (valueType == 2) { Ds1302_Buff[2] = highBits + value % 10; } else Ds1302_Buff[valueType] = highBits + value % 10; }