DM6437 GPIO模拟I2C

DM6437只有一个I2C总线,由于挂在总线上的摄像头的影响,导致不能正常读取ADS1000芯片,具体原因未能查明。现在只能用GPIO去模拟I2C总线。
下面是ADS1000中的I2C的介绍关键的说明:
这里写描述
之前由于没有注意到在SCL为高的时候不能更改状态,导致连续读取字节的时候只是正常读取了一个或两个字节(最后输出的高低有影响)。
下面是具体的程序代码:



#define SET_SCL_HIGH    EVMDM6437_GPIO_setOutput(SCL,1);
#define SET_SCL_LOW     EVMDM6437_GPIO_setOutput(SCL,0);

#define SET_SDA_HIGH    {\
                        EVMDM6437_GPIO_setOutput(SDA,1);\
                        }
#define SET_SDA_LOW     {\
                        EVMDM6437_GPIO_setOutput(SDA,0);\
                        }

//typedef EVMDM6437_GPIO_setDir(SDA,GPIO_IN);EVMDM6437_GPIO_getInput(SDA);  SET_SDA_HIGH
//typedef   EVMDM6437_GPIO_setDir(SDA,GPIO_OUT);EVMDM6437_GPIO_setOutput(SDA,0); SET_SDA_LOW


#ifdef  __cplusplus
extern "C" {
#endif



extern void i2c_read(unsigned char addr, unsigned char *buf, int len);

extern void i2c_write(unsigned char addr, unsigned char *buf, int len);

#ifdef  __cplusplus
}
#endif

#endif
inline int i2c_start()
{
    EVMDM6437_GPIO_setDir(SCL,GPIO_OUT);
    EVMDM6437_GPIO_setDir(SDA,GPIO_OUT);
    SET_SDA_HIGH
    SET_SCL_HIGH
    _waitusec(20);
    SET_SDA_LOW
    _waitusec(20);
    //SET_SCL_LOW
}


inline void i2c_stop(void)
{
    //SET_SCL_LOW
    // SET_SDA_LOW
    //_waitusec(10);
    EVMDM6437_GPIO_setDir(SDA,GPIO_OUT);
    SET_SCL_HIGH
    SET_SDA_LOW
    _waitusec(10);      
    SET_SDA_HIGH
    //_waitusec(10);
}


inline unsigned char i2c_read_ack(void)
{
    unsigned char r;
    EVMDM6437_GPIO_setDir(SDA,GPIO_IN);
    _waitusec(10);
    SET_SCL_LOW
    _waitusec(10);
    r = EVMDM6437_GPIO_getInput(SDA); 
    SET_SCL_HIGH
    _waitusec(10);
    if(r)
    {
        //printf("wrong!\n");
    }
    return r;
}


inline int i2c_send_ack(void)
{
    SET_SCL_LOW 

    EVMDM6437_GPIO_setDir(SDA,GPIO_OUT);
    SET_SDA_LOW
    //_waitusec(10);
    SET_SCL_HIGH
    _waitusec(5);
}


void i2c_write_byte(unsigned char b)
{
    int i;
    EVMDM6437_GPIO_setDir(SDA,GPIO_OUT);
    for(i = 7; i >= 0; i--)
    {
        SET_SCL_LOW
        _waitusec(5);
        if( b & (1 << i))
        {
            SET_SDA_HIGH
        }
        else
        {
            SET_SDA_LOW
        }
        _waitusec(5);
        SET_SCL_HIGH    
        _waitusec(10);

    }
    i2c_read_ack();
}


unsigned char i2c_read_byte(void)
{
    int i;
    unsigned char r = 0;
    EVMDM6437_GPIO_setDir(SDA,GPIO_IN);
    for(i = 7; i >= 0; i--)
    {
        SET_SCL_LOW
        _waitusec(5);

        r = (r << 1) | EVMDM6437_GPIO_getInput(SDA);
        SET_SCL_HIGH
        _waitusec(5);
    }

    i2c_send_ack();

    return r;
}


void i2c_read(unsigned char addr, unsigned char *buf, int len)
{
    int i;
    unsigned char t;
    i2c_start();
    t = (addr << 1) | 1;
    i2c_write_byte(t);

    for(i = 0; i < len; i++)
    {
        buf[i] = i2c_read_byte();
    }
    i2c_stop();
}   


void i2c_write(unsigned char addr, unsigned char *buf, int len)
{
    int i;
    unsigned char t;
    i2c_start();
    t = (addr << 1) | 0;
    i2c_write_byte(t);

    for(i = 0; i < len; i ++)
    {
        i2c_write_byte(buf[i]);

    }
    i2c_stop();
}

发布了27 篇原创文章 · 获赞 8 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/liu1guo2qiang3/article/details/46780017
I2C