⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 baset.c

📁 电力系统中的保护装置全部代码
💻 C
字号:
/////////////////////////////////////////////////////////////////////////////////////
//      程序名: BaseTime.c                                                       
//      时间操作子程序
/////////////////////////////////////////////////////////////////////////////////////
#include    "BaseVariable.h"
#include    "menu_task.h"

Clock       DS1302Time;
TimeSTRU    SoftTime;
UNSIGNED    pSoftTime = (UNSIGNED)&SoftTime;
UNSIGNED    TimeIndex;
UNSIGNED    DS1302WriteEN = 1;
UNSIGNED    Month_Day_Tab[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};  //每月的天数,
UNSIGNED    SoftCLK[6];                          //当前时间:年、月、日、时、分、秒
       
VOID    Time_Initialize(VOID);
VOID    READ_DEC_TIME(UNSIGNED *);
VOID    DS1302BurstRead(UNSIGNED SourceCode, UNSIGNED *pDestination, UNSIGNED Length);
VOID    DS1302BurstWrite(UNSIGNED DestinationCode, UNSIGNED *pSource, UNSIGNED Length);

#define SetSCLK()       *pSerialPort0XCTRL |= 0x4
#define ClrSCLK()       *pSerialPort0XCTRL &= 0xffb
#define SetSDATA()      *pSerialPort0XCTRL |= 0x40
#define ClrSDATA()      *pSerialPort0XCTRL &= 0xfbf
#define SetSRST()       *pSerialPort0XCTRL |= 0x400
#define ClrSRST()       *pSerialPort0XCTRL &= 0xbff
#define DataInMode()    *pSerialPort0XCTRL &= 0xfdf
#define DataOutMode()   *pSerialPort0XCTRL |= 0x20
#define DataDeclare()   *pSerialPort0XCTRL & 0x80

/***********************************************************************************/
/*  延时1us                                                                        */ 
/***********************************************************************************/
VOID    Delay1us(VOID)
{
    register UNSIGNED i = 0;
    while(i++ <= 10);
}

/***********************************************************************************/
/*  写入DS1302一个字节                                                             */ 
/***********************************************************************************/
VOID    DS1302WriteByte(UNSIGNED idata)
{
    register UNSIGNED  i;
    register UNSIGNED  *pSerialPort0XCTRL = (UNSIGNED *)0x808042;

    for(i = 0; i <= 7; i++, idata >>= 1)
    {

        if(idata & 0x1)               //写数据SDATA
        SetSDATA();
        else
        ClrSDATA();
        
        ClrSCLK();                    //SCLK清0
        
        Delay1us();

        SetSCLK();                    //SCLK置1,形成上升沿,数据写入DS1302        

        Delay1us();
    }
}

/***********************************************************************************/
/*  读出DS1302一个字节                                                             */ 
/***********************************************************************************/
UNSIGNED DS1302ReadByte(VOID)
{
    register UNSIGNED  i,j = 0;
    register UNSIGNED  *pSerialPort0XCTRL = (UNSIGNED *)0x808042;

    for(i = 0; i <= 7; i++)
    {
        j >>= 1;

        ClrSCLK();                    //SCLK清0,数据读出DS1302
        Delay1us();
        
        if(DataDeclare())             //判断SDATA
        j |= 0x80;

        SetSCLK();                    //SCLK置1,准备读下一位
        Delay1us();
    }
    
    return(j);
}

/***********************************************************************************/
/*  读出DS1302时间                                                                 */ 
/***********************************************************************************/
VOID    DS1302BurstRead(UNSIGNED SourceCode, UNSIGNED *pDestination, UNSIGNED Length)
{
    register UNSIGNED  i;
    register UNSIGNED  *pSerialPort0XCTRL = (UNSIGNED *)0x808042;

    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,初始值为0
    Delay1us();

    SetSRST();                        //RST置1,允许操作DS1302
    Delay1us();
    Delay1us();

    DS1302WriteByte(SourceCode);      //burst方式读DS1302

    DataInMode();                     //DSP口线设置为输入方式
     
    for(i = 0; i < Length; i ++)
    *pDestination++ = DS1302ReadByte();
     
    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,值为0
}

/***********************************************************************************/
/*  写入DS1302时间                                                                 */ 
/***********************************************************************************/
VOID    DS1302BurstWrite(UNSIGNED DestinationCode, UNSIGNED *pSource, UNSIGNED Length)
{
    static   UNSIGNED    uDS1302_use;

    register UNSIGNED    *p = pSource, i;
    register UNSIGNED    *pSerialPort0XCTRL = (UNSIGNED *)0x808042;
        
    while(uDS1302_use);
    uDS1302_use = 1;
    
    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,值为0
    Delay1us();
    SetSRST();                        //RST置1,允许操作DS1302
    Delay1us();
    Delay1us();

    DS1302WriteByte(0x8e);            //清DS1302写保护WP位
    DS1302WriteByte(0x0);

    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,值为0
    Delay1us();
    SetSRST();                        //RST置1,允许操作DS1302
    Delay1us();
    Delay1us();

    DS1302WriteByte(DestinationCode); //burst方式写DS1302

    for(i = 0; i < Length; i ++) DS1302WriteByte(*p++);
     
    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,值为0
    Delay1us();
    SetSRST();                        //RST置1,允许操作DS1302
    Delay1us();
    Delay1us();

    DS1302WriteByte(0x8e);            //置DS1302写保护WP位
    DS1302WriteByte(0x80);

    *pSerialPort0XCTRL = 0x222;       //DSP口线设置为输出方式,值为0
        
    uDS1302_use = 0;
}

/***********************************************************************************/
/*  将时间从DS1644读入内部采样区                                                   */ 
/***********************************************************************************/
VOID    Time_Initialize(VOID)
{    
    register Clock     *p = &DS1302Time;
    register UNSIGNED  *pp = SoftCLK;
    register UNSIGNED  i;
     
    DS1302BurstRead(0xbf, (UNSIGNED *)p, sizeof(Clock));  //读时间

    if((p->sec & 0x80) || (p->hour & 0x80))
    {
        p->sec &= 0x7f;
        p->hour &= 0x7f;
        DS1302BurstWrite(0xbe, (UNSIGNED *)p, sizeof(Clock));
    }
     
    //将时分秒合成一字节,用毫秒数表示
    *pp++ = (p->year >> 4) * 10 + (p->year & 0x0f);
    *pp++ = (p->month >> 4)* 10 + (p->month & 0x0f);
    *pp++ = (p->date >> 4) * 10 + (p->date & 0x0f);
    *pp++ = (p->hour >> 4) * 10 + (p->hour & 0x0f);
    *pp++ = (p->min >> 4) * 10 + (p->min & 0x0f);
    *pp++ = 1000 * ((p->sec >> 4) * 10 + (p->sec & 0x0f));

}                          

/***********************************************************************************/
/*      读当前时间                                                                 */ 
/***********************************************************************************/
VOID    READ_DEC_TIME(UNSIGNED *pDST)
{
    register UNSIGNED  i,j;
    register UNSIGNED  *p;    
    register UNSIGNED  *pp;
     
    do
    {
        p = pDST;
        pp = SoftCLK;
        j = TMD_System_Clock;
                
        i = 0;
        do
        {
            *p++ = *pp++;
        }while(++i < 6);
    }while(j != TMD_System_Clock);
}


/***********************************************************************************/
/*      校时                                                           */ 
/***********************************************************************************/
VOID    Set_Rtc_Time(CLOCK *pCLOCK)
{
    static   UNSIGNED  uSetRtc;
    
    UNSIGNED k;
    
    register UNSIGNED  i,j;
    register UNSIGNED  *pp = SoftCLK;
    register Clock     *pDS = &DS1302Time;
    register CLOCK     *p = pCLOCK;
    register OPTION    old_preempt;

    old_preempt = NU_Change_Preemption(NU_NO_PREEMPT);    //不再切换任务,避免被其他任务打断,造成误动

    IE &= ~INTT1MASK;

    *pp++ = p->year_;
    *pp++ = p->month_;
    *pp++ = p->day_;
    *pp++ = p->hour_;
    *pp++ = p->minute_;
    *pp++ = p->second_ * 1000;

    IE |= INTT1MASK;

    pDS->sec = ((p->second_ / 10) << 4) + (p->second_ % 10);          
  
    //分
    pDS->min = ((p->minute_ / 10) << 4) + (p->minute_ % 10);
  
    //时
    pDS->hour = ((p->hour_ / 10) << 4) + (p->hour_ % 10);
  
    //日
    pDS->date = ((p->day_ / 10) << 4) + (p->day_ % 10);
  
    //月
    pDS->month = ((p->month_ / 10) << 4) + (p->month_ % 10);
  
    //年
    pDS->year = ((p->year_ / 10) << 4) + (p->year_ % 10);

    k = SAVE_TIME;
    NU_Send_To_Queue(&SaveQueue,&k,1,NU_SUSPEND);
    NU_Change_Preemption(old_preempt);                    //可以切换任务
}                                                                                         
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -