2004v2004 2022-03-02 09:05 采纳率: 0%
浏览 36

请教个问题,iic读写十六位,该如何实现,请指导下,

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

#define CHIP "/dev/i2c-1"
#define I2C_DEVICE_ADDR 0x60 //  I2C device address

static int iic_write(int i2c_fd, int device_addr, unsigned int reg_address, unsigned int reg_val)
{
    struct i2c_rdwr_ioctl_data work_queue;
    int ret = 0;

    work_queue.nmsgs = 1;
    work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));
    if (!work_queue.msgs)
    {
        printf("msgs memery alloc error\n");
        close(i2c_fd);
        return -1;
    }
    if ((work_queue.msgs[0].buf = (unsigned char *)malloc(2 * sizeof(unsigned char))) == NULL)
    {
        printf("buf memery alloc error...\n");
        close(i2c_fd);
        return -1;
    }

    (work_queue.msgs[0]).len = 2;
    (work_queue.msgs[0]).flags = !I2C_M_RD;
    (work_queue.msgs[0]).addr = device_addr;
    (work_queue.msgs[0]).buf[0] = reg_address;
    (work_queue.msgs[0]).buf[1] = reg_val;

    work_queue.nmsgs = 1;

    ret = ioctl(i2c_fd, I2C_RDWR, (unsigned long)&work_queue);
    if (ret < 0)
    {
        printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
        return -1;
    }

    free(work_queue.msgs[0].buf);
    free(work_queue.msgs);

    return 0;
}

static int iic_read(int i2c_fd, int device_addr, unsigned int reg_address)
{
    struct i2c_rdwr_ioctl_data work_queue;
    unsigned char val;
    int ret;

    work_queue.nmsgs = 2;
    work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));

    if (!work_queue.msgs)
    {
        printf("Memery alloc error\n");
        close(i2c_fd);
        return -1;
    }

    val = (unsigned char)reg_address;

    (work_queue.msgs[0]).len = 1;
    (work_queue.msgs[0]).flags = 0;          // write
    (work_queue.msgs[0]).addr = device_addr; // 设备地址
    (work_queue.msgs[0]).buf = &val;

    (work_queue.msgs[1]).len = 1;
    (work_queue.msgs[1]).flags = 1;          // read
    (work_queue.msgs[1]).addr = device_addr; // 设备地址
    (work_queue.msgs[1]).buf = &val;

    ret = ioctl(i2c_fd, I2C_RDWR, (unsigned long)&work_queue);
    if (ret < 0)
    {
        printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
        return -1;
    }
    printf("read  data: %x from address: %#x\n", ret, val);
    free(work_queue.msgs);

    return val;
}

int main()
{
    printf("hello, this is i2c test\n");
    int ret = 0;
    int ik;
    int fd = open(CHIP, O_RDWR);

    if (fd < 0)
    {
        printf("open %s failed\n", CHIP);
        goto exit;
    }

    if (ioctl(fd, I2C_SLAVE, I2C_DEVICE_ADDR) < 0)
    { // device addr
        printf("ioictl: set slave address failed\n");
        goto close;
    }
    ret = iic_write(fd, I2C_DEVICE_ADDR, 0, 0x01);
    if (ret)
        printf("write failed\n");
    ret = iic_write(fd, I2C_DEVICE_ADDR, 0, 0x45);
    if (ret)
        printf("write failed\n");

    ret = iic_write(fd, I2C_DEVICE_ADDR, 0, 0x10);
    if (ret)
        printf("write failed\n");

    // usleep(1000 * 1000 * 0.1);

    // ret = iic_write(fd, I2C_DEVICE_ADDR, 1, 0xbb);
    // if (ret)
    //     printf("write failed\n");

    usleep(1000 * 1000 * 0.1);

    ret = iic_read(fd, I2C_DEVICE_ADDR, 0x10);
    printf("read reg addr:0 data:%x\n", ret);
    // ret = 256 * ret;
    // float f_Temp = -46.85 + 175.7 * ret / 0x10000;
    // printf("Temperature----: %f)\n", f_Temp);
    // ret = iic_read(fd, I2C_DEVICE_ADDR, 0x00);
    // printf("read reg addr:1 data:%x\n", ret);
    // ret = 256 * ret;
    // f_Temp = 6.0 + 125.0 * ret / 0x10000;
    // printf("Humidity------: %f\n", f_Temp);

close:
    close(fd);

exit:
    return 0;
}

我这个是读8位的可以,读写16位具体如何实现,我查到

 

 

int i2c_master_send(struct i2c_client *client, const char *buf, int count)
{
    int ret;
    struct i2c_adapter *adap = client->adapter; // 获取adapter信息
    struct i2c_msg msg;                         // 定义一个临时的数据包

    msg.addr = client->addr;               // 将从机地址写入数据包
    msg.flags = client->flags & I2C_M_TEN; // 将从机标志并入数据包
    msg.len = count;                       // 将此次发送的数据字节数写入数据包
    msg.buf = (char *)buf;                 // 将发送数据指针写入数据包

    ret = i2c_transfer(adap, &msg, 1); // 调用平台接口发送数据
    return (ret == 1) ? count : ret;   // 如果发送成功就返回字节数
}

int i2c_master_recv(struct i2c_client *client, char *buf, int count)
{
    struct i2c_adapter *adap = client->adapter; // 获取adapter信息
    struct i2c_msg msg;                         // 定义一个临时的数据包
    int ret;

    msg.addr = client->addr;               // 将从机地址写入数据包
    msg.flags = client->flags & I2C_M_TEN; // 将从机标志并入数据包
    msg.flags |= I2C_M_RD;                 // 将此次通信的标志并入数据包
    msg.len = count;                       // 将此次接收的数据字节数写入数据包
    msg.buf = buf;

    ret = i2c_transfer(adap, &msg, 1); // 调用平台接口接收数据

    return (ret == 1) ? count : ret; // 如果接收成功就返回字节数
}

这个写法,上述的struct i2c_client *client,  与  i2c_transfer  无法找到结构体的定义和函数定义

  • 写回答

1条回答 默认 最新

  • 疯狂的挖掘机 全栈领域新星创作者 2023-01-06 09:12
    关注

    static int iic_write(int i2c_fd, int device_addr, unsigned int reg_address, unsigned int reg_val)函数最后一个 reg_val数据类型是int 4个字节,32位都支持,不支持16位吗?
    1、试一下 ret = iic_write(fd, I2C_DEVICE_ADDR, 0, 0x1234); //这已经是两个字节,16位
    2、 ret = iic_read(fd, I2C_DEVICE_ADDR, 0x10); //观察ret的值是多少

    评论

报告相同问题?

问题事件

  • 创建了问题 3月2日

悬赏问题

  • ¥15 想问一下stata17中这段代码哪里有问题呀
  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决