c51为啥要宏定义时钟_C51 DS1302实时时钟的应用(2-26)

本文档介绍了C51单片机如何进行宏定义时钟频率,并详细展示了DS1302实时时钟的初始化函数和读写函数。通过DS1302的CE、DIO和SCK引脚操作,实现了与DS1302的通信,以便读取和设置时钟信息。
摘要由CSDN通过智能技术生成

#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;

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值