📄 rtc.c
字号:
/******************************************************************
** 文件名: RTC.c
*******************************************************************/
#ifndef MASTER_FILE
#include <include.h>
#endif
#include "bian.h"
/*---------------------------------------------------
调用方式:void I2CStart(void) ﹫2003/06/06
函数说明:私有函数,I2C专用
----------------------------------------------------*/
void I2CStart(void)
{ //启动条件是SCL =1时,SDA出现一个下降沿
SCLKL;
SDAH;
SCLKH;
SomeNOP();
SomeNOP();
SDAL;
SomeNOP(); //START
SomeNOP();
SCLKL;
}
/*--------------------------------------------------
调用方式:void I2CStop(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用
---------------------------------------------------*/
void I2CStop(void)
{ //停止条件:SCL = 1时,SDA出现上升沿
SCLKL;
SDAL;
SomeNOP();
SomeNOP();
SCLKH;
SomeNOP();
SomeNOP();
SDAH;
}
/**------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2003/06/06
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
-----------------------------------------------------------------------*/
void SendAck(void)
{
SDAL; //SDA=0;
SomeNOP();
SCLKH; //SCL=1;
SomeNOP();
SomeNOP();
SCLKL; //SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2003/06/06
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
**----------------------------------------------------------------------------*/
void SendNotAck(void)
{
SDAH; //SDA=1;
SomeNOP();
SCLKH; //SCL=1;
SomeNOP();
SomeNOP();
SCLKL; //SCL=0;
}
//----------------------------------wait ack begin
uchar WaitAck(void)
{
uchar errtime;
errtime = 255;//因故障接收方无ACK,超时值为255。
SDAH; //SDA=1;
SomeNOP();
SCLKH; //SCL=1;
while (SDA)
{
errtime--;
if (!errtime)
{
I2CStop();
return 0;
}
}
SCLKL; //SCL=0;
return TRUE;
}
//----------------------------------wait ack end
/**--------------------------------------------------------------------------------
调用方式:void I2CSendByte(uchar ch) ﹫2003/06/06
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CSendByte(uchar ch)
{
uchar i = 8;
while (i--)
{
SCLKL; //SCL=0;
SomeNOP();
if (ch & 0X80)
{
SDAH;
} // SDA |= 0X20;
else
{
SDAL;
} //SDA &= 0Xdf; //SDA=(bit)(ch&0x80);
ch <<= 1;
SomeNOP();
SCLKH;//SCL=1;
SomeNOP(); //难点之一
SomeNOP();
}
SCLKL;//SCL=0;
}
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit SET_RTC(uchar *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址0X64,子地址FH,0H,1H...EH,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
uchar SET_RTC(uchar* s, uchar no)
{
uchar i;
if(SwitchRTC == NEW_RTC)
{
s[0] = s[1];
s[1] = s[2];
s[2] = s[3];
//星期(0X01-0X07)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
if((s[4]>0) && (s[4]<8)) //(1-7)星期 2004.11.04
s[3] = s[4];
else
s[3] = 1;//s[4];
s[4] = s[5];
s[5] = s[6];
s[6] = s[7];
if(s[0] > 0X59)
return 0;
if(s[1] > 0X59)
return 0;
if(s[2] > 0X23)
return 0;
// if(s[3] > 0X06)
// return 0;
if( (s[4] > 0X31) || (s[4]==0) )
return 0;
if( (s[5] > 0X12) || (s[5]==0) )
return 0;
if(s[6] > 0X49)
return 0;
//--------------
I2CStart(); /*启动总线*/
// I2CSendByte(0X64); /*发送器件地址*/
I2CSendByte(0Xd0); /*发送器件地址*/
if(WaitAck() == 0)
return 0;
//--------------------------
I2CSendByte(0x00); /*发送器件子地址*/
if(WaitAck() == 0)
return 0;
//-----------------
for(i = 0;i < no;i++)
{
I2CSendByte(*s); /*发送数据*/
if(WaitAck() == 0)
return 0;
s++;
}
I2CStop(); /*结束总线*/
return TRUE;
}
else
{
s[0] = 0x20;
//--------------
if(s[1] > 0X59)
return 0;
if(s[2] > 0X59)
return 0;
if(s[3] > 0X23)
return 0;
// if(s[4] > 0X06)
// return 0;
//星期(0X00-0X06)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
if(s[4] > 6) //星期 2004.11.04
s[4] = 0;
if( (s[5] > 0X31) || (s[5]==0) )
return 0;
if( (s[6] > 0X12) || (s[6]==0) )
return 0;
if(s[7] > 0X99)
return 0;
//--------------
I2CStart(); /*启动总线*/
I2CSendByte(0X64); /*发送器件地址*/
if(WaitAck() == 0)
return 0;
//--------------------------
I2CSendByte(0XF0); /*发送器件子地址*/
if(WaitAck() == 0)
return 0;
//-----------------
for(i = 0;i < no;i++)
{
I2CSendByte(*s); /*发送数据*/
if(WaitAck() == 0)
return 0;
s++;
}
I2CStop(); /*结束总线*/
return TRUE;
}
}
/**--------------------------------------------------------------------------------
调用方式:uchar I2CReceive(void) ﹫2003/06/06
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
uchar I2CReceiveByte(void)
{
unsigned char i = 8;
unsigned char ddata = 0;
SDAH;//SDA=1;
while (i--)
{
ddata *= 2;
SCLKL;//SCL=0;
SomeNOP();
SomeNOP();
SCLKH;//SCL=1;
SomeNOP(); //难点之二
SomeNOP();
if (SDA)
{
ddata++;
}
}
SCLKL;//SCL=0;
SomeNOP();
return ddata;
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit READ_RTC(uchar *s,uchar no);
功能: 从启动总线到发送地址(0X65),读数据,结束总线的全过程,
分别从子地址FH,0H,1H...EH读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
uchar READ_RTC(uchar* s, uchar no)
{
uchar i;
uchar xdata* sss;
if(SwitchRTC == NEW_RTC)
{
I2CStart(); /*启动总线*/
I2CSendByte(0Xd0); /*发送器件子地址*/
if(WaitAck() == 0)
return 0;
I2CSendByte(0X0); /*发送REG地址*/
if(WaitAck() == 0)
return 0;
I2CStart();
I2CSendByte(0Xd1); /*发送器件地址*/
if(WaitAck() == 0)
return 0;
//---------------------------------------
for (i = 0; i < no; i++)
{
*s = I2CReceiveByte(); /*接收数据*/
if (i != (no - 1))
{
SendAck();
}
s++;
}
SendNotAck();
I2CStop(); /*结束总线*/
sss = (uchar *) (s - no);
return TRUE;
}
else
{
I2CStart(); /*启动总线*/
I2CSendByte(0x65); /*发送器件子地址*/
if(WaitAck() == 0)
return 0;
//---------------------------------------
for(i=0;i<no;i++)
{
*s = I2CReceiveByte(); /*接收数据*/
if(i != (no - 1))
SendAck();
s++;
}
SendNotAck();
I2CStop(); /*结束总线*/
sss = (uchar *)(s-no);
return TRUE;
}
}
/***********************************************************************************
*** 函 数 名: uchar RtcTask(void)
*** 功能描述:读取RTC
*** 参 数: 输入: 无
*** 输出: 无
*** 功能模块:
*** 返 回 值: 1.TRUE :正确读取RTC
2.FALSE :错误读取RTC
*** 模块信息:
*************************************************************************************/
uchar RtcTask(void)
{
if(SwitchRTC == NEW_RTC)
{
if (READ_RTC(MRD, 7))
{
MRD[7] = MRD[6]; //年
MRD[6] = MRD[5];
MRD[6] &= 0x1f; //月
MRD[5] = MRD[4];
MRD[5] &= 0x3f; //日期
MRD[4] = MRD[3];
MRD[4] &= 0x07; //星期
MRD[4] -= 1;
MRD[3] = MRD[2];
MRD[3] &= 0x3f; //小时
MRD[2] = MRD[1];
MRD[2] &= 0x7f; //分钟
MRD[1] = MRD[0];
MRD[1] &= 0x7f; //秒
bufTime[0] = 0x32;
bufTime[1] = 0x30;
bufTime[2] = 0x30 +(MRD[7]>>4);
bufTime[3] = 0x30 +(MRD[7]&0x0f);
bufTime[4] = 0x30 +(MRD[6]>>4);
bufTime[5] = 0x30 +(MRD[6]&0x0f);
bufTime[6] = 0x30 + (MRD[5]>>4);
bufTime[7] = 0x30 +(MRD[5]&0x0f);
bufTime[8] = 0x30+(MRD[3]>>4);
bufTime[9] = 0x30+(MRD[3]&0x0f);
bufTime[10] = 0x30+(MRD[2]>>4);
bufTime[11] = 0x30+(MRD[2]&0x0f);
bufTime[12] = 0x30+(MRD[1]>>4);
bufTime[13] = 0x30+(MRD[1]&0x0f);
//星期(0X01-0X07)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
bufTime[14] = 0x30+(MRD[4]>>4); //星期 2004.11.04
bufTime[15] = 0x30+(MRD[4]&0x0f);
return(TRUE);
}
else //读取不正确的相应处理
{
return(FALSE);
}
}
else
{
if(READ_RTC(MRD,8))
{
bufTime[0] = '2';
bufTime[1] = '0';
bufTime[2] = 0x30 +(MRD[7]>>4);
bufTime[3] = 0x30 +(MRD[7]&0x0f);
bufTime[4] = 0x30 +(MRD[6]>>4);
bufTime[5] = 0x30 +(MRD[6]&0x0f);
bufTime[6] = 0x30 + (MRD[5]>>4);
bufTime[7] = 0x30 +(MRD[5]&0x0f);
bufTime[8] = 0x30+(MRD[3]>>4);
bufTime[9] = 0x30+(MRD[3]&0x0f);
bufTime[10] = 0x30+(MRD[2]>>4);
bufTime[11] = 0x30+(MRD[2]&0x0f);
bufTime[12] = 0x30+(MRD[1]>>4);
bufTime[13] = 0x30+(MRD[1]&0x0f);
//星期(0X00-0X06)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
bufTime[14] = 0x30+(MRD[4]>>4); //星期 2004.11.04
bufTime[15] = 0x30+(MRD[5]&0x0f);
return(TRUE);
}
else //读取不正确的相应处理
{
return(FALSE);
}
}
}
/***********************************************************************************
*** 函 数 名: uchar WriteRtc(void)
*** 功能描述:设置RTC
*** 参 数: 输入: 无
*** 输出: 无
*** 功能模块:
*** 返 回 值: 1.TRUE :正确设置RTC
2.FALSE :错误设置RTC
*** 模块信息:
*************************************************************************************/
uchar WriteRtc(void)
{
uchar j;
if(SwitchRTC == NEW_RTC)
{
j = 7;
}
else
{
j = 8;
}
if (SET_RTC(MTD, j))
{
return TRUE;
}
else
{
return FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -