#include
#define FOSC 12000000 //--- 宏定义时钟频率 ---
//=================================================================================================
//--- DS1302实时时钟芯片相关的定义与函数声明区 ---
sbit DS1302CE = P1^3; //--- DS1302器件的CE引脚的定义 ---
sbit DS1302IO = P1^5; //--- DS1302器件的DIO引脚的定义 ---
sbit DS1302CK = P1^4; //--- DS1302器件的SCK引脚的定义 ---
void Init_DS1302_RTC(void) //--- DS1302器件初始化函数 ---
{
DS1302CE = 0;
DS1302CK = 0;
DS1302IO = 1;
}
//void Init_DS1302_RTC(void)
//{
// DS1302CE = 0;
// DS1302CK = 0;
// DS1302IO = 1;
//}
unsigned char Read_DS1302_RTC(unsigned char RTC_Address)
{
unsigned char i;
unsigned char temp;
DS1302CK = 0;
DS1302CE = 1;
//--- 向DS1302器件发送要读的地址信息 ---
for(i=8;i>0;i--)
{
if(RTC_Address & 0x01)DS1302IO = 1;
else DS1302IO = 0;
RTC_Address >>= 1;
DS1302CK = 1;
DS1302CK = 0;
}
//--- 从该地址单元中读出时钟信息 ---
temp = 0;
if(DS1302IO == 1)temp += 0x80;
for(i=7;i>0;i--)
{
temp >>= 1;
DS1302CK = 1;
DS1302CK = 0;
if(DS1302IO == 1)temp += 0x80;
}
DS1302CE = 0;
return(temp);
}
//unsigned char Read_DS1302_RTC(unsigned char RTC_Address)
//{
// unsigned char i;
// unsigned char temp = 0;
//
// DS1302CK = 1;
// DS1302CK = 0;
//
// for(i=8;i>0;i--)
// {
// if(RTC_Address & 0x01) DS21302IO = 1;
// else DS1302IO = 0;
// RTC_Address >>= 1;
// DS1302CK = 1;
// DS1302CK = 0;
//}
//
// for(i=7;i>0;i--)
// {
// if(DS1302 == 1) Temp |= 0x80;
// temp >>= 1;
// DS1302CK = 1;
// DS1302CK = 0;
//}
//
// DS1302CE = 0;
//
// return (temp);
//}
void Write_DS1302_RTC(unsigned char RTC_Address,unsigned char RTC_Data)
{
unsigned char i;
DS1302CK = 0;
DS1302CE = 1;
//--- 向DS1302器件发送要读的地址信息 ---
for(i=8;i>0;i--)
{
if(RTC_Address & 0x01)DS1302IO = 1;
else DS1302IO = 0;
RTC_Address >>= 1;
DS1302CK = 1;
DS1302CK = 0;
}
//--- 向该地址发送要写的数据信息 ---
for(i=8;i>0;i--)
{
if(RTC_Data & 0x01)DS1302IO = 1;
else DS1302IO = 0;
RTC_Data >>= 1;
DS1302CK = 1;
DS1302CK = 0;
}
DS1302CE = 0;
}
//void Write_DS1302_RTC(unsigned char RTC_Address,unsigned char RTC_Date)
//{
// unsigned char i;
//
// DS1302CK = 0;
// DS1302CE = 1;
//
// for(i=8;i>0;i--)
// {
// if(RTC_Address & 0x01) DS1302IO = 1;
// else DS1302IO = 0;
// RTC_Address >>= 1;
// DS1302CK = 1;
// DS1302CK = 0;
//}
//
// for(i=8;i>0;i--)
// {
// if(RTC_Date & 0x01) DS1302IO = 1;
// else DS1302IO = 0;
// RTC_Date >>= 1;
// DS1302CK = 1;
// DS1302CK = 0;
//}
//
// DS1302CE = 0;
//}
//=================================================================================================
//--- 数码管显示定义与函数声明区 ---
struct LEDSEG_STRUCT //--- 数码管显示驱动结构体声明 ---
{
unsigned char Pointer;
unsigned char Buffer[8];
};
struct TIMER_STRUCT //--- 软定时结构体声明 ---
{
unsigned int Interval;
unsigned char Enable;
};
struct LEDSEG_STRUCT LEDSeg;
struct TIMER_STRUCT Timer1S;
//=================================================================================================
//--- 相关LED显示驱动引脚的宏定义 ---
#define SEGPORT P0
#define DIGPORT P2
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
#define TIMER1MS 1000 //--- 宏定义定时1ms,1000us ---
unsigned char code SEGLED[] = //--- 显示0~9,A~F笔段代码表 ---
{
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0x40,
};
unsigned char code DIGLED[] = //--- 数码管显示的位选通段代码表 ---
{
0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
};
//=================================================================================================
//--- 定时器T0初始化函数 ---
void T0_Init(void)
{
P0M1 = 0x00; //--- 配置P0端口的P0.0~P0.7为推挽输出模式 ---
P0M0 = 0xFF;
P2M1 = 0x00; //--- 配置P2端口的P2.0~P2.7为推挽输出模式 ---
P2M0 = 0xFF;
TMOD = 0x01; //--- 配置T1工作于方式0,T0为定时模式,工作于方式1 ---
TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- 初始化T0定时1mS ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
TR0 = 1; //--- 启动T0工作 ---
ET0 = 1; //--- 使能T0中断 ---
}
//=================================================================================================
//--- 定时器T0溢出中断服务程序 ---
void T0_ISR(void) interrupt 1
{
struct LEDSEG_STRUCT *pLEDSeg;
struct TIMER_STRUCT *pTimer;
TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- 重装T0的定时初值 ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
pLEDSeg = &LEDSeg;
SEGPORT = SEGLED[pLEDSeg->Buffer[pLEDSeg->Pointer]];
DIGPORT = DIGLED[pLEDSeg->Pointer];
if(sizeof(pLEDSeg->Buffer) == ++ pLEDSeg->Pointer)pLEDSeg->Pointer = 0;
pTimer = &Timer1S;
if(0 != pTimer->Enable)
{
pTimer->Interval --;
if(0 == pTimer->Interval) pTimer->Enable = 0;
}
}
//=================================================================================================
//--- 日期时间信息结构体声明与定义区 ---
struct timestruct
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Day;
unsigned char Month;
unsigned char Year;
};
struct timestruct DateTime;
//=================================================================================================
//--- main()主程序区 ---
void main(void)
{
unsigned char temp;
struct LEDSEG_STRUCT *pLEDSeg;
struct TIMER_STRUCT *pTimer;
pLEDSeg = &LEDSeg;
pTimer = &Timer1S;
T0_Init(); //--- 初始化定时器T0 ---
EA = 1; //--- CPU开中断 ---
Init_DS1302_RTC();
//--- 初始化时钟 ---
Write_DS1302_RTC(0x8e,0x00);
Write_DS1302_RTC(0x80,0x00);
Write_DS1302_RTC(0x82,0x55);
Write_DS1302_RTC(0x84,0x11);
Write_DS1302_RTC(0x86,0x16);
Write_DS1302_RTC(0x88,0x11);
Write_DS1302_RTC(0x8a,0x05);
Write_DS1302_RTC(0x8c,0x05);
Write_DS1302_RTC(0x8e,0x80); //--- 启动DS1302运行 ---
temp=Read_DS1302_RTC(0x8f);
pTimer->Interval = 1000; //--- 设置定时1S初始值 ---
pTimer->Enable = 1; //--- 启动定时1S开始 ---
while(1)
{
if(pTimer->Enable == 0) //--- 1秒定时时间到 ---
{
pTimer->Interval = 1000; //--- 设置定时1S初始值 ---
pTimer->Enable = 1; //--- 启动定时1S开始 ---
DateTime.Second = Read_DS1302_RTC(0x81); //--- 读取DS1302秒单元 ---
DateTime.Minute = Read_DS1302_RTC(0x83); //--- 读取DS1302分单元 ---
DateTime.Hour = Read_DS1302_RTC(0x85); //--- 读取DS1302时单元 ---
DateTime.Day = Read_DS1302_RTC(0x87); //--- 读取DS1302日单元 ---
DateTime.Month = Read_DS1302_RTC(0x89); //--- 读取DS1302月单元 ---
DateTime.Year=Read_DS1302_RTC(0x8d); //--- 读取DS1302年单元 ---
pLEDSeg->Buffer[0] = DateTime.Second % 16;//--- 将读取的DS1302的信息送数码管上显示 ---
pLEDSeg->Buffer[1] = DateTime.Second / 16;
pLEDSeg->Buffer[2] = DateTime.Minute % 16;
pLEDSeg->Buffer[3] = DateTime.Minute / 16;
pLEDSeg->Buffer[4] = DateTime.Hour % 16;
pLEDSeg->Buffer[5] = DateTime.Hour / 16;
pLEDSeg->Buffer[6] = DateTime.Day % 16;
pLEDSeg->Buffer[7] = DateTime.Day / 16;
}
}
}