您的位置:首页 > 其它

GPIO模拟i2c时序

2016-11-28 09:26 405 查看

#define DELAY   1

/******************************start*****************************************/

void i2c_start(void)

{

    gpio_direction_output(SDA, 1);

    gpio_direction_output(SCL, 1);

    udelay(DELAY);

    gpio_set_value(SDA, 0);

    udelay(DELAY);

            

    gpio_set_value(SCL, 0);

    udelay(DELAY);  

}

/**********************************************stop****************************************/

void i2c_stop(void)

{

    gpio_set_value(SCL, 0);  

    gpio_set_value(SDA, 0);

    udelay(DELAY);  

    gpio_set_value(SCL, 1);  

    udelay(DELAY);

    gpio_set_value(SDA, 1);  

    udelay(DELAY);

}  

/********************************send_ack****************************************/

void i2c_send_ack(u8 ack)

{

    if(ack)

        gpio_direction_output(SDA, 1);

    else

        gpio_direction_output(SDA, 0);

    udelay(DELAY);

    gpio_set_value(SCL, 1);  

    udelay(DELAY);

      

    gpio_set_value(SCL, 0);  

    udelay(DELAY);

}  

/********************************receive_ack*********************************/

u8 i2c_receive_ack(void)  

{  

    u8 rc = 0;

      

    gpio_direction_input(SDA);  

    gpio_set_value(SCL, 1);

    udelay(DELAY);  

      

    if(gpio_get_value(SDA)) {

        rc = 1;  

    }  

    gpio_set_value(SCL, 0);

    gpio_direction_output(SDA, 1);                

    return rc;  

}

/********************************send****************************************/

u8 i2c_send_byte(u8 send_byte)  

{  

    u8 rc = 0;  

    u8 out_mask = 0x80;

    u8 value;  

    u8 count = 8;  

    while(count > 0) {                  

        value = ((send_byte & out_mask) ? 1 : 0);     

        if (value == 1) {                                     

            gpio_set_value(SDA, 1);       

        }

        else {                                    

            gpio_set_value(SDA, 0);  

        }      

        udelay(DELAY);  

        gpio_set_value(SCL, 1);

        udelay(DELAY);  

                       

        gpio_set_value(SCL, 0);

        udelay(DELAY);  

                    

        out_mask >>= 1;        

        count--;         

    }  

      

    gpio_set_value(SDA, 1);    

    rc = i2c_receive_ack();

    return rc;  

}  

/**********************************************receive*************************************/

void i2c_read_byte(u8 *buffer, u8 ack)  

{  

    u8 count = 0x08;  

    u8 data = 0x00;  

    u8 temp = 0;  

    gpio_direction_input(SDA);   

    while(count > 0) {

        gpio_set_value(SCL, 1);  

        udelay(DELAY);  

        temp = gpio_get_value(SDA);       

        data <<= 1;  

        if (temp)  

            data |= 0x01;  

        gpio_set_value(SCL, 0);  

        udelay(DELAY);  

        count--;  

    }  

    i2c_send_ack(ack);//0 = ACK    1 = NACK   

    *buffer = data;

}  

//向client的某个寄存器写入多个字节,len是要写入的数据的长度   

/***********************************************write_bytes********************************/

u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)

{

    u8 rc = 0;

    u8 i;

    i2c_start();

      

    rc |= i2c_send_byte( (device_id << 1) | 0x00 );  

    rc |= i2c_send_byte(reg_address);

    if(data==NULL ||0==len) {

        i2c_stop();  

        return rc;  

    }

          

    for(i=0; i<len; i++) {

        rc |= i2c_send_byte(*data);  

        data++;  

    }

    i2c_stop();

    return rc;

}

//从某个register中读取len个字节放在长度为len的缓冲区buffer中   

/***********************************************read_bytes********************************/

u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u16 len)

{

    u8 rc = 0;

    u16 i;  

    i2c_start();

    rc |= i2c_send_byte( (device_id << 1) | 0x00 );

    rc |= i2c_send_byte(reg_address);  

    i2c_start();//restart I2C      

    rc |= i2c_send_byte( (device_id << 1) | 0x01 );

    for(i=0;i<len;i++) {  

        i2c_read_byte(buffer++, !(len-i-1));//  !(len-i-1)  这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK

    }

    i2c_stop();   

    return rc;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: