📄 eeprom.c
字号:
#include ".\head\intrins.h"
#include ".\head\CPU081.h"
#include ".\head\define.h"
#include ".\head\global.h"
/*-----------------------------------------------------------------------------------------
*
* I2C_eeprom driver for 24c01/02/04/08/16
* ------------------------------------
*
*capbility:
* - support write serial bytes from MCU ram to eeprom
* - support read serial bytes from eeprom to MCU ram
* - support write/read serial bytes in one block
*
*24C02 1block * 32page rows * 4bytes * 8 bit = 128bytes = 1kbits
*24C02 1block * 32page rows * 8bytes * 8 bit = 256bytes = 2kbits
*24C04 2block * 16page rows * 16bytes * 8 bit = 512bytes = 4kbits
*24C08 4block * 16page rows * 16bytes * 8 bit = 1024bytes = 8kbits
*24C16 8block * 16page rows * 16bytes * 8 bit = 2048bytes = 16kbits
*
*----------------------------------------------------------------------------------------*/
//communication config
#define I2CFAILTIMES 30 //*** communication retry times
//IO_Port config
#define SDA_PINCR P1CR //*** select SDA pin IO port
#define SDA_PULL P1PCR //***
#define SDA_PIN P1_1 //***
#define SDA Bin(00000010); //***
#define SCL_PINCR P1CR //*** select SCL pin IO port
#define SCL_PULL P1PCR //***
#define SCL_PIN P1_0 //***
#define SCL Bin(00000001); //***
//EEPROM Type config
#define EEPROM_24C01 0
#define EEPROM_24C02 1
#define EEPROM_24C04 2
#define EEPROM_24C08 3
#define EEPROM_24C16 4
#define EEPROM_TYPE EEPROM_24C02 //*** select eeprom type
#if (EEPROM_TYPE == EEPROM_24C01)
#define PAGE_OVER_ROLL Bin(00000011) //every page contain 4bytes
#elif (EEPROM_TYPE == EEPROM_24C02)
#define PAGE_OVER_ROLL Bin(00000111) //every page contain 8bytes
#elif (EEPROM_TYPE == EEPROM_24C04)
#define PAGE_OVER_ROLL Bin(00001111) //every page contain 16bytes
#elif (EEPROM_TYPE == EEPROM_24C08)
#define PAGE_OVER_ROLL Bin(00001111) //every page contain 16bytes
#elif (EEPROM_TYPE == EEPROM_24C16)
#define PAGE_OVER_ROLL Bin(00001111) //every page contain 16bytes
#else
#define PAGE_OVER_ROLL Bin(00000111) //every page contain 8bytes
#endif
/*------------------------------------------------------------------------------------------
; IICDelay
;*** TBD: delay 4us
;notice: user may need to modify here
;-----------------------------------------------------------------------------------------*/
void IICDelay(void)
{
//delay 20*0.125=2us
//+7 LCALL
_nop_(); //+1 nop
_nop_(); //+1 nop
_nop_(); //+1 nop
_nop_(); //+1 nop
_nop_(); //+1 nop
//+8 RET
}
/*------------------------------------------------------------------------------------------
; IICDelayStop
;*** TBD: delay about 10ms on 8M oscillator
;notice: user may need to modify here
;-----------------------------------------------------------------------------------------*/
void IICDelayStop(void)
{
Byte i,j;
for(j=4;j>0;j--)
{
RSTSTAT = 0x00; //feed watchdog
for(i=250;i>0;i--)
{
}
}
}
/*------------------------------------------------------------------------------------------
; IICInit
;-----------------------------------------------------------------------------------------*/
void IICInit(void)
{
SDA_PINCR |= SDA;
SDA_PULL |= SDA;
SDA_PIN = 1;
SCL_PINCR |= SCL;
SCL_PULL |= SCL;
SCL_PIN = 1;
}
/*------------------------------------------------------------------------------------------
; IICStart
;-----------------------------------------------------------------------------------------*/
void IICStart(void)
{
SDA_PINCR |= SDA;
SDA_PIN=1;
SCL_PINCR |= SCL;
SCL_PIN=1;
IICDelay();
SDA_PIN=0; //SDA H->L
IICDelay();
SCL_PIN=0; //SCL H->L
}
/*------------------------------------------------------------------------------------------
; IICStop
;-----------------------------------------------------------------------------------------*/
void IICStop(void)
{
SDA_PINCR |= SDA;
SDA_PIN=0;
SCL_PINCR |= SCL;
SCL_PIN=0;
IICDelay();
SCL_PIN=1; //SCL L->H
IICDelay();
SDA_PIN=1; //SDA L->H
IICDelay();
SDA_PINCR &= ~SDA; //standby
SCL_PINCR &= ~SCL;
SDA_PULL |= SDA;
SCL_PULL |= SCL;
}
/*------------------------------------------------------------------------------------------
; IICReadByte
;return one byte and tell the slave whether to read the apprend bytes by zI2CCounter
;-----------------------------------------------------------------------------------------*/
Byte IICReadByte(Byte zI2CCounter)
{
Byte zI2CByteData;
Byte zI2CBit;
SCL_PINCR |= SCL; //SCL output
SDA_PIN = 1;
SDA_PINCR &= ~SDA; //SDA input to read bit 1~8 from slave
for( zI2CBit = 8;zI2CBit >0;zI2CBit--)
{
SCL_PIN = 1;
zI2CByteData *=2;
if( SDA_PIN )
{
zI2CByteData |= Bin(00000001);
}
SCL_PIN = 0;
}
SDA_PINCR |= SDA; //SDA output to write apprend bit to slave
if(zI2CCounter == 0 )
{
SDA_PIN = 1;
}
else
{
SDA_PIN = 0;
}
IICDelay();
SCL_PIN = 1;
IICDelay();
SCL_PIN = 0;
IICDelay();
return zI2CByteData;
}
/*------------------------------------------------------------------------------------------
; IICWriteByte
;write one byte,return 1 if success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit IICWriteByte(Byte zI2CByteData)
{
Byte zI2CBit;
bit zI2CAck=0;
SDA_PINCR |= SDA; //SDA output to write bit 1~8 to slave
for( zI2CBit =8;zI2CBit>0;zI2CBit-- )
{
zI2CByteData *=2;
if(CY)
{
SDA_PIN =1; //send Bit1
}
else
{
SDA_PIN =0; //send Bit0
}
IICDelay();
SCL_PIN=1;
IICDelay();
SCL_PIN=0;
}
SDA_PIN=1; //SDA input to read ACK from slave
SDA_PINCR &= ~SDA;
IICDelay();
SCL_PIN=1;
zI2CAck = ~SDA_PIN;
IICDelay();
SCL_PIN =0;
return zI2CAck;
}
/*------------------------------------------------------------------------------------------
; IICCheckBusBusy
;return 1 if idle,return 0 if busy
;-----------------------------------------------------------------------------------------*/
bit IICCheckBusBusy(void)
{
SDA_PINCR &= ~SDA;
SCL_PINCR &= ~SCL;
SDA_PIN=1;
SCL_PIN=1;
if(SDA_PIN && SCL_PIN)
{
return 1;
}
return 0;
}
/*------------------------------------------------------------------------------------------
; EEPROMWrite
;return 1 if communication success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit EEPROMWrite(Byte *zI2Cptr,Word zI2CByteAddr,Byte zI2CCounter)
{
bit zI2CError=0;
Byte zI2CDevAddrH = (((zI2CByteAddr>>8)*2)&0x0f) | Bin(10100000);
Byte zI2CDevAddrL = zI2CByteAddr & 0xff;
Byte zI2CRepeat = I2CFAILTIMES;
while(zI2CCounter!=0)
{
if(_testbit_(zI2CError)) //comunication error and retry
{
IICStop();
IICDelayStop();
zI2CRepeat--;
if( zI2CRepeat==0 )
{
return 0;
}
}
if( ! IICCheckBusBusy()) //1.check bus stable
{
zI2CError = 1; //mark error flag
continue;
}
IICInit();
IICStart(); //2.start
if(! IICWriteByte(zI2CDevAddrH) ) //3.command to write
{
zI2CError = 1; //mark error flag
continue;
}
if(! IICWriteByte(zI2CDevAddrL)) //4.write address
{
zI2CError = 1; //mark error flag
continue;
}
do //5.write serial bytes
{
if( ! IICWriteByte(*zI2Cptr) )
{
zI2CError = 1; //mark error flag
break;
}
zI2CCounter--; //prepare to write next byte
zI2Cptr++;
zI2CDevAddrL ++;
if(zI2CCounter == 0)
{
IICStop(); //finished all bytes written
IICDelayStop();
return 1;
}
if(!(zI2CDevAddrL&PAGE_OVER_ROLL))
{
IICStop(); //switch to next page and continue to write rest bytes
IICDelayStop();
break;
}
}while(zI2CCounter>0);
}
}
/*------------------------------------------------------------------------------------------
; EEPROMRead
;return 1 if communication success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit EEPROMRead(Byte *zI2Cptr,Word zI2CByteAddr,Byte zI2CCounter)
{
bit zI2CError=0;
Byte zI2CDevAddrH = (((zI2CByteAddr>>8)*2)&0x0f) | Bin(10100000);
Byte zI2CDevAddrL = zI2CByteAddr & 0xff;
Byte zI2CRepeat = I2CFAILTIMES;
while(zI2CCounter!=0)
{
if(_testbit_(zI2CError)) //comunication error and retry
{
IICStop();
IICDelayStop();
zI2CRepeat--;
if( zI2CRepeat==0 )
{
return 0;
}
}
if( ! IICCheckBusBusy()) //1.check bus stable
{
zI2CError = 1; //mark error flag
continue;
}
IICInit();
IICStart(); //2.start
if(! IICWriteByte(zI2CDevAddrH) ) //3.command to write
{
zI2CError = 1; //mark error flag
continue;
}
if(! IICWriteByte(zI2CDevAddrL)) //4.write address
{
zI2CError = 1; //mark error flag
continue;
}
IICInit();
IICStart(); //5.command to read
if(! IICWriteByte(zI2CDevAddrH | Bin(00000001)))
{
zI2CError = 1; //mark error flag
continue;
}
do //6.read serial bytes
{
zI2CCounter--;
*zI2Cptr = IICReadByte(zI2CCounter);
zI2Cptr++;
zI2CDevAddrL ++;
}while(zI2CCounter>0);
IICStop();
IICDelayStop();
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -