⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2csw.c

📁 NEC单片机开发资料 NEC单片机开发资料 NEC单片机开发资料
💻 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 + -