浅谈I2c原理

来源:互联网 发布:statistica软件下载 编辑:程序博客网 时间:2024/05/06 19:57

i2c接口连接微控制器和串行i2c总线。支持多主和多从之间通信的协议,主设备通常叫做master,从设备叫做slaver,支持两种不同的通信速度,标准为速度(最高位100kHZ),快速(最高为400kHZ).
通信原理:
这里写图片描述
i2c接口与数据总线之间有两个引脚线,一个是SDA线,一个是SCL线。
起始条件后,紧跟从设备的地址,高七位是地址,后一位代表read/write,每传送完一个字节,相应的从设备要发送ACK和NACK来应答,ACK代表低电平,NACK代表高电平。下面我们就要GPIO来模拟i2c的通信。

void gpio_i2c_start(void){  SDA_MODE_OUT;  SCL_LOW;   delay_us(5);    SDA_HIGH;  delay_us(10);   SCL_HIGH;    delay_us(10);  SDA_LOW;  delay_us(10);   }  以上是发送开始信号,当scl高电平时,sda由高电平向低电平转化,表示开始条件,开始传送数据,在传送过程中scl一直都是低电平,sda才能稳定地采集数据,总线一直处于一直忙状态。  然后开始写数据
uint8_t gpio_i2c_write_byte(uint8_t byte){  int             i;  uint8_t         rv = I2C_ACK;  SDA_MODE_OUT;  /* SCL为低电平时,SDA线才能改变传输的bit; SCL为高电平时,SDA线保持稳定 */  for(i=7; i>=0; i--) /* MSB */  {    /*MSB: 输出相应位的电平信号 */    if( byte&(1<<i) )      SDA_HIGH;    else      SDA_LOW;    delay_us(2);    SCL_HIGH;    delay_us(5);        SCL_LOW;    delay_us(5);  }  rv = gpio_i2c_wait_ack();  return rv;}
uint8_t gpio_i2c_wait_ack(void){  uint8_t    rv;  uint8_t    times = 200;    SDA_MODE_IN;  /* 时钟线拉高 */  SCL_HIGH;  delay_us(5);    do  {    times --;  } while ( (SDA_DAT==1) && (times!=0) );  if( !times )  {    /* 等待 ACK 超时,接收到NAK */    rv = I2C_NAK;    goto OUT;  }  /* 等到ACK */  SCL_LOW;  delay_us(5);  rv = I2C_ACK;OUT:    return rv;}

然后发送停止信号:

void gpio_i2c_stop(void){  SDA_MODE_OUT;      SCL_LOW;  delay_us(5);   SDA_LOW;  delay_us(10);   SCL_HIGH;  delay_us(10);  SDA_HIGH;  delay_us(10);}

假如我们要发送一个buf,首先发送地址:

int gpio_i2c_write(uint8_t addr, uint8_t *buf, int len){  int       i;  int       rv = I2C_OK;    gpio_i2c_start();  /*低位为0表示写数据*/  if( I2C_ACK != gpio_i2c_write_byte( (addr)|I2C_DIR_WRITE ) )  {    rv = I2C_ERROR;    goto OUT;    }  for (i=0; i<len; i++)    {    if( I2C_ACK != gpio_i2c_write_byte(buf[i]) )    {      rv = I2C_ERROR;      break;    }  }OUT:    gpio_i2c_stop();  return rv;  }
0 0
原创粉丝点击