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

📄 ds1337.c

📁 这是ep9315单板计算机的ds1337的驱动程序源代码
💻 C
字号:
//************************************************************************
//                                                                      
// Filename: DS1337.c
//                                                                      
// Copyright(c) Cirrus Logic Corporation 2004, All Rights Reserved                       
//
// Author: YUJIANG.ZHENG@CIRRUS.BEIJING
//
// TODOTODOTODO: Replace all while{} with timeout function.
//
//************************************************************************

#include "ds1337.h"

unsigned long ds1337_bias=0;
unsigned long ds1337_current_sec=0;

static volatile GPIOG * const gpio_g       = (GPIOG *)(GPIO_BASE + 0x0038);

#define PERIOD_US_100HZ             10
#define DELAY_US                    (PERIOD_US_100HZ/2)

void gen_ack(int not_ack);
int wait_ack(void);

/*
 *  Delay Function. 
 */
void DelayInuSec(unsigned long uS)
{
    unsigned long passed, startTime;

    startTime= *TIM_DEBUGVALUELOW;
    passed=0;
    
    while ( passed < uS) 
    {
       passed = (*TIM_DEBUGVALUELOW - startTime);
    }
}

/*
 *  Write the registers of DS1337, 
 */
int write_ds1337(int address,const char* pdata, int nbytes)
{
    int i,j;

    //
    //  Wait for bus not busy.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =0;
    while( !(gpio_g->PGDR.Value & 0x3) ){}

    //
    //  Start Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 0;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}


    //
    //  Send DS1337 Slave Address For Write.
    //
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((WRITE_ADDRESS>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) goto w_failed;
    gpio_g->PGDDR.Field.EEDATA =1;

    //
    //  Set The Register Pointer.
    //
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((address>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) goto w_failed;
    gpio_g->PGDDR.Field.EEDATA =1;

    //
    //  Write Bytes To DS1337.
    //
    j=0;
    while(nbytes--)
    {
        for(i=0;i<8;i++)
        {
            gpio_g->PGDR.Field.EEDATA = ((pdata[j]>>(7-i))&0x01);
            gpio_g->PGDR.Field.EECLK = 1;
            DelayInuSec(DELAY_US);
            gpio_g->PGDR.Field.EECLK = 0;
            DelayInuSec(DELAY_US);
        }
        if(! wait_ack ()) goto w_failed;
        gpio_g->PGDDR.Field.EEDATA =1;
        j++;
    }

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return 0;

w_failed:

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return -1;
}

/*
 *  Read the registers of DS1337, 
 */

int read_ds1337(int address,char* pdata, int nbytes)
{

    int i,j;
    char udata;

    //
    //  Set regsitor pointer.
    //
    if( write_ds1337(address, (void*)0, 0) <0) return -1;

    //
    //  Wait for bus not busy.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =0;
    while( !(gpio_g->PGDR.Value & 0x3) ){}

    //
    //  Start Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 0;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    
    //
    //  Send DS1337 Slave Address For Read.
    //
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    for(i=0;i<8;i++)
    {
        gpio_g->PGDR.Field.EEDATA = ((READ_ADDRESS>>(7-i))&0x01);
        gpio_g->PGDR.Field.EECLK = 1;
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
        DelayInuSec(DELAY_US);
    }
    if(! wait_ack ()) goto r_failed;


    //
    //  Read Bytes From DS1337.
    //
    gpio_g->PGDDR.Field.EEDATA =0;
    j=0;
    while(nbytes--)
    {
        for(i=0;i<8;i++)
        {
            gpio_g->PGDR.Field.EECLK = 1;
            DelayInuSec(DELAY_US);
            gpio_g->PGDR.Field.EECLK = 0;
            udata =(udata<<1) | gpio_g->PGDR.Field.EEDATA;
            DelayInuSec(DELAY_US);
        }
        pdata[j] = udata;
        if(nbytes==0)
            gen_ack(1);
        else
            gen_ack(0);
        j++;
    }

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return 0;
r_failed:

    //
    //  Stop Condition.
    //
    gpio_g->PGDDR.Field.EECLK =0;
    gpio_g->PGDDR.Field.EEDATA =1;
    gpio_g->PGDR.Field.EEDATA = 1;
    while( gpio_g->PGDR.Field.EECLK != 1 ){}

    return -1;
}

/*
 *  When sending data to ds1337, 
 *  DS1337 will generate an ack for every received byte.
 */
int wait_ack(void)
{
    int n;
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =0;

    if(gpio_g->PGDR.Field.EECLK !=0)
    {
        DelayInuSec(DELAY_US);
        gpio_g->PGDR.Field.EECLK = 0;
    }
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 1;
    n=gpio_g->PGDR.Field.EEDATA;
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);

    return  n ? 0:1;
}

/*
 *  When receiving data from ds1337, 
 *  The host should generate an ack for every received byte.
 */
void gen_ack(int not_ack)
{
    gpio_g->PGDDR.Field.EECLK =1;
    gpio_g->PGDDR.Field.EEDATA =1;

    if(gpio_g->PGDR.Field.EECLK !=0)
    {
        gpio_g->PGDR.Field.EECLK = 0;
    }
    gpio_g->PGDR.Field.EEDATA = not_ack;
    gpio_g->PGDR.Field.EECLK = 1;
    DelayInuSec(DELAY_US);
    gpio_g->PGDR.Field.EECLK = 0;
    DelayInuSec(DELAY_US);
    gpio_g->PGDDR.Field.EEDATA =0;
}


int gettime_from_ds1337(PSYSTEMTIME ptime)
{
    int n;
    char buffer[16]={0};
    SYSTEMTIME m_time;
    unsigned long msec;

    n = read_ds1337(0,buffer,7);

    m_time.wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
    m_time.wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
    m_time.wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);

    msec = m_time.wHour * 3600  + m_time.wMinute * 60 + m_time.wSecond;
    
    msec -= ds1337_current_sec;
    msec += ds1337_bias;

    ptime->wYear = 0;
    ptime->wMonth = 0;
    ptime->wDayOfWeek =0;
    ptime->wDay =0;
    ptime->wHour= msec / 3600;
    ptime->wMinute= ( msec % 3600 ) /60;
    ptime->wSecond= msec % 60 ;
    ptime->wMilliseconds= 0;

//    ptime->wYear = ((buffer[6]>>4)*10) + (buffer[6] & 0xf);
//    ptime->wMonth = (((buffer[5]&0x10) >>4)*10) + (buffer[5] & 0xf);
//    ptime->wDayOfWeek =buffer[3] & 0x7;
//    ptime->wDay =(((buffer[4]&0x30) >>4)*10) + (buffer[4] & 0xf); 
//    ptime->wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
//    ptime->wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
//    ptime->wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);
//    ptime->wMilliseconds=0;

    return n;
}

int init_ds1337(PSYSTEMTIME ptime)
{
    int n;
    char buffer[16]={0};
    SYSTEMTIME m_time;
    
    ds1337_bias = ptime->wHour * 3600  + ptime->wMinute * 60 + ptime->wSecond;

    //
    //  Enable 1Hz Square-Wave Output.
    //
    write_ds1337(0x0E, buffer, 1);


    n = read_ds1337(0,buffer,7);

    m_time.wHour= (((buffer[2]&0x10) >>4)*10) + (buffer[2] & 0xf);
    m_time.wMinute= (((buffer[1]&0x70) >>4)*10) + (buffer[1] & 0xf);
    m_time.wSecond= (((buffer[0]&0x70) >>4)*10) + (buffer[0] & 0xf);

    ds1337_current_sec = m_time.wHour * 3600  + m_time.wMinute * 60 + m_time.wSecond;
    
    return 0;
}

⌨️ 快捷键说明

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