内部集成电路(IIC 或者 I2C)总线使用小数据负载连接简单的外部设备。传感器和执行器是常见的 I2C 使用案例,例如包含加速度计,温度计,LCD 显示器,和电机驱动。
- public class HomeActivity extends Activity{
- // I2C Device Name
- private static finalString I2C_DEVICE_NAME = ...;// I2C Slave Address
- private static final intI2C_ADDRESS = ...;privateI2cDevice mDevice;@Override
- protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// Attempt to access the I2C device
- try{
- PeripheralManagerService manager =newPeripheralManagerService();
- 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,intaddress) throws IOException {// Read one register from slave
- byte value= device.readRegByte(address);// Set bit 6
- value|=0x40;// Write the updated value back to slavedevice.writeRegByte(address,value);
- }// Read a register block
- public byte[]readCalibration(I2cDevice device,intstartAddress) throws IOException {// Read three consecutive register values
- byte[] data =new byte[3];
- device.readRegBuffer(startAddress, data, data.length);returndata;
- }
当和一个 I2C 外设交互时,定义不同的 SMBus 寄存器,或许根本不使用寄存器,使用原始的 raw() 和 write() 方法对通过导线传递的字节数据完全控制。这些方法将会执行一个如下单独的 I2C 传输:
- public void writeBuffer(I2cDevice device,byte[] buffer)throwsIOException {intcount = device.write(buffer, buffer.length);
- Log.d(TAG,"Wrote "+ count +" bytes over I2C.");
- }
当你完成 I2C 端口通信,关闭这个连接,并释放资源。此外,在现有端口关闭之前,你不能打开一个新的连接。要想关闭连接,使用端口的 close() 方法;
- public class HomeActivity extends Activity{... ...privateI2cDevice 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 finalString I2C_ADDRESS ="I2C1";private static final intTEMPERATURE_SENSOR_SLAVE =0x77;private static final intREGISTER_TEMPERATURE_CALIBRATION_1 =0x88;private static final intREGISTER_TEMPERATURE_CALIBRATION_2 =0x8A;private static final intREGISTER_TEMPERATURE_CALIBRATION_3 =0x8C;private static final intREGISTER_TEMPERATURE_RAW_VALUE_START =0xFA;private static final intREGISTER_TEMPERATURE_RAW_VALUE_SIZE =3;privateTextView temperatureTextView;privateI2cDevice 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 =newPeripheralManagerService();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) {floattemperature = 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]
- intmsb = data[0] &0xff;intlsb = data[1] &0xff;intxlsb = data[2] &0xf0;// Convert to 20bit integer
- return(msb <<16| lsb <<8| xlsb) >>4;
- }private float compensateTemperature(intrawTemp) {floatdigT1 = calibrationData[0];floatdigT2 = calibrationData[1];floatdigT3 = calibrationData[2];floatadcT = (float) rawTemp;floatvarX1 = adcT /16384f - digT1 /1024f;floatvarX2 = varX1 * digT2;floatvarY1 = adcT /131072f - digT1 /8192f;floatvarY2 = varY1 * varY1;floatvarY3 = varY2 * digT3;return(varX2 + varY3) /5120f;
- }
- }
按照上面的电路图,搭建电路如下: 运行程序,通过传感器检测的温度显示在屏幕上:
1. 新技术,新未来!欢迎大家关注 "1024 工场" 微信服务号,时刻关注我们的最新的技术讯息。(甭客气!尽情的扫描或者长按!) 2. 抛弃各种找元器件的烦恼,来 "1024 工场" 微店,一次性买到你所想要的。(甭客气!尽情的扫描或者长按!) 3. 加入 "Android Things 开发"QQ 讨论群,一起学习一起 Hi。(甭客气!尽情的扫描或者长按!)
来源: http://blog.csdn.net/p106786860/article/details/70037804