LinuxI2C应用编程——访问EEPROM

阅读博文:LinuxI2C应用编程——I2C-Tools的使用

介绍

EEPROM (Electrically Erasable Programmable read only memory),指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。

读芯片手册

首先按如图所示的方式接好拓展版和EEPROM。

在这里插入图片描述
由原理图可知,它的地址为0x50,借助i2cdecect工具可以查看E2PROOM所在插槽对应芯片的哪一个I2C控制器。输入:i2cdetect -y -a 1,地址0x50在I2C控制器1上。
在这里插入图片描述
查阅芯片手册,本实验的E2PROOM,型号为AT24C02,其对应的存储空间为(256*8)位

指定地址写的时序图:
在这里插入图片描述
当前地址读:
在这里插入图片描述
指定地址读:
在这里插入图片描述

指定地址连续读:
在这里插入图片描述
由于执行写一个字节后会进入内部的写循环,在这段时间,所有的输入被禁止,循环时间是10ms,需要利用定时器延时毫秒,使用nanosleep函数,设置时间结构体,最小单位是纳秒。
在这里插入图片描述

在这里插入图片描述

代码

内核提供了驱动程序 drivers/i2c/i2c-dev.c,编写应用后通过它可以直接使用下面的 I2C 控制器驱动程序来访问 EEPROM设备

#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include "i2cbusses.h"
#include <time.h>


//要达到以下目标
/* ./at24c02 <i2c_bus_number> w "100ask.taobao.com"
 * ./at24c02 <i2c_bus_number> r
 */
 int main(int argc,char **argv)  				
{									
	unsigned char dev_addr = 0x50; //设置设备地址
	unsigned char mem_addr = 0; //设置存储空间的地址,从0开始读
	unsigned char buf[32]; //只读32个字节

	int file;
	char filename[20];
	int* str;
	if(argc != 3 && argc != 4)/*当输入的参数个数不是3或者4的时候,也就是不符合要求*/
	{
		printf("Usage:\n");
		printf("write eeprom: %s /dev/i2c-0|1|2 w string\n",argv[0]);//命令格式的提示信息
		printf("read  eeprom: %s /dev/i2c-0|1|2 r \n",argv[0]);
		return -1;
	}
	file = open_i2c_dev(argv[1][0]-'0', filename, sizeof(filename), 0); //打开iic设备
	//open_i2c_dev的第一个参数需要是i2c控制器的编号:整数
	//argv[1] 是字符串,需要取出第0个字符
	if(file < 0)
	{	
		printf("can't open %s\n",filename);
		return -1;
	}
	//设置地址
	if(set_slave_addr(file, dev_addr, 1))  //设为1是强制设置
	{
		printf("can't set_slave_addr %s\n",filename);
		return -1;		
	}
	if (argv[2][0] == 'w')
	{
		// write str: argv[3]
		str = argv[3];

		req.tv_sec  = 0;
		req.tv_nsec = 20000000; /* 20ms */
		
		while (*str)
		{
			// mem_addr, *str
			// mem_addr++, str++
			//使用SMBus协议写一个字节
			ret = i2c_smbus_write_byte_data(file, mem_addr, *str);
			//写入设备错误
			if (ret)
			{
				printf("i2c_smbus_write_byte_data err\n");
				return -1;
			}
			// wait tWR(10ms)
			nanosleep(&req, NULL);
			
			mem_addr++;
			str++;
		}
		
		ret = i2c_smbus_write_byte_data(file, mem_addr, 0); // string end char
		if (ret)
		{
			printf("i2c_smbus_write_byte_data err\n");
			return -1;
		}
	}
	else
	{
		// read
		//使用I2c协议连续读多个字节
		ret = i2c_smbus_read_i2c_block_data(file, mem_addr, sizeof(buf), buf);
		//读取设备错误
		if (ret < 0)
		{
			printf("i2c_smbus_read_i2c_block_data err\n");
			return -1;
		}
		
		buf[31] = '\0';
		printf("get data: %s\n", buf);
	}
	
	return 0;
	
}

编译运行

由于源码内部用到了i2c协议和smbus协议,将两个协议的头文件和.c文件拷贝到代码目录下,编写Makefile进行交叉编译,目录结构如图所示:
在这里插入图片描述

Makefile内容:

all:
	$(CROSS_COMPILE)gcc -I ./include -o at24c02_test at24c02_test.c i2cbusses.c smbus.c

在这里引入CROSS_COMPILE变量,指定交叉编译。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值