📄 time.c
字号:
//************************************************************
//实时时钟SD2400读写C51演示程序
// chendw@whwave.com.cn 2008/01/15
//************************************************************
#include "time.h"
/******读SD2400实时数据寄存器******/
//读出时间后屏蔽掉无用数据位
//如果调用此程序而所用系统当中又没有时钟或时钟不正常就会出现死机现象
void ReadDate(void)
{
if(Fhsec) //系统每0.5S读一次时间
{
bit Flag;
Flag = 1;
Fhsec = 0;
while(Flag)
{
if(I2CStart()) //判断开始是否正确
{
I2CSendByte(0x65);
if(I2CWaitAck()) //判断ACK是否正确
{
TimeBuf.Time.Second = I2CReceiveByte()&0x7f; //秒
I2CAck();
TimeBuf.Time.Minute = I2CReceiveByte()&0x7f; //分
I2CAck();
TimeBuf.Time.Hour = I2CReceiveByte()&0x3f; //时
I2CAck();
TimeBuf.Time.Week = I2CReceiveByte()&0x07; //星期
I2CAck();
TimeBuf.Time.Day = I2CReceiveByte()&0x3f; //日
I2CAck();
TimeBuf.Time.Month = I2CReceiveByte()&0x1f; //月
I2CAck();
TimeBuf.Time.Year = I2CReceiveByte(); //年
I2CNoAck(); //最后一个数据不应答
Flag = 0;
}
}
I2CStop();
}
}
}
/******写SD2400实时数据寄存器******/
void WriteDate(void)
{
WriteTimeOn();
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x00); //设置写起始地址
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Second); // second
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Minute); //minute
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Hour|0x80); //hour ,二十四小时制
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Week); //week
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Day); //day
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Month); //month
I2CWaitAck();
I2CSendByte(TimeBuf.Time.Year); //year
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x12); //设置写起始地址
I2CWaitAck();
I2CSendByte(0x00); //清零数字调整寄存器
I2CWaitAck();
I2CStop();
WriteTimeOff();
}
/********读Flash状态位程序**********/
//如果读取出的数据不正常则要重新启动或者初始化数据
void rState(void)
{
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x14);
I2CWaitAck();
I2CStart();
I2CSendByte(0x65);
I2CWaitAck();
State = I2CReceiveByte();
I2CNoAck(); //最后一个数据不应答
I2CStop();
}
/********写Flash状态位程序**********/
void wState(void)
{
WriteTimeOn();
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x14); //设置写起始地址
I2CWaitAck();
I2CSendByte(State); //写入状态位
I2CWaitAck();
I2CStop();
WriteTimeOff();
}
/********开启SD2400的I2C总线********/
static bit I2CStart(void)
{
SDA=1;
SCL=1;
I2CWait();
if(!SDA) return false;//SDA线为低电平则总线忙,退出
SDA=0;
I2CWait();
if(SDA) return false;//SDA线为高电平则总线出错,退出
SCL=0;
I2CWait();
return true;
}
/********关闭SD2400的I2C总线*******/
static void I2CStop(void)
{
SDA=0;
SCL=0;
I2CWait();
SCL=1;
I2CWait();
SDA=1;
}
/*********发送 ACK*********/
static void I2CAck(void)
{
SDA=0;
SCL=0;
I2CWait();
SCL=1;
I2CWait();
SCL=0;
}
/*********发送NO ACK*********/
static void I2CNoAck(void)
{
SDA=1;
SCL=0;
I2CWait();
SCL=1;
I2CWait();
SCL=0;
}
/*********读取ACK信号*********/
static bit I2CWaitAck(void) //返回为:1=有ACK,0=无ACK
{
uchar i = 0xff;
SCL=0;
SDA=1;
I2CWait();
SCL=1;
I2CWait();
while(SDA)
{
if((i--) == 0)
{
SCL = 0;
return false;
}
}
SCL=0;
return true;
}
/************MCU向SD2400发送一个字节*************/
static void I2CSendByte(uchar Data) //数据从高位到低位//
{
uchar i=8;
while(i--)
{
SCL=0;
_nop_();
SDA = Data & 0x80;
Data <<= 1;
I2CWait();
SCL=1;
I2CWait();
}
SCL=0;
}
/*********MCU从SD2400读入一字节*********/
static uchar I2CReceiveByte(void) //数据从高位到低位//
{
uchar i=8;
uchar ddata=0;
SDA=1;
while(i--)
{
ddata<<=1; //数据从高位开始读取
SCL=0;
I2CWait();
SCL=1;
I2CWait(); //从高位开始 ddata|=SDA;ddata<<=1
if(SDA)
{
ddata|=0x01;
}
}
SCL=0;
return ddata;
}
/******写SD2400允许程序******/
static void WriteTimeOn(void)
{
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x10);//设置写地址10H
I2CWaitAck();
I2CSendByte(0x80);//置WRTC1=1
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x0F);//设置写地址0FH
I2CWaitAck();
I2CSendByte(0x84);//置WRTC2,WRTC3=1
I2CWaitAck();
I2CStop();
}
/******写SD2400禁止程序******/
static void WriteTimeOff(void)
{
I2CStart();
I2CSendByte(0x64);
I2CWaitAck();
I2CSendByte(0x0F);//设置写地址0FH
I2CWaitAck();
I2CSendByte(0x0) ;//置WRTC2,WRTC3=0
I2CWaitAck();
I2CSendByte(0x0) ;//置WRTC1=0(10H地址)
I2CWaitAck();
I2CStop();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -