单总线、IIC、SPI接口详解(二)

上篇已经描述了单总线的优缺点,以及单总线传输机制和程序的编写。接下来这篇需要来讲解IIC。先简单列举采用IIC的设备,如温湿度传感器SHT20,陀螺仪MPU6050,液晶显示屏oled,存储芯片24C02等等。

二、IIC

IIC为I2C Bus的简称,也叫集成电路总线。I2C串行总线上一般有两根信号线,一根双向数据线SDA,一根时钟线SCL。I2C设备通常可以挂载多个,将I2C设备的串行数据SDA接在总线的SDA上,各设备的时钟线SCL接到总线的SCL上。绝大多数I2C设备都有一个固话的地址,只有线上传输的地址等于设备地址时,设备才会响应主机信号。主设备在很多时间都是控制SCL线的,而从设备一般只会拉低SCL用来延长总线的时钟周期信号。

接下来都以SHT2x(SHT20,SHT21等)为例,该传感器体积很小,采用DFN的封装,且可达到14bit精度。

与传感器的通讯。

1、首先通过其数据手册可以发现,所有的该传感器的I2C地址都一致(1000000)。

2、此传感器在上电之后需要至多15ms的等待时间将传感器达到空闲状态。

3、每次传输都以Start状态为开始,以Stop状态为结束。

开始传输状态,当SCL为高电平时,SDA由高电平转换为低电平。由主机控制,指示从机传输开始。

停止传输状态,当SCL为高电平时,SDA由低电平转换为高电平。由主机控制,指示从机传输结束。

程序部分:

  1. void IIC_Init(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure; //先使能外设IO PORTC时钟 
  4.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
  5.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
  6.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
  7.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  8.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  9.     IIC_SCL=1;
  10.     IIC_SDA=1;
  11. }
  12. //产生IIC起始信号
  13. void IIC_Start(void)
  14. {
  15.     SDA_OUT();     //sda线输出
  16.     IIC_SDA=1;
  17.     IIC_SCL=1;
  18.     delay_us(4);
  19.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
  20.     delay_us(4);
  21.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
  22.     delay_us(4);
  23. }
  24. //产生IIC停止信号
  25. void IIC_Stop(void)
  26. {
  27.     SDA_OUT();//sda线输出
  28.     IIC_SCL=0;
  29.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  30.     delay_us(4);
  31.     IIC_SCL=1;
  32.     delay_us(1);
  33.     IIC_SDA=1;//发送I2C总线结束信号
  34.     delay_us(4);
  35. }

4、启动传输之后,先将I2C设备地址(7位)以及SDA的方向位(1位,读为1,写为0)发送。在第八个SCL时钟的下降沿时,

从机通过拉低SDA引脚,指示传感器数据传输正常,即ACK位。SHT2X工作模式分为主机模式和非主机模式,可以通过单片机

改变传感器的工作模式。方法如下,

①主机模式下,在传感器测量过程中,SCL线被封锁。即单片机不能操作SCL线,单片机便不能对传感器传输数据。

②非主机模式下,当传感器在执行测量任务时,SCL线仍保持开放状态,可由单片机操作。

非主机模式下,传输方式如图。图中灰色部分由SHT2X控制。

由于测量的最大分辨率为14bit,所以第二字节的SDA上的后两位(bit43和bit44),用来表示传输的信息,

bit43表示测量的类型(0表示温度,1表示湿度)。

程序源码:

  1. float SHT2x_GetTempPoll(void)
  2. {
  3.     float TEMP;
  4.     u8 ack, tmp1, tmp2;
  5.     u16 ST;
  6.     u16 i=0;
  7.     IIC_Start();                //发送IIC开始信号
  8.     IIC_Send_Byte(I2C_ADR_W);           //IIC发送一个字节 
  9.     ack = IIC_Wait_Ack();
  10.     IIC_Send_Byte(TRIG_TEMP_MEASUREMENT_POLL);
  11.     ack = IIC_Wait_Ack();
  12.     do {
  13.         delay_ms(100);
  14.         IIC_Start();                //发送IIC开始信号
  15.         IIC_Send_Byte(I2C_ADR_R);
  16.     i++;
  17.     ack = IIC_Wait_Ack();
  18.     if(i==1000)break;
  19.     } while(ack!=0);
  20.     tmp1 = IIC_Read_Byte(1);
  21.     tmp2 = IIC_Read_Byte(1);
  22.     IIC_Read_Byte(0);
  23.     IIC_Stop();
  24.     ST = (tmp1 << 8) | (tmp2 << 0);
  25.     ST &= ~0x0003;
  26.     TEMP = ((float)ST * 0.00268127) - 46.85;
  27.     return (TEMP);
  28. }
  29. float SHT2x_GetHumiPoll(void)
  30. {
  31.     float HUMI;
  32.     u8 ack, tmp1, tmp2;
  33.     u16 SRH;
  34.     u16 i=0;
  35.     IIC_Start();                //发送IIC开始信号
  36.     IIC_Send_Byte(I2C_ADR_W);           //IIC发送一个字节 
  37.     ack = IIC_Wait_Ack();
  38.     IIC_Send_Byte(TRIG_HUMI_MEASUREMENT_POLL);
  39.     ack = IIC_Wait_Ack();
  40.     do {
  41.        delay_ms(100);
  42.         IIC_Start();                //发送IIC开始信号
  43.         IIC_Send_Byte(I2C_ADR_R);
  44.     i++;
  45.     ack = IIC_Wait_Ack();
  46.     if(i==100)break;
  47.     } while(ack!=0);
  48.     tmp1 = IIC_Read_Byte(1);
  49.     tmp2 = IIC_Read_Byte(1);
  50.     IIC_Read_Byte(0);
  51.     IIC_Stop();
  52.     SRH = (tmp1 << 8) | (tmp2 << 0);
  53.     SRH &= ~0x0003;
  54.     HUMI = ((float)SRH * 0.00190735) - 6;
  55.     return (HUMI);
  56. }

5、软复位

该命令用于无需关闭和再次打开电源的情况下,重新启动传感器系统。接收到这个命令之后, 传感器系统开始重新初始化,并恢复默认设置状态。

  1. u8 SHT2x_SoftReset(void//SHT20软件复位
  2. {
  3.     u8 err=0;
  4.     IIC_Start();
  5.      IIC_Send_Byte(0x80);
  6.     err = IIC_Wait_Ack();
  7.     IIC_Send_Byte(0xFE);
  8.     err = IIC_Wait_Ack();
  9.     IIC_Stop();
  10.     return err;
  11. }

 

 

波波

发表评论

您必须 登录 才能发表留言!