我是靠谱客的博主 火星上面包,最近开发中收集的这篇文章主要介绍NVIDIA TX2开发板的I2C(IIC)通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本文主要讲述TX2开发板和BMP280高度计采用IIC通讯。

1、首先,要用杜邦线对两者进行连接,连接示意图如下:

对于高度计来说,SCL和SDA分别是IIC通讯的时钟线和地址线,CSB是高度计的激活位,必须连接3.3V的高电平,SDO是地址选择位,若SDO接地,则高度计的地址为0X76,若接3.3V的高电平,则高度计地址为0X77。

对于TX2开发板来说,我们选择J21模块,其中J21_1表示J21模块的1接口。J21_1和J21_17是3.3V的高电平,J21_6和J21_39是低电平(接地),J21_3是SDA接口,J21_5是SCL接口。

2、接下来是查找地址。

采用i2c-tools命令行工具

i2cdetect----用来查找所连接的设备的地址

i2cdump----用来读出特定地址中所有寄存器中的内容

i2cset--------对特定寄存器写入内容

i2cget-------从特定寄存器中读值

我们采用如下命令来查找当前设备的地址:

i2cdetect -y -r -a 1

其中-y表示无视交互问题,-r是SMBus read byte命令,-a是所有地址,0表示TX2开发板的i2c-1(TX2有好几个I2C接口)。

3、Linux环境中IIC代码框架讲解

#include <stdio.h> 
#include <stdint.h> 
#include <fcntl.h> 
#include <unistd.h>
#include <sys/ioctl.h> 
#include "i2c.h" 
#include <linux/i2c-dev.h>


#define BMP280_ADD 0x76     //高度计的地址
#define DIG_START 0x88      //温度补偿寄存器的起始地址
#define TEMP_START 0xFA     //温度测量寄存器的起始地址

#define DIGP_START 0X8E     //压强补偿寄存器的起始地址
#define PRESS_START 0XF7    //压强测量寄存器的起始地址 

#define CTRL_MEAS 0xF4      //选择模式控制寄存器的地址



#define TEMP_ONLY_NORMAL_MODE 0xFF  // 111 111 11    对寄存器的读写方式

int32_t t_fine=0;

//向特定的寄存器写值,用于设置读写方式
int writeReg(int pt, unsigned char add, char value){   
        unsigned char w_buff[2]; 
        w_buff[0] = add; 
        w_buff[1] = value; 
        if (write(pt, w_buff, 2) != 2){ 
                perror("Failed write to device"); 
                return 1; 
        } 
        return 0; 
} 

//从特定的寄存器中读取数据,先写地址寻找这个寄存器,然后读取寄存器中的内容
int readReg(int pt, unsigned char s_add, char buf[], int size){ 
        char writeBuff[1] = {s_add}; 
        if(write(pt, writeBuff, 1)!=1) { 
                perror("Failed to reset the read addressn"); 
                return 1; 
        } 
        if(read(pt, buf, size)!=size){ 
                perror("Failed to read in the buffern"); 
                return 1; 
        } 
        return 0; 
}

//温度补偿
float myFunc(int32_t adc_T, unsigned short dig_T1, short dig_T2, short dig_T3){ 
        double var1, var2, T; 
        var1 = (((double)adc_T)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2); 
        var2 = ((((double)adc_T)/131072.0-((double)dig_T1)/8192.0)*(((double)adc_T)/131072.0-((double)dig_T1)/8192.0))*((double)dig_T3); 
        t_fine =(int32_t)(var1+var2);
	T = (var1+var2)/5120.0; 
        return T; 
}

//压强补偿
float myFunc_p(int32_t adc_P,unsigned short dig_P1,short dig_P2,short dig_P3,short dig_P4,short dig_P5,short dig_P6,short dig_P7,short dig_P8,short dig_P9)
{
	double var1,var2,p;
	if(t_fine==0)
		printf("t_fine is 0!The pressure measurement is not right!Please check temperament measurementn");
	var1 = ((double)t_fine/2.0)-64000.0;
	var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
	var2 = var2 + var1 * ((double)dig_P5) * 2.0;
	var2 = (var2/4.0)+(((double)dig_P4) * 65536.0);
	var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
	var1 = (1.0 + var1 / 32768.0)*((double)dig_P1);
	if (var1 == 0.0)
		return 0; // avoid exception caused by division by zero
	p=1048576.0-(double)adc_P;
	p=(p-(var2/4096.0))*6250.0/var1;
	var1=((double)dig_P9)*p*p/2147483648.0;
	var2=p*((double)dig_P8)/32768.0;
	p = p+(var1+var2+((double)dig_P7))/16.0;
	return p;

}


int main(){ 
        int file; 
        if((file=open("/dev/i2c-1", O_RDWR)) < 0) {     //以只读方式打开i2c地址
                perror("failed to open the busn");  
                return 1; 
        } 
        if(ioctl(file, I2C_SLAVE, BMP280_ADD) < 0) {    //让高度计作为IIC从设备
                perror("Failed to connect to the sensorn"); 
                return 1; 
        }

        char dig_buff[6];    // temperament compensation data
        char tmp_buff[3];    // temperament data
	char digp_buff[18];  // pressure compensation data 
	char pre_buff[3];    //pressure data

        if(writeReg(file, CTRL_MEAS, TEMP_ONLY_NORMAL_MODE)==1){ 
                return 1; 
        } 
	//读取温度计的值
        if(readReg(file, DIG_START, dig_buff, 6)==1){ 
                return 1; 
        } 
        if(readReg(file, TEMP_START, tmp_buff, 3)==1){ 
                return 1; 
        } 
	//读取压强的值
	
        if(readReg(file, DIGP_START, digp_buff, 18)==1){ 
                return 1; 
        } 
        if(readReg(file, PRESS_START, pre_buff, 3)==1){ 
                return 1; 
        } 
        
	close(file);

        printf("temperament:n"); 
        int i; 
        for (i=0; i<6; i++){ 
                printf("%02x ",dig_buff[i]); 
        } 
        printf("n"); 
        for (i=0; i<3; i++){ 
                printf("%02x ",tmp_buff[i]); 
        }
	printf("n"); 
        printf("pressure:n");
	for (i=0;i<18;i++){
		printf("%02x ",digp_buff[i]);
	}
	printf("n");
	for(i=0;i<3;i++){
		printf("%02x ",pre_buff[i]);
	}
	printf("n");
	//temperament
        int adc_T = ((tmp_buff[0]<<16)|(tmp_buff[1]<<8)|(tmp_buff[2]))>>4;
        //pressure
	int adc_P = ((pre_buff[0]<<16)|(pre_buff[1]<<8)|(pre_buff[2]))>>4;
 	
	// for temperament
        unsigned short dig_T1 = (dig_buff[1]<<8)|(dig_buff[0]); 
        short dig_T2 = (dig_buff[3]<<8)|(dig_buff[2]); 
        short dig_T3 = (dig_buff[5]<<8)|(dig_buff[4]); 
	
	// for pressure
        unsigned short dig_P1 = (digp_buff[1]<<8)|(digp_buff[0]); 
        short dig_P2 = (digp_buff[3]<<8)|(digp_buff[2]); 
        short dig_P3 = (digp_buff[5]<<8)|(digp_buff[4]); 
        short dig_P4 = (digp_buff[7]<<8)|(digp_buff[6]); 
        short dig_P5 = (digp_buff[9]<<8)|(digp_buff[8]); 
        short dig_P6 = (digp_buff[11]<<8)|(digp_buff[10]); 
        short dig_P7 = (digp_buff[13]<<8)|(digp_buff[12]); 
        short dig_P8 = (digp_buff[15]<<8)|(digp_buff[14]); 
        short dig_P9 = (digp_buff[17]<<8)|(digp_buff[16]); 
	
	printf("adc_T is : %d n", adc_T); 
        printf("dig_T1 is : %d n", dig_T1); 
        printf("dig_T2 is : %d n", dig_T2); 
        printf("dig_T3 is : %d n", dig_T3); 
        printf("Temperature is : %f DegCn", myFunc(adc_T, dig_T1, dig_T2, dig_T3)); 
         
	printf("adc_P is : %d n", adc_P); 
        printf("dig_P1 is : %d n", dig_P1); 
        printf("dig_P2 is : %d n", dig_P2); 
        printf("dig_P3 is : %d n", dig_P3); 
        printf("dig_P4 is : %d n", dig_P4); 
        printf("dig_P5 is : %d n", dig_P5); 
        printf("dig_P6 is : %d n", dig_P6); 
        printf("dig_P7 is : %d n", dig_P7); 
        printf("dig_P8 is : %d n", dig_P8); 
        printf("dig_P9 is : %d n", dig_P9); 
	printf("pressure is :%f KPan",myFunc_p(adc_P,dig_P1,dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9)/1000.0);

	return 0;
}

以上代码一般只要看懂关键部分即可(用汉语标注的地方),这样就可以学会写适用于自己IIC设备的通讯代码了。

关于BMP280的资料,可以下去自己查资料,或者查看这个博客:http://www.cnblogs.com/leptonation/p/5210331.html

就会明白这些寄存器地址的意义了。

写这篇博客的主要出发点有两个,一个是讲解TX2与IIC设备的连接方式,另一个是讲解Linux下IIC通信的大概思路(即代码框架),BMP280高度计的具体细节不在讲解之内。有问题欢迎提问。

最后

以上就是火星上面包为你收集整理的NVIDIA TX2开发板的I2C(IIC)通信的全部内容,希望文章能够帮你解决NVIDIA TX2开发板的I2C(IIC)通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部