TK1(Linux)下通过I2C控制AM2320温湿度传感器和MPU6050加速度传感器(二)

    做好相关准备后,我们关注的焦点在于怎么控制对应的I2C设备文件。Linux下一切皆文件,控制I2C设备也是通过控制对应的文件来实现的,下面是打开I2C文件过程。

bool MPU6050::openMPU6050()
{
   char fileNameBuffer[32];
   sprintf(fileNameBuffer,"/dev/i2c-%d", kI2CBus);
   kI2CFileDescriptor = open(fileNameBuffer, O_RDWR);
   if (kI2CFileDescriptor < 0) {
       // Could not open the file
      error = errno ;
      return false ;
   }
   //set slave address
   if (ioctl(kI2CFileDescriptor, I2C_SLAVE, kI2CAddress) < 0) {
       // Could not open the device on the bus
       error = errno ;
       return false ;
   }
   return true ;
}
    其中kI2CBus是前面提到过的序号,kI2CFileDescriptor是对应的文件描述符。用ioctl来配置对应的从机地址。第二个参数I2C_SLAVE在<linux/i2c-dev.h>头文件下定义,用于绑定第三个从机地址。完成openMPU6050操作后,就可以通过read,write等函数来读写从机寄存器了。

int MPU6050::i2cwrite(uchar writeAddr, uchar writeValue) {
    int toReturn = i2c_smbus_write_byte_data(kI2CFileDescriptor, writeAddr, writeValue);
    if (toReturn < 0) {
        printf("MPU6050 Write error: %d",errno) ;
        error = errno ;
        toReturn = -1 ;
    }
    return toReturn ;

}
uchar MPU6050::i2cread(uchar writeAddr){
	uchar res = i2c_smbus_read_byte_data(kI2CFileDescriptor, writeAddr);
    if (res < 0) {
        printf("MPU6050 Read error: %d",errno) ;
        error = errno ;
        res = -1 ;
    }
    return res ;
}
    上面是两个关于I2C读写的方法。i2c_smbus_write_byte_data是在kI2CFileDescriptor所指示I2C文件中在writeAddr地址写writeValue数据,也就是给从机寄存器写数据;i2c_smbus_read_byte_data函数则是在指定地址读取数据。i2c_smbus相关函数还有很多,这里不一一列举。

    对于MPU6050来说,操作I2C比较容易,无非是配置参数(指定寄存器写数据),读数据(指定寄存器读数据)。例如初始化initMPU6050:(PWR_MGMT_1等参数均是自己宏定义的)

i2cwrite(PWR_MGMT_1, 0x00);	//解除休眠状态
i2cwrite(SMPLRT_DIV, 0x07); //陀螺仪采样率,典型值:0x07(125Hz)
i2cwrite(CONFIG, 0x06);		//低通滤波频率,典型值:0x06(5Hz)
i2cwrite(GYRO_CONFIG, 0x18);//陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
i2cwrite(ACCEL_CONFIG, 0x01);//加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)

    从MPU6050读数据:Linux下short是2字节16位

short MPU6050::readData(uchar readAddr){
	char h,l; 
	h=i2cread(readAddr);		
	l=i2cread(readAddr+1);
	return (h<<8)+l;   //合成数据
	
}

    用户操作时只需要

    MPU6050 *acc = new MPU6050();
	
    int err = acc->openMPU6050();
    if (err < 0){
        printf("Error: %d", acc->error);
    } 
    else {
        printf("MPU6050 Device Address: 0x%02X\n",acc->kI2CAddress) ;
        acc->initMPU6050();
	x = acc->readData(ACCEL_XOUT_H);
	y = acc->readData(ACCEL_YOUT_H);
	z = acc->readData(ACCEL_ZOUT_H);
    }
    注意:这里得出的值并不是真实的重力值,而是灵敏度。要得到正确值还需要进行转换。下图是测出来x、y、z轴的灵敏度

如果设置ACCEL_CONFIG是 0x01的话,查表可知满量程是2G, LSB灵敏度是16384

 
i2cwrite(ACCEL_CONFIG, 0x01);//加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)



上图的AFS_SEL实际上是ACCEL_CONFIG的第3,4位,从二进制的00~11分别代表设置加速度的满量程单位为2g~16G。


因此有转换公式:加速度值 = 灵敏度值/16384  (量程2G情况下)

同理,角速度也是一样的。下一节介绍AM2320相关内容。

参考资料:

关于I2C_smbus函数讲解可以参考 https://blog.csdn.net/mcgrady_tracy/article/details/50970717

I2C的类构成参考自https://github.com/jetsonhacks/JHLEDBackpack.git



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值