BeagleBoneBlack [5] – I2C communication –
拡張コネクタに I2C デバイスを接続して制御
GPIO の動作は確認できましたので,次は I2C で外部デバイスとの通信を試してみます.GPIO のときと同様,使用可能な拡張コネクタの端子を調べると,下記の通り,P9 の 17 と 18 (I2C1),同じく P9 の 19 と 20 (I2C2) がデフォルトで I2C に割り当てられており,使用可能であることがわかります.
ターゲットは温度センサ STTS751
今回はターゲットとするデバイスとして,秋月で入手した I2C 接続のデジタル温度センサ STTS751 を使用してみます. 小型表面実装の 6ピン温度センサで,割り込みやデュアル・アラーム機能も備えた多機能なセンサです.
これも秋月の BeagleBone ユニバーサルプロトケープ上に実装します.外付け部品としては電源のパスコンと I2C のスレーブアドレス設定用の抵抗(7.5k / 12k / 20k / 33kΩ のいずれか)のみと非常にシンプルです.
汎用ドライバ 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
Leave a Reply