📄 rtc.c
字号:
/****************************************Copyright (c)************************************************
**
**
**
**
**----------------------------------------------------------------------------------------------------
名称:RTC.C
功能:DS1302实时时钟
作者:Albert
日期:2004-12-10
说明:调用System.h中DateTimeType
*****************************************************************************************************/
#include "string.h"
#include "config.h"
#include "System.h" //调用DateTimeType时钟结构体
#include "Message.h"
#include "RTC.h"
#include "Terminal.h"
#include "Display.h"
#include "Sample.h"
#include "SlaveMain.h"
extern uint8 OldSystemTimeMin; //产生1MIN时间消息暂存变量
extern void InitNoPowerTime(void); //获取终端停电时间
/**************************************************
名称: 外部函数定义
**************************************************/
#define RTCSCL_H IO1SET = RTCSCL
#define RTCSCL_L IO1CLR = RTCSCL
#define RTCSDA_H IO1SET = RTCSDA
#define RTCSDA_L IO1CLR = RTCSDA
uint8 RtcInitTime; //初始化时钟时间
uint8 RtcInitFlag; //初始化时钟标志
uint8 RtcCmpTime; //RTC时间比较
uint8 SystemClockOKFlag; //系统时钟正常标志
uint8 RtcSetClockTime;
uint8 RtcSetClockFlag; //时钟设置标志
uint8 monthday[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //公历每月的天数
#ifndef _ISL12022_
/****************************************************************************
* 名 称: RTCWait()
* 功 能: 时钟延时等待
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCWait(void)
{
uint16 i;
for(i=0;i<20;i++);
}
/****************************************************************************
* 名 称: RTCStart()
* 功 能: 启动
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCStart(void)
{
RTCSDA_H;
RTCWait();
RTCSCL_H;
RTCWait();
RTCSDA_L;
RTCWait();
RTCSCL_L;
RTCWait();
return;
}
/****************************************************************************
* 名 称: RTCStop()
* 功 能: 停止
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCStop(void)
{
RTCSDA_L;
RTCWait();
RTCSCL_H;
RTCWait();
RTCSDA_H;
RTCWait();
return;
}
/****************************************************************************
* 名 称: RTCAck()
* 功 能: 正确应答
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCAck(void)
{
RTCSDA_L;
RTCWait();
RTCSCL_H;
RTCWait();
RTCSCL_L;
RTCWait();
return;
}
/****************************************************************************
* 名 称: RTCNoAck()
* 功 能: 否认应答
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCNoAck(void)
{
RTCSDA_H;
RTCWait();
RTCSCL_H;
RTCWait();
RTCSCL_L;
RTCWait();
return;
}
/****************************************************************************
* 名 称: RTCWbyte()
* 功 能: 写一个字节
* 入口参数:
* 出口参数:
****************************************************************************/
void RTCWbyte(uint8 btow)
{
uint8 i;
for(i=0;i<8;i++)
{
if(btow & 0x80)
RTCSDA_H;
else
RTCSDA_L;
RTCWait();
RTCSCL_H;
RTCWait();
RTCSCL_L;
btow<<=1;
}
}
/****************************************************************************
* 名 称: RTCWait()
* 功 能: 读一个字节
* 入口参数:
* 出口参数:
****************************************************************************/
uint8 RTCRbyte(void)
{
uint8 i;
uint8 temp=0;
for(i=0;i<8;i++)
{
RTCSDA_H;
RTCWait();
RTCSCL_H;
RTCWait();
IO1DIR &= ~RTCSDA;
if(IO1PIN & RTCSDA)
temp|=0x01;
IO1DIR |= RTCSDA;
if(i<7)
temp<<=1;
RTCSCL_L;
RTCWait();
}
return (temp);
}
/****************************************************************************
* 名 称: RTC_SetClockData()
* 功 能: 设置RTC初始时钟
* 入口参数: *pClock:初始时钟数据地址 S M H D M W Y C(7Byte BCD码 + 1控制字)
* 出口参数:
****************************************************************************/
void RTC_SetClockData(DateTimeType *pClock)
{
RTCStart();
RTCWbyte(0xD0);
RTCAck();
RTCWbyte(0x00);
RTCAck();
RTCWbyte(0x00);
RTCAck();
RTCWbyte(pClock->second);
RTCAck();
RTCWbyte(pClock->minute);
RTCAck();
RTCWbyte(pClock->hour);
RTCAck();
RTCWbyte(pClock->week);
RTCAck();
RTCWbyte(pClock->day);
RTCAck();
RTCWbyte(pClock->month);
RTCAck();
RTCWbyte(pClock->year);
RTCAck();
RTCStop();
return;
}
/****************************************************************************
* 名 称: RTC_GetData()
* 功 能: 获取RTC数据
* 入口参数:
* 出口参数:
****************************************************************************/
void RTC_GetData(uint8 *timep)
{
uint8 i;
RTCStart();
RTCWbyte(0xD0);
RTCAck();
RTCWbyte(0x00);
RTCAck();
RTCStart();
RTCWbyte(0xD1);
RTCAck();
for(i=0;i<0x13;i++)
{
*timep=RTCRbyte();
RTCAck();
timep++;
}
*timep = RTCRbyte();
RTCNoAck();
RTCStop();
return;
}
/****************************************************************************
* 名 称: RTC_GetClockData()
* 功 能: 获取RTC的当前时间 S M H D M W Y (7Byte BCD码)
* 入口参数: *pClock:读取当前时间存储区
* 出口参数:
****************************************************************************/
void RTC_GetClockData(DateTimeType *pClock)
{
uint8 tim[0x13];
memset((uint8 *)&tim[0],0,0x13);
RTC_GetData(tim);
pClock->second = tim[1];
pClock->minute = tim[2];
pClock->hour = tim[3];
pClock->week = tim[4];
pClock->day = tim[5];
pClock->month = tim[6];
pClock->year = tim[7];
}
/****************************************************************************
* 名 称: InitRTC()
* 功 能: 初始化
* 入口参数:
* 出口参数:
****************************************************************************/
void InitRTC(void)
{
RTCStart();
RTCWbyte(0xD0);
RTCAck();
RTCWbyte(0x0c);
RTCAck();
RTCWbyte(0x00);
RTCAck();
RTCStop();
RTCStart();
RTCWbyte(0xD0);
RTCAck();
RTCWbyte(0x13); //1s方波
RTCAck();
RTCWbyte(0xf0);
RTCAck();
RTCStop();
RTCStart();
RTCWbyte(0xD0);
RTCAck();
RTCWbyte(0x0a); //启动方波输出
RTCAck();
RTCWbyte(0x41); //
RTCAck();
RTCStop();
return;
}
/****************************************************************************
* 名 称: Init_RTC()
* 功 能: 初始化RTC
* 入口参数:
* 出口参数:
****************************************************************************/
void RTC_Init(void)
{
uint8 week1=0;
uint8 flag = 0;
uint8 i;
IO1DIR |= RTCSDA;
IO1DIR |= RTCSCL;
for(i=0;i<3;i++)
{
InitRTC();
RTC_GetClockData(&SysDateTime);
if(Bcd2Byte(SysDateTime.year) < 0x05)
flag = 1;
if((Bcd2Byte(SysDateTime.month) < 1)||(Bcd2Byte(SysDateTime.month) > 12))
flag = 1;
if((Bcd2Byte(SysDateTime.day) < 1)||(Bcd2Byte(SysDateTime.day) > 31))
flag = 1;
if(Bcd2Byte(SysDateTime.hour) > 23)
flag = 1;
if(Bcd2Byte(SysDateTime.minute) > 59)
flag = 1;
if(Bcd2Byte(SysDateTime.second) > 59)
flag = 1;
if(flag == 0)
break;
}
if(flag == 1)
{
SysDateTime.year = 0x07;
SysDateTime.month = 0x01;
SysDateTime.day = 0x01;
SysDateTime.hour = 0x00;
SysDateTime.minute = 0x00;
SysDateTime.second = 0x00;
RtcSetClockFlag = VALID_FLAG;
}
week1 = GetWeek(SysDateTime.year,SysDateTime.month,SysDateTime.day);
if((SysDateTime.week != week1)||(SysDateTime.second & 0x80)||(flag == 1))
{
SysDateTime.week = week1;
SysDateTime.second &= 0x7f;
RTC_SetClockData(&SysDateTime);
InitRTC();
}
DisplayTime(0,11,(DateTimeType *)&SysDateTime);
}
/****************************************************************************
* 名 称: Init_Clock()
* 功 能: 初始化时钟
* 入口参数:
* 出口参数:
****************************************************************************/
void Init_Clock(DateTimeType *pDateTime)
{
DateTimeType gDateTime;
gDateTime.year = pDateTime->year;
gDateTime.month = pDateTime->month;
gDateTime.day = pDateTime->day;
gDateTime.hour = pDateTime->hour;
gDateTime.minute = pDateTime->minute;
gDateTime.second = pDateTime->second;
gDateTime.week = SysDateTime.week;
gDateTime.week = GetWeek(gDateTime.year,gDateTime.month,gDateTime.day);
RTC_SetClockData(&gDateTime);
InitRTC();
}
#else
///////////////////////////////////////////////////////////////////
#include "eeprom.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -