?? eeprom.c
字號:
/*** macro define for 24c08 or.24c01 ***/
//#define DEBUG1 /*NOTE: this line should delete if DSP working in NORMAL mode(ie. MC)*/
#include "eeprom.h"
#include "regs2407.h"
//#ifdef DEBUG1
//#define LINE_I2C_DAT_0 *PFDATDIR =(*PFDATDIR|0x0100)&0xFFFE; //IOPF0
//#define LINE_I2C_DAT_1 *PFDATDIR |=0x0101 //IOPF0
//#define LINE_I2C_CLK_0 *PFDATDIR &=0xFFFD //IOPF1
//#define LINE_I2C_CLK_1 *PFDATDIR |=0x0002 //IOPF1
//#define LINE_I2C_DAT_OUT *PFDATDIR |=0x0100 //IOPF0
//#define LINE_I2C_DAT_IN *PFDATDIR &=0xFEFF //IOPF0
//#define LINE_I2C_DAT (*PFDATDIR & 0x0001) //IOPF0
//#else
#define LINE_I2C_DAT_0 *PBDATDIR =(*PBDATDIR|0x2000)&0xFFDF //'IOPB5
#define LINE_I2C_DAT_1 *PBDATDIR |=0x2020 //'IOPB5
#define LINE_I2C_CLK_0 *PBDATDIR &=0xFFEF //'IOPB4
#define LINE_I2C_CLK_1 *PBDATDIR |=0x0010 //'IOPB4
#define LINE_I2C_DAT_OUT *PBDATDIR |=0x2000 //'IOPB5
#define LINE_I2C_DAT_IN *PBDATDIR &=0xDFFF //'IOPB5
#define LINE_I2C_DAT (*PBDATDIR & 0x0020) //'IOPB5
//#endif
/*** macro define for E2PROM ***/
#define READ 0x0A1
#define WRITE 0x0A0
#define ACCESS_LIMIT 0x07
/**********************************************************************************************************/
void i2cstart(void)
{
LINE_I2C_CLK_0;
LINE_I2C_DAT_OUT;
delay_us(10);
LINE_I2C_DAT_1;
delay_us(10);
LINE_I2C_CLK_1;
delay_us(30);
LINE_I2C_DAT_0;
delay_us(30);
LINE_I2C_CLK_0;
delay_us(30);
LINE_I2C_DAT_1;
}
void i2cstop(void)
{
delay_us(1);
LINE_I2C_CLK_0;
delay_us(10);
LINE_I2C_DAT_OUT;
LINE_I2C_DAT_0;
delay_us(10);
LINE_I2C_CLK_1;
delay_us(30);
LINE_I2C_DAT_1;
delay_us(30);
LINE_I2C_CLK_0;
}
int i2crxack(void) //'返回值0,表示操作成功
{ //'返回值!0,表示操作失敗
int temp;
LINE_I2C_DAT_IN;
delay_us(10);
LINE_I2C_CLK_1;
delay_us(30);
temp=LINE_I2C_DAT;
delay_us(30);
LINE_I2C_CLK_0;
return(temp);
}
void i2ctxack(void)
{
LINE_I2C_DAT_OUT;
LINE_I2C_DAT_0;
delay_us(30);
LINE_I2C_CLK_1;
delay_us(30);
LINE_I2C_CLK_0;
delay_us(10);
}
void i2cnoack(void)
{
LINE_I2C_DAT_OUT;
LINE_I2C_DAT_1;
delay_us(10);
LINE_I2C_CLK_1;
delay_us(10);
LINE_I2C_CLK_0;
delay_us(10);
}
void i2ctxbyte(int data8)
{
int keepbit, nowbit;
LINE_I2C_DAT_OUT;
for(keepbit=0x0080; keepbit!=0x00; keepbit=keepbit>>1 ) //'先發(fā)送字節(jié)數(shù)據(jù)的最高位
{
delay_us(10);
LINE_I2C_CLK_0;
delay_us(10);
nowbit=data8&keepbit;
if(nowbit==0)
{
LINE_I2C_DAT_0;
}
else
{
LINE_I2C_DAT_1;
}
delay_us(10);
LINE_I2C_CLK_1;
delay_us(10);
}
LINE_I2C_CLK_0;
}
int i2crxbyte(void)
{
int i;
int value=0;
LINE_I2C_DAT_IN;
LINE_I2C_CLK_0;
for(i=0;i<8;i++)
{
delay_us(10);
LINE_I2C_CLK_1;
value=value<<1; //--
if(LINE_I2C_DAT) //--
value=value|0x01; //--
delay_us(10);
//' if(LINE_I2C_DAT)
//' { value|=(0x080>>i); } //'字節(jié)數(shù)據(jù)的最高位,最先被接收到
LINE_I2C_CLK_0;
}
return(value);
}
///'''以下程序只能用于對AT24C08的讀寫操作
int read(int* aimaddr,int control, int length) //' 前提條件: 總線啟動信號、控制命令已送出
{ //' 讀E2PROM的源地址已送出,且收到應答信號
int err=1, word_l, word_h; //' 該程序結束后應調(diào)用i2cstop()以停止I2C總線
i2cstart(); //'總線停止信號尚未送出時,該程序讀所送地址單元中的內(nèi)容
i2ctxbyte(control); //'總線停止信號送出時,該程序讀所送地址的下一個單元中的內(nèi)容
if(i2crxack()==0)
{
for(;length>1; length--,aimaddr++)
{
word_h=(i2crxbyte())<<8; //'最先收到的是高位字節(jié)
i2ctxack();
word_l=i2crxbyte();
i2ctxack();
*aimaddr=word_h|word_l;
}
word_h=(i2crxbyte())<<8;
i2ctxack();
word_l=i2crxbyte();
i2cnoack();
*aimaddr=word_h|word_l;
err=0; //'清讀錯標志
}
return(err); //'返回0表示讀操作正確
//'返回1表示讀操作錯誤
}
int write(int* sourseaddr,int control,int length ) //' 前提條件: 總線啟動信號、控制命令已送出,
{ //' 寫E2PROM的目的地址已送出,且收到應答信號
//' 該程序結束后應調(diào)用i2cstop()以停止I2C總線
//'該程序寫所送地址單元中的內(nèi)容
int err, word_l, word_h;
for(;length>0;length--,sourseaddr++)
{
word_h=(*sourseaddr)>>8;
word_l=(*sourseaddr)&0x00FF;
i2ctxbyte(word_h);
err=i2crxack();
if(err==1) break;
i2ctxbyte(word_l);
err=i2crxack();
if(err==1) break;
}
return(err); //'返回0表示寫操作正確
//'返回1表示寫操作錯誤
}
int e2prom(int* ramaddr, int romaddr,int control,int length) //'control 采用宏參WRITE、READ
{ //'為了簡化程序的編寫control命令字的第1、2為固定為0
int err=1, temp; //'所以romaddr只能取0~255,E2PROM只用了低256字節(jié)的空間
i2cstart();
temp=control&0x0FFFE;
i2ctxbyte(temp);
if(i2crxack()==0)
{
i2ctxbyte(romaddr);
if(i2crxack()==0)
{
switch(control)
{
case READ:
err=read(ramaddr,control,length);
break;
case WRITE:
err=write(ramaddr,control,length);
break;
}
}
}
i2cstop();
return(err); //'返回0表示操作正確
} //'返回1表示操作錯誤
//'該程序調(diào)用方法
//' int k ,access_num=0;
//' while(1)
//' {
//' k=e2prom();
//' if(k==0) //訪問成功,結束對E2PROM的操作
//' { break; }
//' else
//' { //訪問不成功次數(shù)達到極限值,結束對E2PROM的操作
//' if((++access_num)>=ACCESS_LIMIT)
//' { break; }
//' }
//' }
//'
//'