• 正文
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard-i2c与从设备通讯编程示例之i2c设备通信编程示例

07/21 16:05
118
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
#include <stdio.h>

#include <linux/types.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ioctl.h>

#include <errno.h>

#include <assert.h>

#include <string.h>

#include <linux/i2c.h>

#include <linux/i2c-dev.h>

#define I2C_DEV_NAME    "/dev/i2c-5"

unsigned int fd;

int func_write_regs(unsigned char devaddr,unsigned char reg, unsigned char *buf)

{

struct i2c_rdwr_ioctl_data work_queue;

int ret;

work_queue.nmsgs = 1;

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

if (!work_queue.msgs) {

printf("memory alloc failed");

ret = -1;

return ret;

}

work_queue.nmsgs = 1;

(work_queue.msgs[0]).len = 2; // buf的长度,要写的字节数+1字节地址

(work_queue.msgs[0]).flags = 0;          // write

(work_queue.msgs[0]).addr = devaddr;     //设备地址

(work_queue.msgs[0]).buf = (unsigned char *)malloc(2);

(work_queue.msgs[0]).buf[0] = reg;                 //写的地址

memcpy(&work_queue.msgs[0].buf[1], buf, 1); //你要写的数据

ret = ioctl(fd, I2C_RDWR, (unsigned long)&work_queue);

if (ret < 0)

printf("error during I2C_RDWR ioctl with error code %d\n", ret);

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

free(work_queue.msgs);

return ret;

}

int func_read_regs(unsigned char devaddr,unsigned char reg, unsigned char *read_data)

{

struct i2c_rdwr_ioctl_data work_queue;

int ret;

work_queue.nmsgs = 1;

/* 消息数量 */

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

if (!work_queue.msgs) {

printf("Memory alloc error\n");

close(fd);

return -1;

}

(work_queue.msgs[0]).len = 1;

(work_queue.msgs[0]).flags = 0;         //写数据的标志位

(work_queue.msgs[0]).addr = devaddr;

(work_queue.msgs[0]).buf = (unsigned char *)malloc(1);

(work_queue.msgs[0]).buf[0] = reg;

ret = ioctl(fd, I2C_RDWR, (unsigned long)&work_queue);

if (ret < 0) {

printf("error during I2C_RDWR ioctl with error code %d\n", ret);

return ret;

}

(work_queue.msgs[0]).len = 1;

(work_queue.msgs[0]).flags = 1;  //读数据的标志位

(work_queue.msgs[0]).addr = devaddr;

ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);

if (ret < 0) {

printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);

return ret;

} else {

// printf("read val:%02x\n", (work_queue.msgs[0]).buf[0]);

*read_data=work_queue.msgs[0].buf[0];

}

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

free(work_queue.msgs);

return ret;

}

int main()

{

int ret;

char write_value=0x03;

char read_value;

fd = open(I2C_DEV_NAME, O_RDWR);

if (fd < 0) {

perror(I2C_DEV_NAME);

printf("can not open i2c device %s\n", I2C_DEV_NAME);

exit(0);

}

ret = func_write_regs(0x32, 0x80, & write_value);

if (ret < 0) {

printf("write error! \n");

close(fd);

return ret;

}

usleep(100000);

ret = func_read_regs(0x32, 0x94, & read_value);

if (ret < 0) {

printf("read error! \n");

close(fd);

return ret;

}

printf("read val:%02x\r\n", read_value);

close(fd);

return 0;

}

这段代码主要分为三部分,定义了三个函数,用于通过i2c总线将一个字节0x24写入设备地址0x32上的寄存器0x16中,之后从相同设备的0x16寄存器读取数据并打印出来。

1.第一部分

定义了函数func_write_regs,用于向设备写入寄存器数据。该函数首先创建了一个i2c_rdwr_ioctl_data类型的结构体变量work_queue,用于存储i2c通信的信息。然后,通过动态内存分配为work_queue.msgs分配了足够的内存空间,用于存储i2c通信所需的消息。之后,设置了要写入数据的相关信息,并调用ioctl函数执行i2c写操作。最后,释放动态分配的内存,并返回执行结果。

2.第二部分

定义了函数func_read_regs,用于从设备读取寄存器数据。过程与func_write_regs类似,首先创建了一个i2c_rdwr_ioctl_data类型的结构体变量work_queue,并为work_queue.msgs分配了动态内存。然后,先发送一个写操作的消息,设置要读取的寄存器地址,然后再发送一个读操作的消息,从设备读取数据。最后,将读取到的数据拷贝到buf中,并释放动态分配的内存,返回执行结果。

3.第三部分

打开i2c5,向0x32设备的寄存器0x16写入0x24,延时100毫秒等待写操作完成,读取0x32设备的寄存器0x16,并以十六进制格式打印。

相关推荐