📄 i2c.c
字号:
/*******************************************************************************
*
* FILE NAME : i2c.c
*
* DESCRIPTION:
* i2c for eeprom read/write routine
*
********************************************************************************
* INCLUDE FILES
********************************************************************************/
#include <machine.h>
#include "iodefine.h"
#include "i2c.h"
#include "extern.h"
/******************************************************************************/
#define SET_SDA_IN (IO.PCR3 = 0xc4)
#define SET_SDA_OUT (IO.PCR3 = 0xc6)
#define SET_SDA_SCL_OUT (IO.PCR3 = 0xc6)
#define I2C_SDA (IO.PDR3.BIT.B1)
#define I2C_SCL (IO.PDR3.BIT.B2)
#define EEPROM_WP (IO.PDR3.BIT.B6)
#define EEPROM_WP_ON (EEPROM_WP = 1)
#define EEPROM_WP_OFF (EEPROM_WP = 0)
#define Power_Io_Data (IO.PDR5.BIT.B0)
// =======================================================================
/*对于EEROM I2C 要注意:
1、应答信号判断,控制;
2、页写延时
*/
// ======================================================================= */
/*对于EEROM I2C 要注意:
1、应答信号判断,控制;
2、页写延时 */
void I2cWStart(void)
{
SET_SDA_SCL_OUT;
NOP;
NOP;
I2C_SCL = 0;
NOP;
NOP;
I2C_SDA = 1;
NOP;
NOP;
I2C_SCL = 1;
NOP;
NOP;
I2C_SDA = 0;
NOP;
NOP;
I2C_SCL = 0;
}
// =======================================================================
void I2cStop(void)
{
SET_SDA_OUT; //I2C_SCL = 0; //EEPROM_i2c_scl_low();
NOP;
NOP;
I2C_SCL = 0;
NOP;
NOP;
I2C_SDA = 0;
NOP;
NOP;
I2C_SCL = 1;
NOP;
NOP;
I2C_SDA = 1;
}
// =======================================================================
void I2_SLK(void)
{
NOP;
I2C_SCL = 1;
NOP;
NOP;
I2C_SCL = 0;
NOP;
}
// =======================================================================
void I2cWrtBit(unsigned char data)
{
unsigned char k;
SET_SDA_OUT;
for(k=0; k<8; k++)
{
if(data & cMsbBitTbl[k])
I2C_SDA = 1; //I2cSdaHigh;
else
I2C_SDA = 0; // I2cSdaLow;
I2_SLK ();
}
}
// =======================================================================
unsigned char ee_ack()
{
unsigned char ack;
SET_SDA_IN;
ack = 0;
NOP;
I2C_SCL = 1;
NOP;
if(I2C_SDA == 1)
ack = 1;
I2C_SCL = 0; //如果延长SCL时间可使I2C_SDA = 1 ???,在SCL =1前可对SDA做任何改动
NOP;
I2C_SDA = 0; //所以要在更改为outport 前=0 ???
return ack;
}
// =======================================================================
unsigned char I2cRBit(void)
{
unsigned char data,j;
SET_SDA_IN;
data = 0;
for(j=0;j<8;j++)
{
I2C_SCL = 1;I2C_SCL = 1;
if(I2C_SDA ==1 ) //IsI2cSdaHigh)
data |= cMsbBitTbl[j];
I2C_SCL = 0;
}
return data;
}
// =======================================================================
void I2c_ACK(void)
{
SET_SDA_OUT;
I2C_SDA = 0;
NOP;
I2_SLK();
}
// =======================================================================
void I2c_NACK(void)
{
SET_SDA_OUT;
I2C_SDA = 1;
NOP;
I2_SLK();
}
// =======================================================================
void delay_10ms(void)
{
unsigned int delay_timer;
for(delay_timer =0;delay_timer<4000;delay_timer++)
{
NOP;
}
}
/*********************************************************************************************************/
unsigned char F_BlckRead_Eeprm(unsigned int Data_SAdr,unsigned char *Data,unsigned char Data_Len)
{
unsigned char mack,i,Loop,j,F_ee_ok=0;
if (Data_Len==0)
{
return F_ee_ok;
}
j=Data_Len;
F_ee_ok = 0;
Loop=0x03;
while(Loop--)
{
I2cWStart();
I2cWrtBit (CHIP_ADDR|((unsigned char )(Data_SAdr>>8)<<1) );
mack = ee_ack();
I2cWrtBit ((unsigned char )Data_SAdr);
mack |= ee_ack();
I2cWStart();
I2cWrtBit ((CHIP_ADDR|((unsigned char )(Data_SAdr>>8)<<1)) |0x01);
mack |= ee_ack();
for ( i=1;i<Data_Len;i++)
{
*Data++ = I2cRBit();
I2c_ACK();
}
*Data = I2cRBit();
if(!mack)
{
F_ee_ok=1;
break;
}
else
{
Data_SAdr=Data_SAdr-j;
Data=Data-j;
Data_Len=j;
}
}
I2c_NACK();
I2cStop();
return F_ee_ok;
}
// =======================================================================
unsigned char F_BlckWrt_Eeprm(unsigned int Data_SAdr,unsigned char *Data,unsigned char Data_Len)
{
unsigned char Loop,mack,i,j,F_ee_ok=0;
if (Data_Len==0)
{
return F_ee_ok;
}
j=Data_Len;
EEPROM_WP_OFF;
now_star:
Loop=3;
while(Loop-- !=0)
{
F_ee_ok = 0;
I2cWStart();
I2cWrtBit (CHIP_ADDR|((unsigned char)(Data_SAdr>>8)<<1) );
mack = ee_ack();
I2cWrtBit ((unsigned char)Data_SAdr);
mack |= ee_ack();
for (i=0;i<Data_Len;i++)
{
I2cWrtBit(*Data++);
mack |= ee_ack();
Data_SAdr+=1;
if((!(Data_SAdr&0x0f)) &&(!mack))
{
I2cStop();
delay_10ms();
Data_Len-=(i+1);
goto now_star;
}
}
if(!mack)
{
F_ee_ok = 1; //表示EEROM操作成功
break;
}
Data_SAdr=Data_SAdr-j;
Data=Data-j;
Data_Len=j;
}
I2cStop();
for (i =0;i<10;i++)
{
NOP;
NOP;
NOP;
NOP;
}
EEPROM_WP_ON;
delay_10ms();
return F_ee_ok;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -