调试OK的DS1302驱动程序
//寄存器宏定义
#define DS1302_WRITE_SECOND 0x80
#define DS1302_WRITE_MINUTE 0x82
#define DS1302_WRITE_HOUR 0x84
#define DS1302_READ_SECOND 0x81
#define DS1302_READ_MINUTE 0x83
#define DS1302_READ_HOUR 0x85
#define DS1302_WRITE_PROTECT 0x8E
#define DS1302_WRITE_DAY 0x86
#define DS1302_WRITE_MONTH 0x88
#define DS1302_WRITE_YEAR 0x8C
#define DS1302_WRITE_WEEK 0x8A
#define DS1302_READ_DAY 0x87
#define DS1302_READ_MONTH 0x89
#define DS1302_READ_YEAR 0x8D
#define DS1302_READ_WEEK 0x8B
#define DS1302_GPIO_Init() P3DIR &= ~(BIT(0)|BIT(1)); P3 |=(BIT(0)|BIT(1));\
P1DIR &= ~(BIT(7)); P1 |=BIT(7);
#define DS1302_DIO_Input() P3DIR |= BIT(0); P3PU |= BIT(0);
#define DS1302_DIO_State (P3 & BIT(0))
#define DS1302_DIO P30
#define DS1302_CE P31
#define DS1302_CLK P17
void DS1302Write ( unsigned char addr,uint8 dat )
{
unsigned char i;
DS1302_GPIO_Init();
DS1302_CE=0; //CE引脚为低,数据传送中止
DS1302_CLK=0; //清零时钟总线
Delay_us(2);
DS1302_CE = 1; //CE引脚为高,逻辑控制有效
Delay_us(2);
//发送地址
//addr = addr & 0xFE; //最低位置零
for ( i=0; i<8; i++ ) //循环8次移位
{
DS1302_CLK = 0;
if (addr&0x01)//每次传输低字节
{
DS1302_DIO = 1;
}
else
{
DS1302_DIO = 0;
}
addr >>= 1; //右移一位
DS1302_CLK = 1;
}
//发送数据
for ( i=0; i<8; i++ )
{
DS1302_CLK = 0;
if (dat&0x01)
{
DS1302_DIO = 1;
}
else
{
DS1302_DIO = 0;
}
dat >>= 1;
DS1302_CLK = 1;
}
DS1302_CE = 0;
DS1302_CLK = 0;
}
//数据读取子程序
unsigned char DS1302Read ( unsigned char addr )
{
unsigned char i,temp;
DS1302_GPIO_Init();
DS1302_CE=0;
DS1302_CLK=0;
DS1302_CE = 1;
//addr = addr | 0x01;//最低位置高
//发送地址
for ( i=0; i<8; i++ ) //循环8次移位
{
DS1302_CLK = 0;
if (addr&0x01)//每次传输低字节
{
DS1302_DIO = 1;
}
else
{
DS1302_DIO = 0;
}
addr >>= 1; //右移一位
DS1302_CLK = 1;
Delay_us(5);
}
//读取数据
DS1302_DIO_Input();
for ( i=0; i<8; i++ )
{
if(DS1302_DIO_State)
{
temp = temp|0x80;
}
else
{
temp = temp&0x7f;
}
DS1302_CLK = 1;
temp = temp>>1;
DS1302_CLK = 0;
}
DS1302_CE=0;
DS1302_CLK = 0;
/*dat1=temp;
dat2=dat1/16; //数据进制转换
dat1=dat1%16; //十六进制转十进制
dat1=dat1+dat2*10;*/
return (temp);
}
//uint8 time_data[]={0x50,0x59,0x23,0x00,0x00,0x00,0x00};
void DS1302_SetTime(uint8 reg,uint8 data)
{
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(reg,data);//写保护关
DS1302Write(0x8e,0x80); //允许写保护
}
void DS1302_GetTime(void)
{
//uint8 i;
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(0x8e,0x80); //允许写保护
}
/*************************************************
名称:DS1302WriteByte*说明:无 *功能:写入8bit数据*调用:
delayus() *输入:dat:要写入的数据*输出:无
*************************************************/
void DS1302WriteByte(uint8 dat)
{
uint8 i;
DS1302_CE=0;//初始时钟线置为0
Delay_us(2);
for(i=0;i<8;i++)//开始传输8个字节的数据
{
DS1302_DIO=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
Delay_us(2);
DS1302_CLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输
Delay_us(2);
DS1302_CLK=0;//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
DS1302_CE=1;
}
/*************************************************
名称:DS1302ReadByteDS1302ReadByte()()*说明:无 *功能:
读取8bit的数据*调用:delayus()*输入:无 *输出:dat:读取
的数据 *************************************************/
uint8 DS1302ReadByte(void)
{
uint8 i,dat;
DS1302_CE=0;
Delay_us(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据左移一位
if(DS1302_DIO==1)//当数据线为高时,证明该位数据为1
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
DS1302_CLK=1;//拉高时钟线
Delay_us(2);
DS1302_CLK=0;//制造下降沿
Delay_us(2);
}
DS1302_CE=1;
return dat;//返回读取出的数据
}
/*************************************************
名称:voidInit_DS1302(void)*说明:给1302写入一个初始的值*功能:
写入日期,和时钟的值*调用:DS1302Write()*输入:无*输出:无
*************************************************/
void Init_DS1302(void)
{
DS1302_GPIO_Init();
DS1302Write(0x8e,0x00);//写保护关
DS1302Write(DS1302_WRITE_SECOND,0x00);//初始秒值为0
DS1302Write(DS1302_WRITE_MINUTE,0x20);//初始分钟值为0
DS1302Write(DS1302_WRITE_HOUR,0x09);//初始为24小时模式初始时间为0点
DS1302Write(DS1302_WRITE_DAY,0x15);//2011年1月1日星期6
DS1302Write(DS1302_WRITE_MONTH,0x12);
DS1302Write(DS1302_WRITE_YEAR,0x10);
DS1302Write(DS1302_WRITE_WEEK,0x06);
DS1302Write(0x90,0x00);//充电
DS1302Write(0xc0,0xf0);//初始化一次标示
DS1302Write(0x8e,0x80); //允许写保护
}