使用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参数去掉才可以。)
使用C语言和i2c-dev驱动的更多相关文章
- Linux I2C设备驱动编写(三)-实例分析AM3359
TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1版本规格 支持标准模式(100K bits/s)和快速模式(400K bits/s) 多路接收.发送模式 ...
- Linux I2C设备驱动编写(二)
在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_driver.i2c_client.三者的关系也在上一节进行了描述.应该已经算是对Linux I2C子系统有了初步 ...
- Linux I2C设备驱动编写(一)
在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解. I2C client 某个I2C ...
- 【转】Linux I2C设备驱动编写(三)-实例分析AM3359
原文网址:http://www.cnblogs.com/biglucky/p/4059586.html TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1 ...
- 【转】Linux I2C设备驱动编写(二)
原文网址:http://www.cnblogs.com/biglucky/p/4059582.html 在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_drive ...
- 【转】Linux I2C设备驱动编写(一)
原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ...
- Linux i2c子系统(一) _动手写一个i2c设备驱动
i2c总线是一种十分常见的板级总线,本文以linux3.14.0为参考, 讨论Linux中的i2c驱动模型并利用这个模型写一个mpu6050的驱动, 最后在应用层将mpu6050中的原始数据读取出来 ...
- Linux i2c子系统(四) _从i2c-s3c24xx.c看i2c控制器驱动的编写
"./drivers/i2c/busses/i2c-s3c2410.c"是3.14.0内核中三星SoC的i2c控制器驱动程序, 本文试图通过对这个程序的分析, 剥离繁复的细节, 总 ...
- i2c触摸屏驱动文件的实现
转自:http://blog.chinaunix.net/uid-29507718-id-4314013.html Linux下I2C接口触摸屏驱动分析 分类: LINUX linux下触摸屏驱动的 ...
- i2c设备驱动注册
Linux I2C设备驱动编写(二) 原创 2014年03月16日 23:26:50 在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_driver.i2c ...
随机推荐
- (68)zabbix windows性能计数器使用详解
概述 windows下的性能计数器让zabbix监控更加轻松,直接获取性能计数器的数值即可完成windows监控.性能计数器如下: 1 perf_counter["\Processor( ...
- 【Spring】事务的实现方式
1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:转账. 场景设定: 用户名 余额 A 1000 B 1000 操作: A通过支付宝给B转账200块,做这件事情会进行两个操作. 1:A账号- ...
- Python基础(六)——面向对象编程
(1)定义类和实例 这一部分难得和 Java 较为一致,直接写个例子: class Stu: def __init__(self, name, id): # 构造方法 self.name = name ...
- 中移物联网onenet入门学习笔记1:资料获取
onenet学习资料.视频.例程汇总:https://open.iot.10086.cn/bbs/thread-977-1-1.html onenet开发文档:https://open.iot.100 ...
- MySQL迁移至MariaDB
为什么要用MariaDB来代替MySQL MariaDB是MySQL社区开发的分支,也是一个增强型的替代品.它由MySQL前开发者们带头组织的基金会开发,使用起来和MySQL完全一样.自从Oracle ...
- poj 1017 装箱子问题 贪心算法
题意:有1*1到6*6的的东西,需要用6*6的箱子将它们装起来.问:至少需要多少个6*6箱子 思路: 一个瓶子怎么装东西最多?先装石头,在装沙子,然后装水. 同样放在本题就是先装6*6然后5*5... ...
- 1512 Monkey King
Monkey King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 关于windows服务的编写/安装/与调试
前注: 首先,这篇文章是从网上转过来的,因为最近有个项目,需要编写一个Windows Service来定时执行程序,网上很容易找到了这篇文章,大概看了一下,文章讲的还是很详细的.不过这篇文章应该是.n ...
- 再谈H2的MVStore与MVMap
对H2的[MVStore]: http://www.cnblogs.com/simoncook/p/5188105.html 这篇文章的补充. 概述 我们通常用的map,比如HashMap Linke ...
- webdriver高级应用- 改变一个页面对象的属性值
适用于一些无法操作的元素,可以直接改他的属性从而操作,代码如下: #encoding=utf-8 from selenium import webdriver import unittest impo ...