BBB學習(十):操作BBB I2C接口

一、前言

前文中介紹了普通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

image

4. 連接設備

本文采用DS3231時鐘模塊測試i2C接口,採用BBB板上3.3V給模塊供電。如下圖:

DS3231連接圖

5. 查看設備地址

通過命令i2cdetect -y -r 2可以查看總線2下的設備有哪些,如下圖,從圖中可以看出在地址0x68處有設備,是剛連接的RTC設備:

image

6. 查看設備寄存器

通過命令i2cdump -y -f 2 0x68可以查看該設備下的所以寄存器的值,如下圖所示,可以看出,從0x00到0x12這18個寄存器可以操作。

image

7. DS3231的寄存器介紹

通過ds3231的datasheet可以知道各個寄存器的功能,如下圖所示,可以得到從0x00到0x06寄存器中分別是秒、分、時、日、月、年。因此程序中我們只需要讀取這幾個寄存器的值就可以確定時間。

image

三、程序實現

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,運行程序可以得到以下結果:

image

而通過i2cdump -y -f 2 0x68命令可以對比其讀出的寄存器值是否正確,如下圖:

image

由以上兩圖中紅色方框中可以看出除了保存秒的寄存器外,其他寄存器的值均正確。由此實現了通過i2c讀取RTC寄存器的值

結語

本文主要通過讀取i2c接口上的RTC芯片的寄存器的值來進一步熟悉BBB的一些常用IO口的使用,程序中主要是通過i2c的設備文件/dev/i2c-2實現i2c接口的打開,並讀寫i2c設備(如RTC DS3231)的相關寄存器,本次操作中主要爲了進一步加深前兩節內容的理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章