生活随笔
收集整理的這篇文章主要介紹了
使用C语言和i2c-dev驱动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文地址:blog.csdn.NET/wyt2013/article/details/20740659 感謝作者分享。
在本博客的《使用Beaglebone Black的I2C(一)》中,介紹了BBB上無需編程對i2c總線進行讀寫操作的方法,本文將介紹如何在C語言程序中使用i2c-dev驅動來操作i2c設備。
以下將還以前文中使用過的L3G4200D三軸陀螺儀為例。
BBB自帶了i2c-dev驅動,它使用ioctl方法對i2c設備進行配置,然后利用read()、write()函數就可以操作i2c設備了。
要操作某個i2c設備,首先要確定它的地址。按照我在前文中的說法,通常i2cdetect顯示的器件地址是由“7位”二進制數換算成的,而器件的讀寫地址則需要將這7位左移,然后在末尾添加一個1或0。但是對于i2c-dev驅動來說,我們不必費此周折,只要告訴他i2cdetect顯示的那個地址就可以了,驅動會自動根據你的讀操作或寫操作來相應地在末尾添加1或者0。
先把完整程序擺出來:
#include?<stdio.h>??#include?<stdlib.h>???//exit()??#include?<fcntl.h>????//define?O_RDWR??#include?<linux/i2c-dev.h>??#include?<sys/ioctl.h>????void?main()??{??????????int?file,i;??????????int?addr?=?0b01101001;?//i2c?device?address?of?gyro??????????char?*filename?=?"/dev/i2c-1";??????????char?wbuf[]?=?{0x20,?0x0f};?//first?byte?is?address?to?write.?others?are?bytes?to?be?written??????????char?read_start_buf[1];???????????char?rbuf[1000]?=?{0};????????????if((file?=?open(filename,?O_RDWR))?<?0)??????????{??????????????????perror("Failed?to?open?i2c?device.\n");??????????????????exit(1);??????????}????????????if(ioctl(file,?I2C_SLAVE,?addr)?<?0)??????????{??????????????????printf("Failed?to?access?bus.\n");??????????????????exit(1);??????????}????????????write(file,?wbuf,?2);?//write?0x0f?to?register?0x20?to?enable?gyro.?????????????for(i=0;i<5;i++)??????????{??????????????????read_start_buf[0]?=?0x29;???????????????????write(file,?read_start_buf,?1);?//reposition?file?pointer?to?register?0x29??????????????????read(file,?rbuf,?1);?//read?register?0x29?and?save?to?rbuf??????????????????printf("%x",?rbuf[0]);????????????????????read_start_buf[0]?=?0x28;??????????????????write(file,?read_start_buf,?1);?//reposition?file?pointer?to?register?0x28??????????????????read(file,?rbuf,?1);?//read?register?0x28?and?save?to?rbuf??????????????????printf("%x\n",?rbuf[0]);??????????????????sleep(1);??????????}????????????close(file);??}??上面的程序首先打開/dev/i2c-1這個設備,然后用ioctl配置成slave模式。然后通過將第0x20這個寄存器寫成0x0f來使能陀螺儀。然后在for循環中依次讀取0x29和0x28兩個寄存器的值并輸出,這兩個寄存器一起組成了X軸的角速度值。程序輸出如下:
root@beaglebone:~/ioctl_test#?./i2c??03c??04a??035??
05f??03c??root@beaglebone:~/ioctl_test#?./i2c??1f7f??f2c3??f567??3979??3aca??運行了兩次,第一次陀螺儀靜止(但輸出仍有一點小波動),第二次陀螺儀在晃動。可以看到輸出值的不同。
需要注意的一點,讀i2c設備時如何定位讀取的位置?
使用lseek()的話會返回-1,這個是不可行的。答案就是程序中,用write()寫一個字節。write函數參數中的buf數組里的第一項代表了write的位置,從第二項開始是寫入的內容,因此只寫一個字節就是把指針移動過去了但是不寫入任何內容。
用這個方法就無需其他驅動也可以操作任意i2c外設了。
另外有個疑問。按理說執行?read(file, rbuf, 10); 的話,可以讀出當前指針位置開始的10個字節的內容。我在其他設備上也驗證了這點。但是在L3G4200D陀螺儀上,一次讀取10個的話,讀出的就全是一樣的數值,都是第一個數值。所以只能一位一位地讀取。難道是陀螺儀芯片有意設置成這樣?(這個現象跟我在《使用Beaglebone Black的I2C(一)》中的問題相符,即執行?i2cdump -y 1 0x69 c?會導致輸出全部是一樣的,都是第一個字節的內容。把c參數去掉才可以。)
轉載于:https://www.cnblogs.com/muhuacat/p/7246040.html
總結
以上是生活随笔為你收集整理的使用C语言和i2c-dev驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。