stm32通过I2C接口实现温湿度(AHT20)的采集

1、I2C 简介
I2C 是很常见的一种总线协议, I2C 是 NXP 公司设计的, I2C 使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线),另外一条是 SDA(串行数据线),这两条数据线需要接上拉电阻,总线空闲的时候 SCL 和 SDA 处于高电平。 I2C 总线标准模式下速度可以达到 100Kb/S,快速模式下可以达到 400Kb/S。 I2C 总线工作是按照一定的协议来运行的,接下来就看一下 I2C 协议。

2、I2C 协议
I2C 是支持多从机的,也就是一个 I2C 控制器下可以挂多个 I2C 从设备,这些不同的 I2C从设备有不同的器件地址,这样 I2C 主控制器就可以通过 I2C 设备的器件地址访问指定的 I2C设备了,一个 I2C 总线连接多个 I2C 设备如下图所示:
stm32通过I2C接口实现温湿度(AHT20)的采集_第1张图片

上图中 SDA 和 SCL 这两根线必须要接一个上拉电阻,一般是 4.7K。其余的 I2C 从器件都挂接到 SDA 和 SCL 这两根线上,这样就可以通过 SDA 和 SCL 这两根线来访问多个 I2C设备。

3.I2C 的特点

I2C总线具有以下特点:

只需要SDA、SCL两条总线;
没有严格的波特率要求;
所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;
I2C是真正的多主设备总线,可提供仲裁和冲突检测;
传输速度分为四种模式:
标准模式(Standard Mode):100 Kbps
快速模式(Fast Mode):400 Kbps
高速模式(High speed mode):3.4 Mbps
超快速模式(Ultra fast mode):5 Mbps
最大主设备数:无限制;
最大从机数:理论上,1008个从节点,寻址模式的最大节点数为2的7次方或2的10次方,但有16个地址保留用于特殊用途。
I2C有16个保留I2C地址。这些地址对应于以下两种模式之一:0000 XXX或1111 XXX。下表显示了为特殊目的而保留的I2C地址。

I2C 节点地址    R/W    位功能描述
0000 000    0    广播地址
0000 000    1    起始字节
0000 001    X    CBUS 地址
0000 010    X    保留用于不同总线格式
0000 011    X    保留供未来使用
0000 1XX    X    高速模式主代码
1111 1XX    X    保留供未来使用
1111 0XX    X    10位节点地址
I2C还有两个变体,分别专注于系统和电源应用,称为系统管理总线(SMBus)和电源管理总线(PMBus)

4、I2C的两种方式——硬件I2C和软件I2C
①硬件I2C
直接利用 STM32 芯片中的硬件 I2C 外设。

硬件I2C的使用
只要配置好对应的寄存器,外设就会产生标准串口协议的时序。在初始化好 I2C 外设后,只需要把某寄存器位置 1,此时外设就会控制对应的 SCL 及 SDA 线自动产生 I2C 起始信号,不需要内核直接控制引脚的电平。

②软件I2C
直接使用 CPU 内核按照 I2C 协议的要求控制 GPIO 输出高低电平,从而模拟I2C。

软件I2C的使用
需要在控制产生 I2C 的起始信号时,控制作为 SCL 线的 GPIO 引脚输出高电平,然后控制作为 SDA 线的 GPIO 引脚在此期间完成由高电平至低电平的切换,最后再控制SCL 线切换为低电平,这样就输出了一个标准的 I2C 起始信号。

③两者的差别
硬件 I2C 直接使用外设来控制引脚,可以减轻 CPU 的负担。不过使用硬件I2C 时必须使用某些固定的引脚作为 SCL 和 SDA,软件模拟 I2C 则可以使用任意 GPIO 引脚,相对比较灵活。对于硬件I2C用法比较复杂,软件I2C的流程更清楚一些。如果要详细了解I2C的协议,使用软件I2C可能更好的理解这个过程。在使用I2C过程,硬件I2C可能通信更加快,更加稳定。

二、AHT20采集程序

1.AHT20相关资料

AHT20

2.主要代码分析

1、主函数代码

#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"


int main(void)
{    
    delay_init();     
    uart_init(115200);    //串口通信波特率115200
    IIC_Init();
        while(1)
    {
        printf("温度湿度显示");
        read_AHT20_once();
        delay_ms(1500);
  }
}

2、模块读取函数

void  read_AHT20_once(void)
{
    delay_ms(10);

    reset_AHT20();//重置AHT20芯片
    delay_ms(10);

    init_AHT20();//初始化AHT20芯片
    delay_ms(10);

    startMeasure_AHT20();//开始测试AHT20芯片
    delay_ms(80);

    read_AHT20();//读取AHT20采集的到的数据
    delay_ms(5);
}

3、I2C读取及输出温湿度函数

void read_AHT20(void)
{
    uint8_t   i;

    for(i=0; i<6; i++)
    {
        readByte[i]=0;
    }
    I2C_Start();//I2C启动

    I2C_WriteByte(0x71);//I2C写数据
    ack_status = Receive_ACK();//收到的应答信息
    readByte[0]= I2C_ReadByte();//I2C读取数据
    Send_ACK();//发送应答信息

    readByte[1]= I2C_ReadByte();
    Send_ACK();

    readByte[2]= I2C_ReadByte();
    Send_ACK();

    readByte[3]= I2C_ReadByte();
    Send_ACK();

    readByte[4]= I2C_ReadByte();
    Send_ACK();

    readByte[5]= I2C_ReadByte();
    SendNot_Ack();
    //Send_ACK();

    I2C_Stop();//I2C停止函数
    //如果读取过程没有问题,就对读到的数据进行相应的处理
    if( (readByte[0] & 0x68) == 0x08 )
    {
        H1 = readByte[1];
        H1 = (H1<<8) | readByte[2];
        H1 = (H1<<8) | readByte[3];
        H1 = H1>>4;

        H1 = (H1*1000)/1024/1024;

        T1 = readByte[3];
        T1 = T1 & 0x0000000F;
        T1 = (T1<<8) | readByte[4];
        T1 = (T1<<8) | readByte[5];

        T1 = (T1*2000)/1024/1024 - 500;

        AHT20_OutData[0] = (H1>>8) & 0x000000FF;
        AHT20_OutData[1] = H1 & 0x000000FF;

        AHT20_OutData[2] = (T1>>8) & 0x000000FF;
        AHT20_OutData[3] = T1 & 0x000000FF;
    }
    else
    {
        AHT20_OutData[0] = 0xFF;
        AHT20_OutData[1] = 0xFF;

        AHT20_OutData[2] = 0xFF;
        AHT20_OutData[3] = 0xFF;
        printf("读取失败");

    }
    printf("\r\n");
    //根据温度和湿度的计算公式,计算后输出结果,通过串口发送到上位机显示
    printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
    printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
    printf("\r\n");
}

三、总结

初步了解了AHT20 和I2C协议,在程序正确和硬件连接正确的情况下,温湿度传感器会输出数据,当用手捂住传感器时,可发现串口调试中的数据会发生变化。

四、参考资料

  1. AHT20温度采集
  2. 完整代码

你可能感兴趣的:(stm32,单片机,arm)