拡張コネクタに I2C デバイスを接続して制御

GPIO の動作は確認できましたので,次は I2C で外部デバイスとの通信を試してみます.GPIO のときと同様,使用可能な拡張コネクタの端子を調べると,下記の通り,P9 の 17 と 18 (I2C1),同じく P9 の 19 と 20 (I2C2) がデフォルトで I2C に割り当てられており,使用可能であることがわかります.

BBB_ex_pin2

ターゲットは温度センサ STTS751

今回はターゲットとするデバイスとして,秋月で入手した I2C 接続のデジタル温度センサ STTS751 を使用してみます. 小型表面実装の 6ピン温度センサで,割り込みやデュアル・アラーム機能も備えた多機能なセンサです.

これも秋月の BeagleBone ユニバーサルプロトケープ上に実装します.外付け部品としては電源のパスコンと I2C のスレーブアドレス設定用の抵抗(7.5k / 12k / 20k / 33kΩ のいずれか)のみと非常にシンプルです.

bbb_i2c_01

汎用ドライバ i2c-dev を使用してプログラミング

制御用のドライバソフトは,I2C 用汎用ドライバ(i2c-dev)の仕組みを利用します.I2C バス用のデバイスファイル /dev/i2c-1 を開き, ioctl で SSTS751 内のレジスタを読み・書きすることで制御します.アクセス先スレーブアドレスは,今回は外付け抵抗を 7.5kΩ としたので 0x48 になります.

内部レジスタ 0x03 の設定レジスタにより高精度モードに設定,0x00 0x02 レジスタから温度データが取得できます.その他の機能の詳細な設定等は STTS751 デバイスのデータシート,レジスタマップに書かれていますので,必要に応じて設定します.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
#include <linux/spi/spidev.h>
/****************************************************************
* Constants
****************************************************************/
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
/****************************************************************
* i2c_open
****************************************************************/
int i2c_open(void)
{
int handle;
handle = open("/dev/i2c-1", O_RDWR);
return handle;
}
/****************************************************************
* i2c_write
****************************************************************/
int i2c_write(int handle, unsigned char reg, unsigned char data)
{
int ret;
unsigned char buf[2];
ret = ioctl(handle, I2C_SLAVE, 0x48);
buf[0] = reg;
buf[1] = data;
ret = write(handle, buf, 2);
return 0;
}
/****************************************************************
* i2c_read
****************************************************************/
unsigned char i2c_read(int handle, unsigned char reg)
{
int ret;
unsigned char buf[2];
ret = ioctl(handle, I2C_SLAVE, 0x48);
buf[0] = reg;
ret = write(handle, buf, 1);
ret = read(handle, buf, 1);
return buf[0];
}
/****************************************************************
* Main
****************************************************************/
int main(int argc, char **argv, char **envp)
{
int i2c_fd;
int count;
unsigned char temp1, temp2;
double temp;
int timeout = POLL_TIMEOUT;
i2c_fd = i2c_open();
printf("i2c : %d\n", i2c_fd);
if(i2c_fd < 0) return 0;
i2c_write(i2c_fd, 0x03, 0x0C);
for(count = 0; count < 100; count++) {
usleep(500000);
temp1 = i2c_read(i2c_fd, 0x00);
temp2 = i2c_read(i2c_fd, 0x02);
printf("temp_data : %02x %02x\n", temp1, temp2);
}
close(i2c_fd);
printf("i2c close\n");
return 0;
}

参考文献

参考 URL

BeagleBone Black 技術資料 : http://elinux.org/Beagleboard:BeagleBoneBlack#LATEST_PRODUCTION_FILES_.28C.29