微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 有没有人用过SD2400时钟芯片,用它来做一个倒计时控制

有没有人用过SD2400时钟芯片,用它来做一个倒计时控制

时间:10-02 整理:3721RD 点击:
有没有人用过SD2400时钟芯片,我想用它来做一个倒计时,控制继电器进行相应的动作。谁能写个小程序给我示例一下,SD2400的头文件如下所示:
#ifndef __Sd2400_H__
#define __Sd2400_H__
#pragma SAVE
#pragma REGPARMS
#define                RTC_Address                        0x64//RTC器件地址
#define                true                          1
#define         false                         0
//*********变量及IO口定义*********
sbit        SDA=P2^0;                 //
sbit        SCL=P2^1;                //

typedef        struct
{
        unsigned char         second;
        unsigned char        minute;
        unsigned char        hour;
        unsigned char        week;
        unsigned char        day;
        unsigned char        month;
        unsigned char        year;
}S_Time;
       

/********SD24XX函数名********/
extern unsigned char I2CReadOneByte(unsigned char DeviceAddress,unsigned char add);//读一字节
extern bit I2CWriteOneByte(unsigned char DeviceAddress,unsigned char add, unsigned char date);//写一字节
//extern uchar I2CReadSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps);//连续读
//extern uchar I2CWriteSerial(uchar DeviceAddress, uchar Address, uchar length,uchar *ps);//连续写
extern bit I2CWriteDate(S_Time        SetRTC);//写时间,以S_Time结构体的形式初始化时间值       
extern bit I2CReadDate(S_Time        *psRTC);//读时间,以S_Time结构体的形式读取
extern bit        WriteTimeOn(void);//写允许
extern bit        WriteTimeOff(void);//写禁止
//void Delay(uint nn);
/*********I2C延时4us***********/
void I2CWait(void)//4us
{       
        //_nop_();_nop_();_nop_();_nop_();//AT89S52一个nop是1us
        unsigned char i=12;
        while(--i);
}
/********开启SD24XX的I2C总线********/
bit I2CStart(void)
{
        SDA=1;
        SCL=1;
        I2CWait();
        if(!SDA)return false;        //SDA线为低电平则总线忙,退出
        SDA=0;
        I2CWait();
        while(SDA)return false;        //SDA线为高电平则总线出错,退出
        SCL=0;
        I2CWait();
        return true;
}
/********关闭SD24XX的I2C总线*******/
void I2CStop(void)
{
        SDA=0;
        SCL=0;
        I2CWait();
        SCL=1;
        I2CWait();
        SDA=1;
}
/*********发送 ACK*********/
void I2CAck(void)
{       
        SDA=0;
        SCL=0;
        I2CWait();
        SCL=1;
        I2CWait();
        SCL=0;
}
/*********发送NO ACK*********/
void I2CNoAck(void)
{       
        SDA=1;
        SCL=0;
        I2CWait();
        SCL=1;
        I2CWait();
        SCL=0;
}
/*********读取ACK信号*********/
bit I2CWaitAck(void)          //返回为:1=有ACK,0=无ACK
{
        SCL=0;
        SDA=1;                //设置SDA为输入(其它类型的单片机需要配置IO输入输出寄存器)
        I2CWait();
        SCL=1;
        I2CWait();
        while(SDA)
        {
                SCL=0;
                return false;
        }
        SCL=0;
        return true;
}
/************MCU向SD24XX发送一个字节*************/
void I2CSendByte(unsigned char demand) //数据从高位到低位//
{
unsigned char i=8;                       
                                        
       
        while(i--)
        {
                SCL=0;
                _nop_();
                SDA=(bit)(demand&0x80);
                demand<<=1;
                I2CWait();
                SCL=1;
                I2CWait();
        }
        SCL=0;
}
/*********MCU从SD24XX读入一字节*********/
unsigned char I2CReceiveByte(void)      //数据从高位到低位//
{
unsigned char i=8;
unsigned char ddata=0;
        SDA=1;                        //设置SDA为输入(其它类型的单片机需要配置IO输入输出寄存器)
        while(i--)
        {
                ddata<<=1;      //数据从高位开始读取
                SCL=0;
                I2CWait();
                SCL=1;
                I2CWait();        //从高位开始 ddata|=SDA;ddata<<=1
                if(SDA)
                {
                        ddata|=0x01;
                }
        }
        SCL=0;
        return ddata;
}
/******I2C写一个字节******/
bit I2CWriteOneByte(unsigned char DeviceAddress,unsigned char add, unsigned char date)
{               
        if(!I2CStart())return false;
        I2CSendByte(DeviceAddress);      
        I2CWaitAck();   
        I2CSendByte(add);                //设置写地址      
        I2CWaitAck();       
        I2CSendByte(date);                //写数据
        I2CWaitAck();       
        I2CStop();
        return        true;
}
/******I2C读一个字节程序******/
unsigned char I2CReadOneByte(unsigned char DeviceAddress,unsigned char add)
{               
        unsigned char dat;
        if(!I2CStart())return false;
        I2CSendByte(DeviceAddress);      
        if(!I2CWaitAck()){I2CStop(); return false;}
          I2CSendByte(add);                //设置要读的地址
        I2CWaitAck();
        I2CStart();       
        I2CSendByte(DeviceAddress+1);       
        I2CWaitAck();       
        dat=I2CReceiveByte();                //读数据
        I2CNoAck();
        I2CStop();
        return  dat;
}
/******写SD24XX允许程序******/
bit WriteTimeOn(void)
{               
        if(!I2CWriteOneByte(RTC_Address,0x10,0x80))return false;
        I2CWriteOneByte(RTC_Address,0x0f,0x84);
        return        true;
}
/******写SD24XX禁止程序******/
bit WriteTimeOff(void)
{               
        if(!I2CWriteOneByte(RTC_Address,0x0f,0))return false;
        I2CWriteOneByte(RTC_Address,0x10,0);
        return        true;
}
/******读SD24XX实时数据寄存器******/
bit I2CReadDate(S_Time        *psRTC)
{
       
        if(!I2CStart())return false;
        I2CSendByte(RTC_Address+1);
    if(!I2CWaitAck()){I2CStop(); return false;}
        psRTC->second=I2CReceiveByte();
        I2CAck();
        psRTC->minute=I2CReceiveByte();
        I2CAck();
        psRTC->hour=I2CReceiveByte();
        I2CAck();
        psRTC->week=I2CReceiveByte();
        I2CAck();
        psRTC->day=I2CReceiveByte();
        I2CAck();
        psRTC->month=I2CReceiveByte();
        I2CAck();
        psRTC->year=I2CReceiveByte();
        I2CNoAck();                //读时间完成,发送NoAck
        I2CStop();
        return        true;
}
/******写SD24XX实时数据寄存器******/
bit I2CWriteDate(S_Time        SetRTC)        //写时间操作要求一次对实时时间寄存器(00H~06H)依次写入,
{                               //不可以单独对7个时间数据中的某一位进行写操作,否则可能会引起时间数据的错误进位.
                                //要修改其中某一个数据 , 应一次性写入全部 7 个实时时钟数据.
        S_Time         *psRTC;
    psRTC=&SetRTC;
        WriteTimeOn();                                //使能,开锁
        if(!I2CStart())return false;
        I2CSendByte(RTC_Address);
        if(!I2CWaitAck()){I2CStop(); return false;}
        I2CSendByte(0x00);                        //设置写起始地址      
        I2CWaitAck();       
        I2CSendByte(psRTC->second);                //second     
        I2CWaitAck();       
        I2CSendByte(psRTC->minute);                //minute      
        I2CWaitAck();       
        I2CSendByte(psRTC->hour|0x80);                //hour ,同时设置小时寄存器最高位(0:为12小时制,1:为24小时制)
        I2CWaitAck();       
        I2CSendByte(psRTC->week);                //week      
        I2CWaitAck();       
        I2CSendByte(psRTC->day);                //day      
        I2CWaitAck();       
        I2CSendByte(psRTC->month);                //month      
        I2CWaitAck();       
        I2CSendByte(psRTC->year);                //year      
        I2CWaitAck();       
        I2CStop();
       
        WriteTimeOff();                                //使能,关锁
        return        true;
}

/******设置SD24XX报警中断演示程序演示******/
void WriteALARM(void)                                //设置报警时间:2015年2月14日 8:00
{                                                //只有设置未来的时间才有效
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x09,0x08);        //8时
        I2CWriteOneByte(RTC_Address,0x0b,0x14);        //14日
        I2CWriteOneByte(RTC_Address,0x0c,0x02);        //02月
        I2CWriteOneByte(RTC_Address,0x0d,0x15);        //15年
        I2CWriteOneByte(RTC_Address,0x0e,0x74);        //设置报警允许(使能年、月、日、小时报警)
        I2CWriteOneByte(RTC_Address,0x10,0x92);        //设置INT中断选通(INTS1,INTS0),及报警中断总允许位(INTAE)
        WriteTimeOff();
}
/******关闭SD24XX报警中断程序******/
void ClrALARM(void)                                                        //关闭报警中断
{
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x10,0x90);
        WriteTimeOff();
}
/******设置SD24XX倒计时中断演示******/
void SetDjs(void)                                                        //设置倒计时中断
{
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x10,0x0f);//先清倒计时中断总允许位(INTDE)
        I2CWriteOneByte(RTC_Address,0x10,0xf4);//设置周期性中断(IM=1)INT中断选通(INTS1,INTS0),配置倒计时中断总允许位(INTDE)
        I2CWriteOneByte(RTC_Address,0x11,0x30);//选择定时器频率源(TDS1、TDS0)为1/60HZ
        I2CWriteOneByte(RTC_Address,0x13,0x05);//倒计时初值寄存器,设置8位倒计时计数初值(5min)
        WriteTimeOff();
}
/******关闭SD24XX倒计时中断程序******/
void ClrDjs(void)         
{
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x10,0xf0);
        WriteTimeOff();
}
/******设置SD24XX频率中断演示******/
void SetFrq(void)                                       
{
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x10,0xa1);        //选通频率中断(INTS1,INTS0),设置频率中断总允许位(INTFE)
        I2CWriteOneByte(RTC_Address,0x11,0x09);        //设置2Hz频率中断
        WriteTimeOff();
}
/******关闭SD24XX频率中断******/
void ClrFrq(void)         
{
        WriteTimeOn();
        I2CWriteOneByte(RTC_Address,0x10,0xa0);
        WriteTimeOff();
}


#pragma RESTORE
#endif

大哥了,谁看看会的话跪求啊

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top