linux i2c 设备节点读写
最近需要操作24C02,封装了一下函数方便以后操作。
参考链接:
https://my.oschina.net/handawei/blog/68526
http://blog.csdn.net/onetwothreef/article/details/49488443
源码:
#include <stdio.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#define I2C_DEFAULT_TIMEOUT 1
#define I2C_DEFAULT_RETRY 3
/*
* fd : 文件描述符
* timeout : 发送超时时间
* retry : 重复发送次数
*/
//重复发送次数可以设多一点,在调试的时候,只设置了一次,导致有时候发送会失败。
int i2c_set(int fd, unsigned int timeout, unsigned int retry)
{
if (fd == 0 )
return -1;
if (ioctl(fd, I2C_TIMEOUT, timeout ? timeout : I2C_DEFAULT_TIMEOUT) < 0)
return -1;
if (ioctl(fd, I2C_RETRIES, retry ? retry : I2C_DEFAULT_RETRY) < 0)
return -1;
return 0;
}
/*
* fd : 文件描述符
* addr : i2c的设备地址
* reg : 寄存器地址
* val : 要写的数据
* 描述 :从指定地址写数据
*/
int i2c_byte_write(int fd, unsigned char addr, unsigned char reg, unsigned char val)
{
int ret = 0;
unsigned char outbuf[2];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages;
packets.nmsgs = 1;
packets.msgs = &messages;
//发送要读取的寄存器地址
messages.addr = addr;
messages.flags = 0;
messages.len = 2; //寄存器地址加数据,共发送2个字节
messages.buf = outbuf;
outbuf[0] = reg;
outbuf[1] = val;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets); //读出来
if (ret < 0)
ret = -1;
return ret;
}
/*
* fd : 文件描述符
* addr : i2c的设备地址
* reg : 寄存器地址
* val : 要写的数据
* len : 数据长度
* 描述 :从指定地址写数据
* 24c02以8字节为1个page,如果在一个page里面写,写的字节长度超过这个page的末尾,
* 就会从page的开头写,覆盖开头的内容
*/
int i2c_nbytes_write(int fd, unsigned char addr, unsigned char reg, unsigned char *val, int len)
{
int ret = 0;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages;
int i;
packets.nmsgs = 1;
packets.msgs = &messages;
//发送要读取的寄存器地址
messages.addr = addr;
messages.flags = 0; //write
messages.len = len + 1; //数据长度
//发送数据
messages.buf = (unsigned char *)malloc(len+1);
if (NULL == messages.buf)
{
ret = -1;
goto err;
}
messages.buf[0] = reg;
for (i = 0; i < len; i++)
{
messages.buf[1+i] = val[i];
}
ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets);//读出来
if (ret < 0){
printf("write error!\n");
return -1;
}
err:
free(messages.buf);
return ret;
}
/*
* fd : 文件描述符
* addr : i2c的设备地址
* val : 保存读取数据
* 描述 :从当前地址读取一个字节数据
*/
int i2c_byte_read(int fd, unsigned char addr, unsigned char *val)
{
int ret = 0;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages;
packets.nmsgs = 1; //数据帧类型只有一种,读操作,只需要发送一个起始信号,因此是1
packets.msgs = &messages;
//发送要读取的寄存器地址
messages.addr = addr; //i2c设备地址
messages.flags = I2C_M_RD; //读操作
messages.len = 1; //数据长度
messages.buf = val; //读取的数据保存在val
ret = ioctl (fd, I2C_RDWR, (unsigned long)&packets); //发送数据帧
if (ret < 0)
ret = -1;
return ret;
}
/*
* fd : 文件描述符
* addr : i2c的设备地址
* reg : 寄存器地址
* val : 保存读取的数据
* len : 读取数据的长度
* 描述 :读取达到eeprom的末尾时,会读取最开头的字节
*/
int i2c_nbytes_read(int fd, unsigned char addr, unsigned char reg, unsigned char *val, int len)
{
int ret = 0;
unsigned char outbuf;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
/* 数据帧类型有2种
* 写要发送起始信号,进行写寄存器操作,再发送起始信号,进行读操作,
* 有2个起始信号,因此需要分开来操作。
*/
packets.nmsgs = 2;
//发送要读取的寄存器地址
messages[0].addr = addr;
messages[0].flags = 0; //write
messages[0].len = 1; //数据长度
messages[0].buf = &outbuf; //发送寄存器地址
outbuf = reg;
//读取数据
messages[1].len = len; //读取数据长度
messages[1].addr = addr; //设备地址
messages[1].flags = I2C_M_RD; //read
messages[1].buf = val;
packets.msgs = messages;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets); //发送i2c,进行读取操作
if (ret < 0)
ret = -1;
return ret;
}
Tony Liu
2016-9-23, Shenzhen
linux i2c 设备节点读写的更多相关文章
- linux spi 设备节点 读写
本文记录spi设备节点的操作方法. SPI总线设备文件名通常为/dev/spidevN.P(N=0.1.2--,P=0.1.2--), 其中N表示第几路SPI总线,而P表示在该路SPI总线中使用哪个C ...
- Linux I2C设备驱动编写(二)
在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_driver.i2c_client.三者的关系也在上一节进行了描述.应该已经算是对Linux I2C子系统有了初步 ...
- 【转】Linux I2C设备驱动编写(二)
原文网址:http://www.cnblogs.com/biglucky/p/4059582.html 在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_drive ...
- Android和Linux下设备节点的创建笔记
1. Linux kernel创建的/dev/下的设备节点是不对的, 其实是kernel仅负责在/sys/(基于内存的虚拟文件系统)创建一大堆下目录和文件,而真正的设备节点是在用户空间程序创建的,应该 ...
- Linux I2C设备驱动编写(三)-实例分析AM3359
TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1版本规格 支持标准模式(100K bits/s)和快速模式(400K bits/s) 多路接收.发送模式 ...
- 【转】Linux I2C设备驱动编写(三)-实例分析AM3359
原文网址:http://www.cnblogs.com/biglucky/p/4059586.html TI-AM3359 I2C适配器实例分析 I2C Spec简述 特性: 兼容飞利浦I2C 2.1 ...
- Linux I2C设备驱动
i2c设备:ts.camera.audio.gsensor.e2prom I2C基本协议: 写:开始 -> 设备地址 -> 写标志 -> 应答 -> 内部地址 -> 应答 ...
- Linux I2C设备驱动编写(一)
在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解. I2C client 某个I2C ...
- 【转】Linux I2C设备驱动编写(一)
原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ...
随机推荐
- 转:jQuery Ajax 实例 全解析
jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对 ...
- POJ 2948 Martian Mining(DP)这是POJ第200道,居然没发现
题目链接 两种矿石,Y和B,Y只能从从右到左,B是从下到上,每个空格只能是上下或者左右,具体看图.求左端+上端最大值. 很容易发现如果想最优,分界线一定是不下降的,分界线上面全是往上,分界线下面都是往 ...
- redis运用连接池报错解决
redis使用连接池报错解决redis使用十几小时就一直报异常 redis.clients.jedis.exceptions.JedisConnectionException: Could not g ...
- 紧挨导航栏下的链接a标签失效
在我编完网页测试的的时候,发现导航下的链接不能用,不出现小手的图表,而下面的相同的链接都能用.如下图所示 遇到的相同问题的另一个未完成的页面如图 先不谈论其原因,说一下我对第一个页面的解决办法,我在导 ...
- Silic PHP大马Cookie欺骗漏洞
$password="ebd9a3c106064a255aaee28b6eb4f21c"; if($_COOKIE['admin_silicpass'] != md5($passw ...
- java对象比较器和克隆
一.比较器Comparable和Comparator 上一篇博客介绍了工具类Arrays工具类 .我们可以对基本类型的数组调用Arrays.sort()函数来进行数组的排序.排序操作在日常开发中经常要 ...
- Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)
1741. Communication Fiend Time limit: 1.0 second Memory limit: 64 MB Kolya has returned from a summe ...
- Responsive布局技巧
在Responsive布局中,可以毫无保留的丢弃: 第一, 尽量少用无关紧要的div: 第二,不要使用内联元素(inline): 第三,尽量少用JS或flash: 第四,丢弃没用的绝对定位和浮动样式: ...
- .NET开发问题汇总
问题一: mvc 部署到iis 提示错误未能加载文件或程序集System.Web.Http.WebHost 解决方案: Nuget程序包管理 —>程序包管理控制台,运行以下命令即可:Update ...
- 让你的PHP更安全之PHP.ini
让你的PHP更安全之PHP.ini 发布时间:2013-05-02 12:43:06 来源:PHP100论坛 评论:0 点击: 次 [字号:大 中 小] QQ空间新浪微博腾讯微博人人网豆瓣网百 ...