模拟IIC通信

发布时间:2024年01月17日

模拟IIC通信

底层接口

device是可以用来增加多个IIC设备管理的

void I2C_SET_SCL(unsigned char device, unsigned char bit_value)
{
	bit_value ? MCU_SCL_H() : MCU_SCL_L(); 
}

void I2C_SET_SDA(unsigned char device, unsigned char bit_value)
{
	bit_value ? MCU_SDA_H() : MCU_SDA_L();
}

void I2C_SDA_OUT(unsigned char device)
{
 	MCU_SDA_OUT(); 
}

void I2C_SDA_IN(unsigned char device)
{
 	MCU_SDA_IN(); 
}

bool I2C_SDA_DATA(unsigned char device)
{
    bool boolDat = 0;
 	boolDat = MCU_SDA_DATA();
    return boolDat;
}

时间控制(通信速度)

void i2c_delay_us(unsigned int us)
{
    unsigned int i, j;
    for (i = 0; i <= us; i++)
    {
        for (j = 0; j <= 20; j++);
    }
}

功能实现

/* I2C CODE  */
#define i2c_speed_time1 40
#define i2c_speed_time2 20
#define i2c_speed_time3 20

void I2C_Start(unsigned char device)
{
    I2C_SDA_OUT(device);
    I2C_SET_SDA(device, 1);
    I2C_SET_SCL(device, 1);
    i2c_delay_us(i2c_speed_time1);
    I2C_SET_SDA(device, 0);
    i2c_delay_us(i2c_speed_time1);
    I2C_SET_SCL(device, 0);
    I2C_SET_SCL(device, 0);
}

void I2C_Stop(unsigned char device)
{
    I2C_SDA_OUT(device);
    I2C_SET_SCL(device, 0);
    I2C_SET_SDA(device, 0);
    i2c_delay_us(i2c_speed_time1);
    I2C_SET_SCL(device, 1);
    I2C_SET_SDA(device, 1);
    i2c_delay_us(i2c_speed_time1);
}

unsigned char I2C_Wait_Ack(unsigned char device)
{
    unsigned char ucErrTime = 0;

    I2C_SDA_IN(device);
    i2c_delay_us(i2c_speed_time2);
    I2C_SET_SCL(device, 1);
    i2c_delay_us(i2c_speed_time2);
    while(I2C_SDA_DATA(device))
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            I2C_Stop(device);
            return 1;
        }
    }
    I2C_SET_SCL(device, 0);

    return 0;
}

void I2C_Ack(unsigned char device)
{
    I2C_SET_SCL(device, 0);
    I2C_SDA_OUT(device);
    I2C_SET_SDA(device, 0);
    i2c_delay_us(i2c_speed_time3);
    I2C_SET_SCL(device, 1);
    i2c_delay_us(i2c_speed_time3);
    I2C_SET_SCL(device, 0);
}

void I2C_NAck(unsigned char device)
{
    I2C_SET_SCL(device, 0);
    I2C_SDA_OUT(device);
    I2C_SET_SDA(device, 1);
    i2c_delay_us(i2c_speed_time3);
    I2C_SET_SCL(device, 1);
    i2c_delay_us(i2c_speed_time3);
    I2C_SET_SCL(device, 0);
}

void I2C_Send_Byte(unsigned char device, unsigned char txd)
{
    unsigned char t;

    I2C_SDA_OUT(device);
    I2C_SET_SCL(device, 0);

    for(t=0; t<8; t++)
    {
        if(txd & 0x80)
        {
            I2C_SET_SDA(device, 1);
        }
        else
        {
            I2C_SET_SDA(device, 0);
        }
        txd <<= 1;
        i2c_delay_us(i2c_speed_time3);
        I2C_SET_SCL(device, 1);
        i2c_delay_us(i2c_speed_time3);
        I2C_SET_SCL(device, 0);
        i2c_delay_us(i2c_speed_time3);
    }
}

unsigned char I2C_Read_Byte(unsigned char device, unsigned char ack)
{
    unsigned char i,receive=0;
    I2C_SDA_IN(device);
    for(i=0; i<8; i++)
    {
        I2C_SET_SCL(device, 0);
        i2c_delay_us(i2c_speed_time3);
        I2C_SET_SCL(device, 1);
        receive <<= 1;
        if(I2C_SDA_DATA(device))
        {
            receive++;
        }
        i2c_delay_us(i2c_speed_time3);
    }
    if(!ack)
    {
        I2C_NAck(device);
    }
    else
    {
        I2C_Ack(device);
    }
    return receive;
}

对外接口

unsigned char i2c_write_byte(unsigned char addr, unsigned char offset, unsigned char len, unsigned char *pdata, unsigned char device)
{
    unsigned char i;

    I2C_Start(device);
    I2C_Send_Byte(device, addr);

    I2C_Wait_Ack(device);
    I2C_Send_Byte(device, offset);
    I2C_Wait_Ack(device);

    for (i=0; i<len-1; i++)
    {
        I2C_Send_Byte(device, *pdata);
        I2C_Wait_Ack(device);
        pdata++;
    }

    I2C_Send_Byte(device, *pdata);
    I2C_Wait_Ack(device);
    I2C_Stop(device);

    return 1;
}

unsigned char i2c_read_byte(unsigned char addr, unsigned char offset, unsigned char len, unsigned char *pdata,unsigned char ack,unsigned char device)
{
    unsigned char i;

    I2C_Start(device);
    I2C_Send_Byte(device, addr);
    I2C_Wait_Ack(device);
    I2C_Send_Byte(device, offset);
    I2C_Wait_Ack(device);
    I2C_Start(device);
    I2C_Send_Byte(device, addr|0x01);
    I2C_Wait_Ack(device);

    for (i=0; i<len-1; i++)
    {
        *pdata = I2C_Read_Byte(device, ack);
        pdata++;
    }
    *pdata = I2C_Read_Byte(device, 0);

    I2C_Stop(device);

    return 1;
}

/* 连续读,无应答 */
void I2C_ReadBurst_Ack(unsigned char addr,unsigned char offset,unsigned char len,unsigned char* pdata,unsigned char device)
{
    i2c_read_byte( addr, offset, len, pdata, 0, device);
}

/* 连续读,有应答 */
void I2C_ReadBurst_NAck(unsigned char addr,unsigned char offset,unsigned char len,unsigned char* pdata,unsigned char device)
{
    i2c_read_byte( addr, offset, len, pdata, 1, device );
}

/* 连续写 */
void I2C_WriteBurst(unsigned char addr,unsigned char offset,unsigned char len,unsigned char* pdata,unsigned char device)
{
    i2c_write_byte( addr, offset, len, pdata, device );
}

/* 单个读 */
unsigned char I2C_ReadByte(unsigned char addr, unsigned char offset,unsigned char device)
{
    unsigned char u8RdData;

    i2c_read_byte( addr, offset, 1, &u8RdData, 0, device );

    return u8RdData;
}

/* 单个写 */
void I2C_WriteByte(unsigned char addr, unsigned char offset, unsigned char u8Data,unsigned char device)
{
    i2c_write_byte( addr, offset, 1, &u8Data, device );
}

EEPROM相关

/* EEPROM */
unsigned char EEPROM_ReadByte(unsigned short int addr, unsigned char device)
{
    unsigned char temp = 0;

    I2C_Start(device);
    I2C_Send_Byte(device, 0XA0);
    I2C_Wait_Ack(device);
    I2C_Send_Byte(device, addr);
    I2C_Wait_Ack(device);
    I2C_Start(device);
    I2C_Send_Byte(device, 0XA1);
    I2C_Wait_Ack(device);
    temp = I2C_Read_Byte(device, 0);
    I2C_Stop(device);

    return temp;
}

void EEPROM_WriteByte(unsigned char addr, unsigned char dat, unsigned char device)
{
    i2c_delay_us(2);

    I2C_Start(device);
    I2C_Send_Byte(device, 0XA0);
    I2C_Wait_Ack(device);
    I2C_Send_Byte(device, addr);
    I2C_Wait_Ack(device);
    I2C_Send_Byte(device, dat);
    I2C_Wait_Ack(device);
    I2C_Stop(device);

    delay_ms(5); // 延时
}

void EEROM_WriteNByte(const unsigned char *pbuf, unsigned char device)
{
    int iCurNum, iCur8ByteNum ;

    for (iCurNum = 0; iCurNum < 32; iCurNum ++ )
    {
        I2C_Start(device);
        I2C_Send_Byte(device, 0XA0);
        I2C_Wait_Ack(device);
        I2C_Send_Byte(device, iCurNum * 8);
        I2C_Wait_Ack(device);
        for (iCur8ByteNum = 0; iCur8ByteNum < 8; iCur8ByteNum ++)
        {
            I2C_Send_Byte(device, pbuf[iCurNum * 8+iCur8ByteNum]);
            I2C_Wait_Ack(device);
        }
        I2C_Stop(device);
    }
}

文章来源:https://blog.csdn.net/weixin_42831633/article/details/135650030
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。