【elfboard linux开发板】7.i2C工具应用与aht20温湿度寄存器读取
1. I2C工具查看aht20的温湿度寄存器值
1.1 原理图
传感器通过IIC方式进行通信,连接的为IIC1总线,且设备地址为0x38,实际上通过后续iic工具查询,这个设备是挂载在iic-0上

1.2 I2C工具
通过i2c工具可以实现查询i2c总线、以及上面挂载的设备以及设备的寄存器值。
 a. 下载安装:
可以通过IIC工具地址进行下载,或以下命令下载(慢):
git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
- 下载后,复制到相关文件夹下,按ctrl+alt+t打开终端,通过
tar -zxvf解压缩
cd i2c-tools-4.3目录下,下载版本不同,名称可能不一样
vi Makefile将下列三行改写为:前–>后
CC ?= gcc-->#CC ?= gcc
AR ?= ar–>#AR ?= ar
STRIP ?= strip-->#STRIP ?= strip
make编译后会在./tools/下生成可执行文件

- 将i2cdetect、i2cdump、i2cget、i2cset、i2ctransfer等工具拷贝到开发板的/usr/bin目录下
- 并且将对应的i2c工具依赖的库拷贝到开发板的/usr/lib下
i2c工具介绍:
i2cdetect
-V 输出版本
-y 接i2c序号,检测挂载在i2c总线上的器件
-l 打印i2c总线
-F MODE_FUNC
-r MODE_READ
-q MODE_QUICK
-a 设置扫描的地址从0x00到0x7F
iic1上有在0x1a位置上有挂载设备和驱动;UU表示既有设备也有驱动;
i2cdump:
i2cdump -f -y 1 0x1a 查看挂载在i2c1的设备0x1a的寄存器的值
i2ctransfer
格式为:i2ctransfer -f -y iic序号 w[number]@设备地址 命令 参数 r[number2]
number 为写入的字节数,number2为读取的字节数
AHT20的命令介绍:
初始化 0xBE(1011’ 1110)
触发测量 0xAC
软复位 0xBA
状态字用来判断寄存器的状态,具体对应如下:
| bit[7] | bit[6] | bit[5] | bit[4] | bit[3] | bit[2] | bit[1] | bit[0] | 
|---|---|---|---|---|---|---|---|
| 1-测量中 0-休眠 | 1-已校准 0- 未校准 | 
传感器读取流程:
- 上电后等待40ms, 通过0x71命令查看状态字的bit[3]是否为1,如果不为1,初始化(发送0xBE命令,命令有两个参数,分别为0x08与0x00,然后,等待10ms
- 启动测量(发送0xAC命令,有两个参数,分别为0x33与0x00)
- 等待80ms, 通过0x71命令读取状态字,bit[7]处于休眠态,说明测量完成,然后读取6个字节;如果bit[7]处于测量中,则继续等待;
- 发送应答位
- 接收数据,通过下列公式计算温湿度
 
     
      
       
       
         V 
        
       
         a 
        
       
         l 
        
       
         u 
        
        
        
          e 
         
        
          湿度 
         
        
       
         = 
        
        
         
         
           v 
          
         
           a 
          
         
           l 
          
         
           u 
          
          
          
            e 
           
           
           
             r 
            
           
             e 
            
           
             g 
            
           
             1 
            
           
          
         
         
         
           2 
          
         
           20 
          
         
        
       
         100 
        
       
      
        Value_{湿度}=\frac{value_{reg1}}{2^{20}}100 
       
      
    Value湿度?=220valuereg1??100
  
     
      
       
       
         V 
        
       
         a 
        
       
         l 
        
       
         u 
        
        
        
          e 
         
        
          温度 
         
        
       
         = 
        
        
         
         
           v 
          
         
           a 
          
         
           l 
          
         
           u 
          
          
          
            e 
           
           
           
             r 
            
           
             e 
            
           
             g 
            
           
             2 
            
           
          
         
         
         
           2 
          
         
           20 
          
         
        
       
         200 
        
       
         ? 
        
       
         50 
        
       
      
        Value_{温度} = \frac{value_{reg2}}{2^{20}}200-50 
       
      
    Value温度?=220valuereg2??200?50
应用
1.初始化
i2ctransfer -f -y 0 w3@0x38 0xbe 0x08 0x00
2. 开始测量:
i2ctransfer -f -y 0 w3@0x38 0xAC 0x33 0x00
3. 读取值
i2ctransfer -f -y 0 w1@0x38 0x71 r7
补充说明:
 Makefile的四种赋值运算符
= 赋值,可以使用后面定义的变量
:= 就地直接解析,只能使用前面定义好的变量
?=没有被赋值则进行赋值,赋值过则忽略
+=追加赋值
2. 使用安装好的驱动读取温湿度传感器的值
通过进程的方式获取iic总线挂载的设备,与iic设备寄存器的值后(实际上可以不用前面这些,直接循环读取就行),循环读取并计算温湿度传感器的值
 注意:
 execlp执行完,后续的将不会执行,因此,交给子进程单独执行该命令,在父进程中等待回收完子进程后,执行后续指令
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define read_len 2
int main(int argc,char*argv[]){
        printf("i2c-1 的 寄存器\n");
        unsigned int buf[read_len];
        float hum,temp;
        float hum1,temp1;
        int h1,t1;
        int ret = 0;
        pid_t pid = fork();
        if(pid<0){
                perror("fork error");
                exit(1);
        }else if(pid == 0){
                execlp("i2cdetect","i2cdetect","-y","0",NULL);
        }else{  
                waitpid(-1,NULL,0);
                if(argc<2||strncmp(argv[1],"/dev/",5))
                {
                        printf("参数错误,请输入/dev/");
                        exit(1);
                }
                int fd = open(argv[1],O_RDWR);
                if(fd<0){
                        perror("open error");
                        exit(1);
                }
                pid_t pid2 = fork();
                if(pid2 == 0){ 
                        execlp("i2cdump","i2cdump","-f","-y","0","0x38",NULL);
                }               
                else if(pid2 > 0){
                        waitpid(-1,NULL,0);
                        while(1){
                                if((ret=read(fd,buf,sizeof(buf)))==0){
                                        h1 = (buf[0]*1000)>>20;
                                        t1 = ((buf[1]*2000)>>20)-500;
                                        hum = buf[0]*1000./1024/1024/10;
                                        temp = (buf[1]*200.*10/1024/1024-500)/10;
                                        printf("湿度为%0.2f, 温度为%0.2f \n",hum,temp);
                                        printf("hum:%0.2f, temp:%0.2f \n",(float)h1/10.0,(float)t1/10.0);
                                        sleep(1);
                                }
                        }
                        close(fd);
                }
        }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!




