📄 i2csw.c
字号:
//*****************************************************************************
//
// File Name : "i2csw.c"
/
//
//*****************************************************************************
#include "include.h"
// Creat public variable
PubVarDef PubVar;
#define QDEL NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
#define HDEL NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
#define SDADDR PM2
#define SCLDDR PM2
#define SDAPORT P2
#define SDAPIN P2
#define SCLPORT P2
#define SDA 5
#define SCL 6
#define I2C_SDA_IN (SDADDR.SDA = IN)
#define I2C_SDA_OUT (SDADDR.SDA = OUT)
#define I2C_SDA_LO CLRBIT( SDAPORT, SDA)
#define I2C_SDA_HI SETBIT( SDAPORT, SDA)
#define I2C_SCL_IN (SDADDR.SCL = IN)
#define I2C_SCL_OUT (SDADDR.SCL = OUT)
#define I2C_SCL_LO CLRBIT( SCLPORT, SCL)
#define I2C_SCL_HI SETBIT( SCLPORT, SCL)
void I2cInit(void)
{
I2C_SCL_OUT;
I2C_SDA_OUT;
I2C_SCL_LO; // SCL port output 0
I2C_SDA_LO; // SDA port output 0
I2C_SCL_LO; HDEL // set SCL LO
I2C_SDA_HI; HDEL // set SDA HI
I2C_SCL_HI; HDEL // set SCL HI
}
void i2ct(void)
{
HDEL;
I2C_SCL_HI;
HDEL;
I2C_SCL_LO;
}
void i2cstart(void)
{
I2C_SCL_LO; HDEL;
I2C_SDA_HI; HDEL;
I2C_SCL_HI; QDEL;
I2C_SDA_LO; QDEL;
I2C_SCL_LO; HDEL;
}
void i2cstop(void)
{
HDEL;
I2C_SDA_LO; HDEL;
I2C_SCL_HI; QDEL;
I2C_SDA_HI; HDEL;
}
// I2c operation Macro define
#define I2C_SCL_TOGGLE i2ct(); // I2c SCL execute Lo-Hi-Lo
#define I2C_START i2cstart();
#define I2C_STOP i2cstop();
INT8U i2cPutbyte(INT8U b)
{
int i;
I2C_SDA_OUT;
for (i=8;i>0;i--)
{
if ( b & 0x80 )
I2C_SDA_HI;
else
I2C_SDA_LO; // address bit
b <<= 1;
I2C_SCL_TOGGLE; // clock HI, delay, then LO
}
I2C_SDA_IN;
I2C_SDA_HI; // leave SDL HI,change direction to input on SDA line
HDEL;
I2C_SCL_HI; // clock back up
HDEL;
b = CHKBIT(SDAPIN,SDA); // get the ACK bit
I2C_SCL_LO; // not really ??
I2C_SDA_OUT;
HDEL;
if(b == 0) // return ACK value
return (1);
else
return (0);
}
INT8U i2cGetbyte(INT8U last)
{
INT8U i;
INT8U c,b = 0;
I2C_SDA_IN;
I2C_SDA_HI; // make sure pullups are ativated,change direction to input on SDA line
for(i=8;i>0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
c = CHKBIT(SDAPIN,SDA);
b <<= 1;
if(c) b |= 1;
HDEL;
I2C_SCL_LO; // clock LO
}
I2C_SDA_OUT; // change direction to output on SDA line
QDEL;
if (last)
I2C_SDA_HI; // set NAK
else
I2C_SDA_LO; // set ACK
I2C_SCL_TOGGLE; // clock pulse
I2C_SDA_HI; // leave with SDL HI
return b; // return received byte
}
void I2cSend(INT8U device, INT8U subAddr, INT8U length, INT8U *dataP)
{
I2C_START; // do start transition
i2cPutbyte(device); // send DEVICE address
i2cPutbyte(subAddr); // and the subaddress
// send the data
while (length--)
i2cPutbyte(*dataP++);
I2C_STOP; // send STOP transition
}
//! Retrieve a byte sequence on the I2C bus
void I2cReceive(INT8U device, INT8U subAddr, INT8U length, INT8U *dataP)
{
INT8U j = length;
INT8U *p = dataP;
I2C_START; // do start transition
i2cPutbyte(device); // send DEVICE address
i2cPutbyte(subAddr); // and the subaddress
I2C_START; // transition
i2cPutbyte(device | READ); // resend DEVICE, with READ bit set
// receive data bytes
while (j--)
{
*p++ = i2cGetbyte(0);
}
*p++ = i2cGetbyte(1);
I2C_STOP; // send STOP transition
}
/******************************************************************************
//FUNCTION : I2cSend16(INT16U addr,INT8U *dataP,INT8U length)
//DESCRIPTION : Send a byte sequence on the I2C bus
//NOTICE : Auto skip page
******************************************************************************/
void I2cSend16(INT16U addr,INT8U *dataP,INT8U length)
{
INT8U address;
address = (INT8U)addr;
if(address%I2C_EEP_PAGE_SIZE)
{
I2C_START; // do start transition
i2cPutbyte((INT8U)(addr>>8)); // send DEVICE address
i2cPutbyte(address); // and the subaddress
}
while (length--) // send the data
{
if((address%I2C_EEP_PAGE_SIZE)==0) // Skip page
{
I2C_STOP;
if(address != (INT8U)addr) // Skip first byte delay
Delayms(10);
I2C_START; // do start transition
i2cPutbyte((INT8U)(addr>>8)); // send DEVICE address
i2cPutbyte(address); // and the subaddress
}
i2cPutbyte(0xFF-(*dataP++));
address++;
}
I2C_STOP; // send STOP transition
Delayms(10);
}
/******************************************************************************
//FUNCTION : INT8U I2cSend16_V(INT16U addr,INT8U *dataP,INT8U length)
//DESCRIPTION : Send bytes to I2C bus with verify
//NOTICE :
******************************************************************************/
INT8U I2cSend16_V(INT16U addr,INT8U *dataP,INT8U length)
{
unsigned char WrCnt=0;
unsigned char i;
CopyRam(dataP ,PubVar.BuffWr,length);
REPEAT_WR:
WDTE =WDT_CLR; // Watch clr
I2cSend16(addr,PubVar.BuffWr,length);
I2cReceive16(addr,PubVar.BuffRd,length);
for(i=0;i<length;i++)
{
if(PubVar.BuffWr[i] != PubVar.BuffRd[i])
{
if(++WrCnt>=100)
{
return(0);
PubVar.E2Erro = 1;
}
else
goto REPEAT_WR;
}
}
return(1);
}
/******************************************************************************
//FUNCTION : I2cReceive16(INT16U addr,INT8U *dataP,INT8U length)
//DESCRIPTION : Retrieve a byte sequence on the I2C bus
//NOTICE :
******************************************************************************/
void I2cReceive16(INT16U addr,INT8U *dataP,INT8U length)
{
INT8U j = length-1;
INT8U *p = dataP;
I2C_START; // Start
i2cPutbyte((INT8U)(addr>>8)); // send DEVICE address
i2cPutbyte((INT8U)addr); // and the subaddress
I2C_START; // transition
i2cPutbyte((INT8U)(addr>>8) | READ); // resend DEVICE, with READ bit set
// receive data bytes
while (j--)
{
*p++ = 0xFF-i2cGetbyte(0);
}
*p++ = 0xFF-i2cGetbyte(1);
I2C_STOP; // send STOP transition
}
/******************************************************************************
//FUNCTION : I2cReceive16_V(INT16U addr,INT8U *dataP,INT8U length)
//DESCRIPTION : Retrieve a byte sequence on the I2C bus
//NOTICE :
******************************************************************************/
void I2cReceive16_V(INT16U addr,INT8U *dataP,INT8U length)
{
unsigned char RdCnt=0;
unsigned char i;
REPEAT_RD:
WDTE =WDT_CLR; // Watch clr
I2cReceive16(addr,PubVar.BuffWr,length);
I2cReceive16(addr,PubVar.BuffRd,length);
for(i=0;i<length;i++)
{
if(PubVar.BuffWr[i] != PubVar.BuffRd[i])
{
if(++RdCnt>=100)
{
PubVar.E2Erro = 1;
}
else
goto REPEAT_RD;
}
}
CopyRam(PubVar.BuffWr,dataP ,length);
}
/***************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -