标签:device 接口 raw ade type sys demo 数据传输 man
内部集成电路(IIC或者I2C)总线使用小数据负载连接简单的外部设备。传感器和执行器是常见的I2C使用案例,例如包含加速度计,温度计,LCD显示器,和电机驱动。
I2C设备连接使用3线接口:
public class HomeActivity extends Activity {
// I2C Device Name
private static final String I2C_DEVICE_NAME = ...;
// I2C Slave Address
private static final int I2C_ADDRESS = ...;
private I2cDevice mDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Attempt to access the I2C device
try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS);
} catch (IOException e) {
Log.w(TAG, "Unable to access I2C device", e);
}
}
}
I2C Slave设备组织内容给可读或者可写的寄存器(单个字节数据由一个地址值引用):
一个常见的协议实现被称为System Management Bus(SMBus)存在于I2C顶部,以标准的方式和寄存器通信。SMBus命令由下面的两个I2C事务组成:
外设I/O提供了三种类型的SMBus命令来访问寄存器:
// Modify the contents of a single register
public void setRegisterFlag(I2cDevice device, int address) throws IOException {
// Read one register from slave
byte value = device.readRegByte(address);
// Set bit 6
value |= 0x40;
// Write the updated value back to slave
device.writeRegByte(address, value);
}
// Read a register block
public byte[] readCalibration(I2cDevice device, int startAddress) throws IOException {
// Read three consecutive register values
byte[] data = new byte[3];
device.readRegBuffer(startAddress, data, data.length);
return data;
}
当和一个I2C外设交互时,定义不同的SMBus寄存器,或许根本不使用寄存器,使用原始的raw()和write()方法对通过导线传递的字节数据完全控制。这些方法将会执行一个如下单独的I2C传输:
public void writeBuffer(I2cDevice device, byte[] buffer) throws IOException {
int count = device.write(buffer, buffer.length);
Log.d(TAG, "Wrote " + count + " bytes over I2C.");
}
当你完成I2C端口通信,关闭这个连接,并释放资源。此外,在现有端口关闭之前,你不能打开一个新的连接。要想关闭连接,使用端口的close()方法;
public class HomeActivity extends Activity {
... ...
private I2cDevice mDevice;
@Override
protected void onDestroy() {
super.onDestroy();
if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close I2C device", e);
}
}
}
}
下面我们就通过使用i2c接口,获取bmp280温度传感器的温度数据来演示该接口的使用。
广告时间咯:如果你还没有自己的开发板和元器件,到我们的“1024工场微店”来逛逛一逛吧(文章底部二维码),这里能一次性有买到你想要的!
I2CDemo\app\src\main\java\com\chengxiang\i2cdemo\MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String I2C_ADDRESS = "I2C1";
private static final int TEMPERATURE_SENSOR_SLAVE = 0x77;
private static final int REGISTER_TEMPERATURE_CALIBRATION_1 = 0x88;
private static final int REGISTER_TEMPERATURE_CALIBRATION_2 = 0x8A;
private static final int REGISTER_TEMPERATURE_CALIBRATION_3 = 0x8C;
private static final int REGISTER_TEMPERATURE_RAW_VALUE_START = 0xFA;
private static final int REGISTER_TEMPERATURE_RAW_VALUE_SIZE = 3;
private TextView temperatureTextView;
private I2cDevice i2cDevice;
private final short[] calibrationData = new short[3];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
temperatureTextView = (TextView) findViewById(R.id.temperature);
PeripheralManagerService peripheralManagerService = new PeripheralManagerService();
try {
i2cDevice = peripheralManagerService.openI2cDevice(I2C_ADDRESS, TEMPERATURE_SENSOR_SLAVE);
calibrationData[0] = i2cDevice.readRegWord(REGISTER_TEMPERATURE_CALIBRATION_1);
calibrationData[1] = i2cDevice.readRegWord(REGISTER_TEMPERATURE_CALIBRATION_2);
calibrationData[2] = i2cDevice.readRegWord(REGISTER_TEMPERATURE_CALIBRATION_3);
byte[] data = new byte[REGISTER_TEMPERATURE_RAW_VALUE_SIZE];
i2cDevice.readRegBuffer(REGISTER_TEMPERATURE_RAW_VALUE_START, data, REGISTER_TEMPERATURE_RAW_VALUE_SIZE);
if (data.length != 0) {
float temperature = compensateTemperature(readSample(data));
temperatureTextView.setText("temperature:" + temperature);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (i2cDevice != null) {
try {
i2cDevice.close();
i2cDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close I2C device", e);
}
}
}
private int readSample(byte[] data) {
// msb[7:0] lsb[7:0] xlsb[7:4]
int msb = data[0] & 0xff;
int lsb = data[1] & 0xff;
int xlsb = data[2] & 0xf0;
// Convert to 20bit integer
return (msb << 16 | lsb << 8 | xlsb) >> 4;
}
private float compensateTemperature(int rawTemp) {
float digT1 = calibrationData[0];
float digT2 = calibrationData[1];
float digT3 = calibrationData[2];
float adcT = (float) rawTemp;
float varX1 = adcT / 16384f - digT1 / 1024f;
float varX2 = varX1 * digT2;
float varY1 = adcT / 131072f - digT1 / 8192f;
float varY2 = varY1 * varY1;
float varY3 = varY2 * digT3;
return (varX2 + varY3) / 5120f;
}
}
按照上面的电路图,搭建电路如下:
运行程序,通过传感器检测的温度显示在屏幕上:
1.新技术,新未来!欢迎大家关注“1024工场”微信服务号,时刻关注我们的最新的技术讯息。(甭客气!尽情的扫描或者长按!)
2.抛弃各种找元器件的烦恼,来“1024工场”微店,一次性买到你所想要的。(甭客气!尽情的扫描或者长按!)
3.加入“Android Things开发”QQ讨论群,一起学习一起Hi。(甭客气!尽情的扫描或者长按!)
标签:device 接口 raw ade type sys demo 数据传输 man
原文地址:http://blog.csdn.net/p106786860/article/details/70037804