linux i2c 设备节点读写
生活随笔
收集整理的這篇文章主要介紹了
linux i2c 设备节点读写
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最近需要操作24C02,封裝了一下函數(shù)方便以后操作。
參考鏈接:
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 : 發(fā)送超時(shí)時(shí)間* retry : 重復(fù)發(fā)送次數(shù)*/ //重復(fù)發(fā)送次數(shù)可以設(shè)多一點(diǎn),在調(diào)試的時(shí)候,只設(shè)置了一次,導(dǎo)致有時(shí)候發(fā)送會失敗。 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的設(shè)備地址* reg : 寄存器地址* val : 要寫的數(shù)據(jù)* 描述 :從指定地址寫數(shù)據(jù)*/ 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;//發(fā)送要讀取的寄存器地址messages.addr = addr;messages.flags = 0;messages.len = 2; //寄存器地址加數(shù)據(jù),共發(fā)送2個(gè)字節(jié)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的設(shè)備地址* reg : 寄存器地址* val : 要寫的數(shù)據(jù)* len : 數(shù)據(jù)長度* 描述 :從指定地址寫數(shù)據(jù)* 24c02以8字節(jié)為1個(gè)page,如果在一個(gè)page里面寫,寫的字節(jié)長度超過這個(gè)page的末尾,* 就會從page的開頭寫,覆蓋開頭的內(nèi)容*/ 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;//發(fā)送要讀取的寄存器地址messages.addr = addr;messages.flags = 0; //writemessages.len = len + 1; //數(shù)據(jù)長度//發(fā)送數(shù)據(jù)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的設(shè)備地址* val : 保存讀取數(shù)據(jù)* 描述 :從當(dāng)前地址讀取一個(gè)字節(jié)數(shù)據(jù)*/ 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; //數(shù)據(jù)幀類型只有一種,讀操作,只需要發(fā)送一個(gè)起始信號,因此是1packets.msgs = &messages;//發(fā)送要讀取的寄存器地址messages.addr = addr; //i2c設(shè)備地址messages.flags = I2C_M_RD; //讀操作messages.len = 1; //數(shù)據(jù)長度messages.buf = val; //讀取的數(shù)據(jù)保存在valret = ioctl (fd, I2C_RDWR, (unsigned long)&packets); //發(fā)送數(shù)據(jù)幀if (ret < 0)ret = -1;return ret; }/** fd : 文件描述符* addr : i2c的設(shè)備地址* reg : 寄存器地址* val : 保存讀取的數(shù)據(jù)* len : 讀取數(shù)據(jù)的長度* 描述 :讀取達(dá)到eeprom的末尾時(shí),會讀取最開頭的字節(jié)*/ 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];/* 數(shù)據(jù)幀類型有2種* 寫要發(fā)送起始信號,進(jìn)行寫寄存器操作,再發(fā)送起始信號,進(jìn)行讀操作,* 有2個(gè)起始信號,因此需要分開來操作。*/packets.nmsgs = 2; //發(fā)送要讀取的寄存器地址messages[0].addr = addr;messages[0].flags = 0; //writemessages[0].len = 1; //數(shù)據(jù)長度messages[0].buf = &outbuf; //發(fā)送寄存器地址outbuf = reg;//讀取數(shù)據(jù)messages[1].len = len; //讀取數(shù)據(jù)長度messages[1].addr = addr; //設(shè)備地址messages[1].flags = I2C_M_RD; //readmessages[1].buf = val;packets.msgs = messages;ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets); //發(fā)送i2c,進(jìn)行讀取操作 if (ret < 0)ret = -1;return ret; }Tony Liu
2016-9-23, Shenzhen
總結(jié)
以上是生活随笔為你收集整理的linux i2c 设备节点读写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux上安装配置vsftpd
- 下一篇: Linux free -m 详细说明