/*
This software uses a BSD license.

Copyright (c) 2010, Sean Cross / chumby industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the
   distribution. 
* Neither the name of Sean Cross / chumby industries nor the names
   of its contributors may be used to endorse or promote products
   derived from this software without specific prior written
   permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdio.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

#define I2C_FILE_NAME "/dev/i2c-1"
#define USAGE_MESSAGE \
    "Usage:\n" \
    "  %s r [addr] [register]   " \
        "to read value from [register]\n" \
    "  %s w [addr] [register] [value]   " \
        "to write a value [value] to register [register]\n" \
    ""

static int set_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char value) {

unsigned char outbuf[2];
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[1];

messages[0].addr  = addr;
    messages[0].flags = 0;
    messages[0].len   = sizeof(outbuf);
    messages[0].buf   = outbuf;

/* The first byte indicates which register we'll write */
    outbuf[0] = reg;

/*
     * The second byte indicates the value to write.  Note that for many
     * devices, we can write multiple, sequential registers at once by
     * simply making outbuf bigger.
     */
    outbuf[1] = value;

/* Transfer the i2c packets to the kernel and verify it worked */
    packets.msgs  = messages;
    packets.nmsgs = 1;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }

return 0;
}

static int get_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char *val) {
    unsigned char inbuf, outbuf;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];

/*
     * In order to read a register, we first do a "dummy write" by writing
     * 0 bytes to the register we want to read from.  This is similar to
     * the packet in set_i2c_register, except it's 1 byte rather than 2.
     */
    outbuf = reg;
    messages[0].addr  = addr;
    messages[0].flags = 0;
    messages[0].len   = sizeof(outbuf);
    messages[0].buf   = &outbuf;

/* The data will get returned in this structure */
    messages[1].addr  = addr;
    messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
    messages[1].len   = sizeof(inbuf);
    messages[1].buf   = &inbuf;

/* Send the request to the kernel and get the result back */
    packets.msgs      = messages;
    packets.nmsgs     = 2;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    *val = inbuf;

return 0;
}

int main(int argc, char **argv) {
    int i2c_file;

// Open a connection to the I2C userspace control file.
    if ((i2c_file = open(I2C_FILE_NAME, O_RDWR)) < 0) {
        perror("Unable to open i2c control file");
        exit(1);
    }

if(argc > 3 && !strcmp(argv[1], "r")) {
        int addr = strtol(argv[2], NULL, 0);
        int reg = strtol(argv[3], NULL, 0);
        unsigned char value;
        if(get_i2c_register(i2c_file, addr, reg, &value)) {
            printf("Unable to get register!\n");
        }
        else {
            printf("Register %d: %d (%x)\n", reg, (int)value, (int)value);
        }
    }
    else if(argc > 4 && !strcmp(argv[1], "w")) {
        int addr = strtol(argv[2], NULL, 0);
        int reg = strtol(argv[3], NULL, 0);
        int value = strtol(argv[4], NULL, 0);
        if(set_i2c_register(i2c_file, addr, reg, value)) {
            printf("Unable to get register!\n");
        }
        else {
            printf("Set register %x: %d (%x)\n", reg, value, value);
        }
    }
    else {
        fprintf(stderr, USAGE_MESSAGE, argv[0], argv[0]);
    }

close(i2c_file);

return 0;
}

参考链接:http://blog.csdn.net/zfzf294990051/article/details/17322621

Linux i2c 读写程序的更多相关文章

  1. Linux下读写芯片的I2C寄存器

    要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...

  2. linux i2c 设备节点读写

    最近需要操作24C02,封装了一下函数方便以后操作. 参考链接: https://my.oschina.net/handawei/blog/68526 http://blog.csdn.net/one ...

  3. Linux+I2C总线分析(主要是probe的方式)

    Linux I2C 总线浅析 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法,I2C通信方法(即“algo ...

  4. Linux I2C总线设备驱动模型分析(ov7740)

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...

  5. linux i2c驱动架构-dm368 i2c驱动分析

      linux i2c驱动架构-dm368 i2c驱动分析   在阅读本文最好先熟悉一种i2c设备的驱动程序,并且浏览一下i2c-core.c以及芯片提供商的提供的i2c总线驱动(i2c-davinc ...

  6. Linux I2C设备驱动

    i2c设备:ts.camera.audio.gsensor.e2prom I2C基本协议: 写:开始 -> 设备地址 -> 写标志 -> 应答 -> 内部地址 -> 应答 ...

  7. Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】

    本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...

  8. Linux I2C核心、总线和设备驱动

    目录 更新记录 一.Linux I2C 体系结构 1.1 Linux I2C 体系结构的组成部分 1.2 内核源码文件 1.3 重要的数据结构 二.Linux I2C 核心 2.1 流程 2.2 主要 ...

  9. Linux I2C总线控制器驱动(S3C2440)

    s3c2440的i2c控制器驱动(精简DIY),直接上代码,注释很详细: #include <linux/kernel.h> #include <linux/module.h> ...

随机推荐

  1. 029、限制容器的block IO(2019-01-24 周四)

    参考https://www.cnblogs.com/CloudMan6/p/7016050.html   Block IO ,是另一种可以限制容器使用的资源,block IO 指的是磁盘的读写,doc ...

  2. 【转载】 C#读写注册表

    文章地址:https://blog.csdn.net/younghaiqing/article/details/61918968 自Windows95以来的所有Windows版本中,注册表是包含Win ...

  3. C# WinForm 多线程 应用程序退出的方法 结束子线程

    1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消息中止,退 ...

  4. JS创建对象之动态原型模式

    动态原型模式把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了 同时使用构造函数和原型的优点:换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初 ...

  5. nmap学习之nmap -sP 【目标】

    一.通过arp包判断局域网内的主机状态 二.对于局域网外的主机通过向主机 1)发送普通ICMP请求包[类型字段为8,代码字段为0]: 2)发送时间戳ICMP请求包[类型字段为13,代码字段为0]: 3 ...

  6. 007_Reverse Integer

    ###solution1####small data # def reverse(x): # res=[] # t=0 # p=1 #记录位数 # y=x # if x<0: # x=-x # ...

  7. struct详解

    正常定义一个数据结构都是这样用 typedef struct{ int a; int b; }M; 在使用时 M a; 其实 struct是这样的 struct M{ int a; int b; }; ...

  8. Ant使用指南

    ant 使用指南  参考:http://www.cnblogs.com/hoojo/archive/2013/06/14/java_ant_project_target_task_run.html 一 ...

  9. 常用linux命令总结

    Linux 版本 centos 1.查看Linux版本 uname -a 2.查看 ip 地址 ip addr 3.查看端口应用程序 netstat -lanp 如果输入上述命令,显示“-bash: ...

  10. STL之heap学习

    C++标准库中的堆-heap make_heap函数,包括两个参数(begin(number),end(number)).(左闭右开) pop_heap函数,包括两个参数,起始位置和终止位置,将当前区 ...