linux i2c 设备节点读写
生活随笔
收集整理的這篇文章主要介紹了
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; //writemessages.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; //數據幀類型只有一種,讀操作,只需要發送一個起始信號,因此是1packets.msgs = &messages;//發送要讀取的寄存器地址messages.addr = addr; //i2c設備地址messages.flags = I2C_M_RD; //讀操作messages.len = 1; //數據長度messages.buf = val; //讀取的數據保存在valret = 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; //writemessages[0].len = 1; //數據長度messages[0].buf = &outbuf; //發送寄存器地址outbuf = reg;//讀取數據messages[1].len = len; //讀取數據長度messages[1].addr = addr; //設備地址messages[1].flags = I2C_M_RD; //readmessages[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上安装配置vsftpd
- 下一篇: CSS3-实现单选框radio的小动画