一、前言
前文中介紹了普通IO口的使用以及引腳功能互查表的用法,主要想通過簡單的IO操作熟悉BBB的使用流程,在BBB的接口中,還在一類功能複用的引腳,如I2C、spi等,本節通過介紹I2C的使用方法,希望能夠加深對BBB引腳功能使用的理解。
二 I2C-tool使用
1. i2c-tool基本命令
i2cdetect -l //羅列出系統所有i2c接口
i2cdetect -y -r 1 //羅列出第1個i2c接口下的所有可用設備
i2cdump -y -f 1 0x3a //第一個i2c接口下地址0x3a處的所有寄存器的值
i2cget -y -f 1 0x3a 0x02 //得到第一個i2c接口下地址0x3a處寄存器0x02的值
i2cset -y -f 1 0x3a 0x02 0x05 //設置第一個i2c接口下地址0x3a處寄存器0x02的值爲0x05
2. 查看i2C接口
BBB系統中自帶了i2c工具,可以通過相關命令查看i2c相關內容,如:
輸入i2cdetect -l
命令:
i2c-0 i2c OMAP I2C adapter I2C adapter
i2c-2 i2c OMAP I2C adapter I2C adapter
從結果中可知:BBB已經配置了兩個i2c接口可以供使用。
3. 查看IO口
實際上BBB的i2c接口如下圖,可以看出如果要使用i2c2則接口可以是P9_19 P9_20或P9-21 P9-22,通過前文BBB引腳功能互查表的用法,可以查出是哪個引腳當前處於I2C功能狀態。經查本文中是採用P9_19和P9_20
4. 連接設備
本文采用DS3231時鐘模塊測試i2C接口,採用BBB板上3.3V給模塊供電。如下圖:
5. 查看設備地址
通過命令i2cdetect -y -r 2
可以查看總線2下的設備有哪些,如下圖,從圖中可以看出在地址0x68處有設備,是剛連接的RTC設備:
6. 查看設備寄存器
通過命令i2cdump -y -f 2 0x68
可以查看該設備下的所以寄存器的值,如下圖所示,可以看出,從0x00到0x12這18個寄存器可以操作。
7. DS3231的寄存器介紹
通過ds3231的datasheet可以知道各個寄存器的功能,如下圖所示,可以得到從0x00到0x06寄存器中分別是秒、分、時、日、月、年。因此程序中我們只需要讀取這幾個寄存器的值就可以確定時間。
三、程序實現
1. 程序代碼
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define I2C_DIR "/dev/i2c-2" //i2c接口路徑
#define CHIP_ADDR 0x68 //RTC設備地址
using namespace std;
char readRegesiterAddr[2];
char readRegesiterData[20];
int main()
{
int fp;
int i = 0, res = 0;
char ioStatus = 0;
fp = open(I2C_DIR, O_RDWR); /*讀寫模式打開direction*/
if (fp < 0) {
cout << "open failed!" << endl;
return 0;
}
if (ioctl(fp, I2C_TENBIT, 0) < 0) //not 10bi
{
printf("set failed!\r\n");
close(fp);
return 0;
}
if (ioctl(fp, I2C_SLAVE, CHIP_ADDR) < 0) //設置爲slave模式
{ /* 設置芯片地址 */
printf("oictl:set slave address failed\n");
close(fp);
return 0;
}
for (i = 0; i<5; i++)
{
readRegesiterAddr[0] = 0x00;
if (write(fp, readRegesiterAddr, 1) != 1) //定稿寄存器地址,從0x00開始讀取
{
printf("write addr failed\n");
}
res = read(fp, readRegesiterData, 10); //讀取10個寄存器的值
printf("read data len:%d\n", res);
printf("%x, %x, %x, %x, %x, %x\n", readRegesiterData[0], readRegesiterData[1], readRegesiterData[2], readRegesiterData[3], readRegesiterData[4], readRegesiterData[5]);
sleep(1); /*延時一秒*/
}
close(fp);
return 0;
}
2. 程序編譯及結果對比
該程序通過上文操作BBB普通IO口進行編譯,首先將程序通過nano工具複製保存爲i2ctest.cpp
文件,通過前文方法編譯爲可運行程序test,運行程序可以得到以下結果:
而通過i2cdump -y -f 2 0x68
命令可以對比其讀出的寄存器值是否正確,如下圖:
由以上兩圖中紅色方框中可以看出除了保存秒的寄存器外,其他寄存器的值均正確。由此實現了通過i2c讀取RTC寄存器的值
結語
本文主要通過讀取i2c接口上的RTC芯片的寄存器的值來進一步熟悉BBB的一些常用IO口的使用,程序中主要是通過i2c的設備文件/dev/i2c-2
實現i2c接口的打開,並讀寫i2c設備(如RTC DS3231)的相關寄存器,本次操作中主要爲了進一步加深前兩節內容的理解。