/********************************************************************
*文件名: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
}
/*============================================================
* 函 数 名: 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功能,未帖出来 呵呵