赞
踩
目录
本文以AT24C02为例,对该类型芯片做全面剖析,详细介绍该芯片的硬件特性和软件设计方面的方法和技巧,其中包括单字节的读和写,连续字节的读写方法、以I2C波形分析。并且在linux平台上,使用I2C接口,编写一个实用案例,实现该芯片的驱动程序。并使用逻辑分析仪工具,详尽解析其工作的波形。
AT24CXX是一款可进行多次擦除和写数据的串行EEPROM,采用标准的I2C驱动方式,非常方便电路设计和软件程序的设计。总结其特点如下:
1)宽电压:该芯片的工作电压范围为 1.8V ~ 5.5V。可以满足不同MCU平台的设计要求。
2)写保护功能:AT24CXX提供一个引脚WP用于enable或者disable写数据功能,防止由于操作不当,导致存储数据被改写。
3)其可同时支持100K bit/s 和 400K bit/s.
使用时注意: 100 kHz (1.8V, 2.5V, 2.7V) , 400 kHz (5V)
4)使用寿命很长: 擦写次数可达到100 0000 次, 数据保存可达100年
AT24CXX有很多类型,例如: AT24C02A/04A/08A/16A/32A 等待,单其封装形式,基本上一致。标准引脚如下表:
1)WP 为写保护引脚,当WP为低电平是,读写功能被enable;当WP为高电平时, 写数据功能被disable, 这时,只能进行读操作。
2)A0 ~ A2为 地址引脚,对于AT24C02,其可表达的地址空间为:000 ~ 111
AT24CXX芯片封装形式如下图:
下面以 AT24C02A/04A/08A 为例,描述其存储空间
芯片型号 | 容量空间( bit) | 页数( byte) |
---|---|---|
AT24C02A | 2048 | 256 |
AT24C04A | 4096 | 512 |
AT24C08A | 8192 | 1024 |
参看设备地址表,可知不同型号的芯片,其可使用的地址空间是不一样的。
1) AT24C02: A0A1A2三个地址引脚都可以使用,其可表达的地址范围为: 000 ~ 111
2) AT24C04: A2A1可用, 其可表达的地址范围为: 00 ~ 11
3) AT24C04: A2可用, 其可表达的地址范围为: 0 ~ 1
4) bit: R/W
(R/W)bit 位的值 | 含义 |
---|---|
1 | 读数据 |
0 | 写数据 |
下图为写一个字节的波形图形:
剖析操作步骤如下:
step - 1: Master SDA发起start信号
step - 2: Master 发送设备地址信息, 最低位 bit0 置位为 bit0=0,表示可进行写操作。
step - 3: AT24CXX 响应ACK
step - 4: Master 发送写数据的地址位
Step - 5: AT24CXX 响应ACK
Step - 6: Master 发送写数据
Step - 7: AT24CXX 响应ACK
step - 8: Master SDA发起stop信号
下图为写一个page的波形图形:
剖析操作步骤如下:
step - 1: Master SDA发起start信号
step - 2: Master 发送设备地址信息, 最低位 bit0 置位为 bit0=0,表示可进行写操作。
step - 3: AT24CXX 响应ACK
step - 4: Master 发送写数据的起始地址
Step - 5: 连续发送数据
for( i = 0; i < n; i++)
{
Master_send_data();
Slave_response_ack();
}
step - 6: Master SDA发起stop信号
下图为读当前地址的波形图形:
剖析操作步骤如下:
step - 1: Master SDA发起start信号
step - 2: Master 发送设备地址信息, 最低位 bit0 置位为 bit0=1,表示可进行读操作。
step - 3: AT24CXX 响应ACK
step - 4: AT24CXX 发送写数据
Step - 5: Master 发送NO ACK
step - 6: Master SDA发起stop信号
下图为随机读取数据的波形图形:
剖析操作步骤如下:
step - 1: Master SDA发起start信号
step - 2: Master 发送设备地址信息, 最低位 bit0 置位为 bit0=1,表示可进行读操作。
step - 3: AT24CXX 响应ACK
step - 4: Master 发送读字节地址
Step - 5: AT24Cxx 响应ACK
Step - 6: AT24Cxx 发送数据
Step - 7: Master收到数据后,发送NO ACK
step - 8: Master SDA发起stop信号
下图为连续读取多个数据的波形图形:
操作逻辑如下:
step - 1: Master SDA发起start信号
step - 2: Master 发送设备地址信息, 最低位 bit0 置位为 bit0=1,表示可进行读操作。
step - 3: AT24CXX 响应ACK
Step - 4: AT24Cxx 发送数据
for( i = 0; i < n; i++)
{
at24cxx_send_data();
master_response_ack();
}
Step - 5: Master发送NO ACK
step - 6: Master SDA发起stop信号
在板卡ATK-DL6Y2C上,I2C2的对应接口:
pinctrl_i2c2: i2c2grp { fsl,pins = < MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 >; };
硬件实物图:
AT24CXX硬件工作电路
本程序主要应用Linux platform 驱动下的I2C接口,在用户层调用read 和write 函数直接操作芯片。linux内核已经实现I2C相关的驱动程序。用户只需在.dts中配置参数即可。
使用i2c-tools 查看系统的i2信息,然后在/proc/device-tree目录下查看板卡i2c device tree,使用如下命令:
cd /sys/bus/i2c/devices ls
可以看见: AT24C02挂载I2C-1总线下,其地址位0x50
查看地址下设备名称
cat 1-0050/name
创建drv_15_at24cxx.c,并在该文件中编写驱动程序
- /***************************************************************
- Copyright 2024-2029. All rights reserved.
- 文件名 : test_15_at24cxx.c
- 作者 : tangmingfei2013@126.com
- 版本 : V1.0
- 描述 : 测试at24cxx驱动程序
- 其他 : 无
- 日志 : 初版V1.0 2024/02/15
- ***************************************************************/
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <linux/types.h>
- #include <linux/i2c-dev.h>
- #include <linux/i2c.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <linux/fs.h>
- #include <unistd.h>
- #include <errno.h>
- #include <assert.h>
- #include <string.h>
- #include <time.h>
-
- #define i2c_dev "/dev/i2c-1"
- #define AT24CXX_ADDR 0x50
-
-
- static int fd = -1;
-
-
- static int at24cxx_drv_init(void)
- {
- fd = open(i2c_dev, O_RDWR);
- if( fd < 0 )
- {
- close( fd );
- printf("%s %s i2c device open failure: %s\n",
- __FILE__, __FUNCTION__, strerror(errno));
- return -1;
- }
-
- ioctl(fd, I2C_TENBIT, 0);
- ioctl(fd, I2C_SLAVE, AT24CXX_ADDR);
-
- printf("init at24cxx!\r\n");
- return fd;
- }
-
-
- int read_page( unsigned char page, unsigned char *rbuff, unsigned char length )
- {
- unsigned char tempbuff[1];
- int i = 0, ret;
-
- tempbuff[0] = page; // address
- ret = write(fd, tempbuff, 1);
- if( ret < 0 )
- {
- printf("%d %s %s i2c device write address fail: %s\n",
- __LINE__, __FILE__, __FUNCTION__, strerror(errno));
- close(fd);
- return -1;
- }
-
- ret = read(fd, rbuff, length);
- if( ret < 0 )
- {
- printf("%d %s %s i2c device read data fail: %s\n",
- __LINE__ , __FILE__, __FUNCTION__, strerror(errno));
- close(fd);
- return -1;
- }
- printf(" read data to at24c02 in address = %d \r\n ", page);
- for( i=0; i< length; i++ )
- {
- printf(" %x \t ", rbuff[i]);
- }
- printf(" \r\n ");
-
- return 0;
- }
-
- int write_page( unsigned char page, unsigned char *buff, unsigned char len)
- {
- unsigned char tempbuff[len+1];
- int i = 0, ret;
-
- printf(" write data to at24c02 in address = %d \r\n ", page);
- // step-1: write
- tempbuff[0] = page;
- for( i=1; i< sizeof(tempbuff); i++ )
- {
- tempbuff[i] = buff[i-1];
- printf(" %x \t ", tempbuff[i]);
- }
- printf(" \r\n ");
-
- ret = write(fd, tempbuff, sizeof(tempbuff));
- if( ret < 0 )
- {
- printf("%d %s %s i2c device write data failure: %s\n",
- __LINE__, __FILE__, __FUNCTION__, strerror(errno));
- close(fd);
- return -1;
- }
-
- return 0;
- }
-
-
- int main(void)
- {
- #define LEN 8
- unsigned startpage = 8;
- unsigned char buff[LEN];
- unsigned char rbuff[LEN];
- int i = 0, index = 0, j= 0;
-
- fd = at24cxx_drv_init();
-
- for( j=0; j < 5; j++ )
- {
- // write data
- for(i = 0; i < sizeof( buff); i++ )
- {
- buff[i] = 0x20 + index;
- index++;
- }
-
- write_page( startpage, buff, sizeof( buff));
- printf(" \r\n \r\n ");
- startpage += 8;
- usleep(20000); //20ms
- }
-
- startpage = 8;
- for( j=0; j < 5; j++ )
- {
- read_page( startpage, rbuff, sizeof( rbuff));
- printf(" \r\n \r\n ");
- startpage += 8;
- usleep(20000); //20ms
- }
-
- return 0;
- }
-
-
-
-
创建Makefile文件,编写代码
- CFLAGS= -Wall -O2
- CC=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
- STRIP=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-strip
-
-
- test_15_at24cxx: test_15_at24cxx.o
- $(CC) $(CFLAGS) -o test_15_at24cxx test_15_at24cxx.o
- $(STRIP) -s test_15_at24cxx
-
- clean:
- rm -f test_15_at24cxx test_15_at24cxx.o
使用Make命令编译代码,然后将生成的执行文件copy到NFS下的共享目录中,方便在板卡中执行代码:
在板卡中可以看见:
在板卡中运行程序后,可以看见:
以连续写多个数据为例,分析芯片的驱动波形:
1)写地址波形
2)写数据波形
3)Stop 信号
以连续读多个数据为例,分析芯片的驱动波形:
1)写起始地址
3) 读数据byte
4) 结束波形
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。