NXP LPC2146 RTC驱动——DS1339

来源:互联网 发布:孙尚香出装 知乎 编辑:程序博客网 时间:2024/06/05 20:48

/********************************************************************
*文件名:rtc1340.c
*文件描述:本程序,是基于NXP LPC2146的处理器上,通过I/O口模拟IIC通讯,
    实现对RTC DS1339的驱动。
*创建人:Sha zq
*创建日期: 2007年10月

*版本号:1.0.01
*E-mail:sasinop@hotmail.com
*修改记录:
 1) void ReadRTC()和unsigned char RevByte()函数,具体说明见相关函数处
 修改者:sha zq  2007-11
********************************************************************/

#include "config.h"
unsigned char  monthflag[13]={0,1,0,1,0,1,0,1,1,0,1,0,1};
unsigned char  year,month,date,hour,minute,second;
unsigned char  RTCyear,RTCmonth,RTCdate,RTChour,RTCminute,RTCsecond;
extern unsigned int  sendlength;
extern void  DelayNS(uint32  dly);

#define   sda 0x00000800  /* P0.11 */
#define   scl 0x00000400  /* P0.10 */

#define  sdaH IO0SET^(1<<11)
#define  sdaL IO0CLR&(0<<11)
#define  sclH IO0SET^(1<<10)
#define  sclL IO0CLR&(0<<10)

#define  OSDA (IO0DIR|(1<<11))
#define  ISDA (IO0DIR &(0<<11))
//IO0DIR=0x00000C04; //0000 1100  P011(sda RTC)  P010 (sck  RTC)输出


/*============================================================
* 函 数 名: Delay1340
* 参  数:Null
* 功能描述:
*     延时程序
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11==============================================================*/
void  Delay1340(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--)
      for(i=0; i<40; i++);
}
/*============================================================
* 函 数 名: eedelay200us
* 参  数:Null
* 功能描述:
*     延时程序
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/
void eedelay200us()
{
  uint32  i;
      for(i=0; i<10; i++);
}
/*============================================================
* 函 数 名: eedelay
* 参  数:Null
* 功能描述:
*     延时程序
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/
void eedelay(uint32 n)
{
  uint32  i; 
      for(i=0; i<n; i++);
}

/*============================================================
* 函 数 名: StartIIC
* 参  数:Null
* 功能描述:
*     IIC开始
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/
void StartIIC()
{
 IO0DIR=0x00000C04;  //SDA 为输出 
 //scl=1;
 IO0SET =scl; //0x00000400;  // P0.10  
 eedelay(1); /////////////////////////////////
 //sda=0;
 IO0CLR =sda; 
 eedelay(4);
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl; 
 eedelay(3);
}
/*============================================================
* 函 数 名: StopIIC
* 参  数:Null
* 功能描述:
*     IIC停止
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/
void StopIIC()
{
 IO0DIR=0x00000C04;  //SDA 为输出 
 //sda=0;
 IO0CLR =sda;
 //scl=1;
 IO0SET =scl; //0x00000400;  // P0.10
 
 eedelay(5);
 //sda=1;
 IO0SET =sda;
 eedelay(5); /////////////////////////
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl;
 Delay1340(1);
}                      
/*============================================================
* 函 数 名: SendByte
* 参  数:para
* 功能描述:
*     发送数据
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/       
void SendByte(unsigned char para)
{
 unsigned char  bitcnt;
 IO0DIR=0x00000C04;  //SDA 为输出 
 for (bitcnt=0;bitcnt<8;bitcnt++)
 {
     if (para & 0x80)
      //sda=1;
      IO0SET =sda;
     else
       //sda=0;
       IO0CLR =sda;
     para=para<<1;   
     //scl=1;
     Delay1340(1);  //aprox 5us   
     IO0SET =scl; //0x00000400;  // P0.10
 eedelay(10); //1.6us
     //scl=0;
     IO0CLR=scl; //0x00000400;  // P0.10  scl;
     
   }   
 //sda=1; 
 
 eedelay(12); //
 eedelay(6);
 IO0SET =sda;
 //scl=1;
 Delay1340(1); 
 
 IO0SET =scl; //0x00000400;  // P0.10 
 eedelay(10); //1.6us 
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl;
 eedelay(10); // 
}
/*============================================================
* 函 数 名: RevByte
* 参  数:Null
* 功能描述:
*     接受DS1339返回的数据
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11

* 修改记录:
  1)接受返回数据时,做了处理改进,原来的方法,得不到返回值。
* 修改人  :

==============================================================*/     
unsigned char RevByte()
{
 unsigned char  bitcnt,retc,sdabyte;
 IO0DIR=0x00000404;  //SDA 为输入 
  
 retc=0;
 for (bitcnt=0;bitcnt<8;bitcnt++)
 {
     //scl=1;
     IO0SET =scl; //0x00000400;  // P0.10
 retc=retc<<1;
 
 sdabyte=((IO0PIN>>11) & 0x01); //把SDA,即p0.11上的脉冲
 
 retc=retc+sdabyte;
 eedelay(5); // 后七位高时钟延时
     //scl=0;
     IO0CLR=scl; //0x00000400;  // P0.10  scl;
     Delay1340(1);
   }
 return(retc);
}
/*============================================================
* 函 数 名: SendAck
* 参  数:Null
* 功能描述:
*     模拟IIC时,返回应答标志,标志为 “0”
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/  
void SendAck(unsigned char abit)
{

 IO0DIR=0x00000C04;  //SDA 为输出

 IO0CLR= sda;

 eedelay(5);
 //scl=1;
 IO0SET =scl; //0x00000400;  // P0.10
 eedelay(5);
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl;
}
/*============================================================
* 函 数 名: SendAckOne
* 参  数:Null
* 功能描述:
*     模拟IIC时,返回应答标志,标志为 “1”
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11
==============================================================*/  
void SendAckOne(unsigned char abit)
{

 IO0DIR=0x00000C04;  //SDA 为输出
 IO0SET= sda;
 eedelay(5);
 //scl=1;
 IO0SET =scl; //0x00000400;  // P0.10
 eedelay(5);
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl; 
}

/*============================================================
* 函 数 名: ReadRTC
* 参  数:Null
* 功能描述:
*     接受DS1339返回的数据后的处理函数,共得到 年,月,日,时,分,秒
* 返 回 值:Null
* 作  者:Sha zq 日期:2007-11

* 修改记录:
  1)在开始IIC时,修改了开始条件,原来的IIC开始条件不符合要求,
     故在此函数中的StartIIC()前,加了代码,完善IIC开始条件。
* 修改人  :sha zq 2007
==============================================================*/ 

void ReadRTC()
{
 IO0DIR=0x00000C04;  //SDA 为输出
 //scl=1;
 IO0SET =scl; //0x00000400;  // P0.10 
 eedelay(5);  
 //scl=0;
 IO0CLR=scl; //0x00000400;  // P0.10  scl;
 Delay1340(1);   //5us  
 
 StartIIC();
    SendByte(0xd0);
    SendByte(0x00);
    StopIIC();
 StartIIC();
   SendByte(0xd1);
   
   //IO0DIR=0x00000404;   //SDA 为输入
   RTCsecond=RevByte();
    SendAck(0);
 RTCminute=RevByte();
    SendAck(0);
    RTChour=RevByte();
    SendAck(0);
    RTCdate=RevByte();
    SendAck(0);
    RTCdate=RevByte();
    SendAck(0);
    RTCmonth=RevByte();
    SendAck(0);
   RTCyear=RevByte();
    SendAckOne(1);
 StopIIC();
 
 second=((RTCsecond&0x70)>>3)*5+(RTCsecond&0x0f);//24us执行完成
 minute=((RTCminute&0x70)>>3)*5+(RTCminute&0x0f);
 hour=((RTChour&0x30)>>3)*5+(RTChour&0x0f);
 date=((RTCdate&0x30)>>3)*5+(RTCdate&0x0f);
 month=((RTCmonth&0x10)>>3)*5+RTCmonth&0xf;
 year=((RTCyear&0xf0)>>3)*5+(RTCyear&0x0f);
 
}

只有读时钟功能,写RTC功能,未帖出来 呵呵