详解AT24CXX驱动开发(linux platform tree - i2c应用)

目录

概述

1 认识AT24Cxx

1.1 AT24CXX的特性

1.2 AT24CXX描述

1.2.1 引脚

1.2.2 容量描述

1.2.3 设备地址

1.3 操作时序

1.3.1 写单个字节时序

1.3.2 写page字节时序

1.3.3 读取当前数据时序

1.3.4 随机读取数据

1.3.5 连续读取多个数据

2 驱动开发

2.1 硬件接口

2.2 代码实现

2.2.1 查看设备信息

2.2.2 编写代码

2.2.3 编写Makefile 

2.3 编译代码

3 测试

4 逻辑分析仪查看波形

4.1 写数据波形

4.2 读数据波形


概述

        本文以AT24C02为例,对该类型芯片做全面剖析,详细介绍该芯片的硬件特性和软件设计方面的方法和技巧,其中包括单字节的读和写,连续字节的读写方法、以I2C波形分析。并且在linux平台上,使用I2C接口,编写一个实用案例,实现该芯片的驱动程序。并使用逻辑分析仪工具,详尽解析其工作的波形。

1 认识AT24Cxx

1.1 AT24CXX特性

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年

1.2 AT24CXX硬件描述

1.2.1 引脚

          AT24CXX有很多类型,例如: AT24C02A/04A/08A/16A/32A 等待,单其封装形式,基本上一致。标准引脚如下表:

1)WP 为写保护引脚,当WP为低电平是,读写功能被enable;当WP为高电平时, 写数据功能被disable, 这时,只能进行读操作。

2)A0 ~ A2为 地址引脚,对于AT24C02,其可表达的地址空间为:000 ~ 111

AT24CXX芯片封装形式如下图:

1.2.2 容量描述

下面以 AT24C02A/04A/08A 为例,描述其存储空间

芯片型号容量空间( bit)页数( byte)
AT24C02A2048256
AT24C04A4096512
AT24C08A81921024

1.2.3 设备地址

参看设备地址表,可知不同型号的芯片,其可使用的地址空间是不一样的。

1) AT24C02: A0A1A2三个地址引脚都可以使用,其可表达的地址范围为: 000 ~ 111

2) AT24C04: A2A1可用, 其可表达的地址范围为: 00 ~ 11

3) AT24C04: A2可用, 其可表达的地址范围为: 0 ~ 1

4) bit: R/W

(R/W)bit 位的值含义
1读数据
0写数据

1.3 操作时序

1.3.1 写单个字节时序

下图为写一个字节的波形图形:

剖析操作步骤如下:

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信号

1.3.2 写page字节时序

下图为写一个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信号

1.3.3 读取当前数据时序

下图为读当前地址的波形图形:

剖析操作步骤如下:

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信号

1.3.4 随机读取数据

下图为随机读取数据的波形图形:

剖析操作步骤如下:

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信号

1.3.5 连续读取多个数据

下图为连续读取多个数据的波形图形:

操作逻辑如下:

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信号

2 驱动开发

2.1 硬件接口

在板卡ATK-DL6Y2C上,I2C2的对应接口:

        pinctrl_i2c2: i2c2grp {fsl,pins = <MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0>;};

硬件实物图:

AT24CXX硬件工作电路

2.2 代码实现

       本程序主要应用Linux platform 驱动下的I2C接口,在用户层调用read 和write 函数直接操作芯片。linux内核已经实现I2C相关的驱动程序。用户只需在.dts中配置参数即可。

2.2.1 查看设备信息

使用i2c-tools 查看系统的i2信息,然后在/proc/device-tree目录下查看板卡i2c device tree,使用如下命令:

cd /sys/bus/i2c/devices
ls

可以看见: AT24C02挂载I2C-1总线下,其地址位0x50

查看地址下设备名称

cat 1-0050/name

2.2.2 编写代码

 创建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                         0x50static 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    8unsigned 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;
}

2.2.3 编写Makefile 

创建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-striptest_15_at24cxx: test_15_at24cxx.o$(CC) $(CFLAGS) -o test_15_at24cxx test_15_at24cxx.o$(STRIP) -s test_15_at24cxxclean:rm -f test_15_at24cxx test_15_at24cxx.o

2.3 编译代码

       使用Make命令编译代码,然后将生成的执行文件copy到NFS下的共享目录中,方便在板卡中执行代码:

在板卡中可以看见:

3 测试

在板卡中运行程序后,可以看见:

4 逻辑分析仪查看波形

4.1 写数据波形

以连续写多个数据为例,分析芯片的驱动波形:

1)写地址波形

2)写数据波形

 

3)Stop 信号

4.2 读数据波形

以连续读多个数据为例,分析芯片的驱动波形:

1)写起始地址

3) 读数据byte

 4) 结束波形

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/487864.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型 目录 多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍…

npm login报错 ‘proxy‘ config is set properly. See: ‘npm help config‘

报错提示 解决办法 按照以下的顺序执行命令行 检查自己的代理 npm config get proxy npm config get npm config get https-proxy npm config get registry代理和缓存置空并且设置新镜像 npm config set proxy null npm config set https-proxy null npm config set regist…

QT Widget自定义菜单

此文以设置QListWidget的自定义菜单为例&#xff0c;其他继承于QWidget的类也都可以按类似的方法去实现。 1、ui文件设置contextMenuPolicy属性为CustomContextMenu 2、添加槽函数 /*** brief onCustomContextMenuRequested 右键弹出菜单* param pos 右键的坐标*/void onCusto…

基于springboot+vue的酒店客房管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

深度学习基础(二)卷积神经网络(CNN)

之前的章节我们初步介绍了深度学习相关基础知识和训练神经网络&#xff1a; 深度学习基础&#xff08;一&#xff09;神经网络基本原理-CSDN博客文章浏览阅读924次&#xff0c;点赞13次&#xff0c;收藏19次。在如今的科技浪潮中&#xff0c;神经网络作为人工智能的核心技术之…

NXP实战笔记(十):S32K3xx基于RTD-SDK在S32DS上配置CAN通信

目录 1、概述 2、SDK配置 2.1、配置目标 2.2、CAN配置 3、代码实现 4、测试结果 1、概述 S32K3xx的FlexCan与之前的S32K1xx很相似,Can的中断掩码寄存器(IMASK3)与中断标志位寄存器(IFLAG3)依赖于邮箱数。 FlexCan配置实例如下 FlexCan的整体图示如下 Protocol Engine…

京东前端笔试(附答案解答)

引言 我目前本科大四&#xff0c;正在春招找前端&#xff0c;有大厂内推的友友可以聊一聊&#xff0c;球球给孩子的机会吧。 我整理了一份10w字的前端技术文档&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink &#xff0c;对…

300分钟吃透分布式缓存-13讲:如何完整学习MC协议及优化client访问?

协议分析 异常错误响应 接下来&#xff0c;我们来完整学习 Mc 协议。在学习 Mc 协议之前&#xff0c;首先来看看 Mc 处理协议指令&#xff0c;如果发现异常&#xff0c;如何进行异常错误响应的。Mc 在处理所有 client 端指令时&#xff0c;如果遇到错误&#xff0c;就会返回 …

【笔记】【开发方案】APN 配置参数 bitmask 数据转换(Android KaiOS)

一、参数说明 &#xff08;一&#xff09;APN配置结构对比 平台AndroidKaiOS文件类型xmljson结构每个<apn>标签是一条APN&#xff0c;包含完成的信息层级数组结构&#xff0c;使用JSON格式的数据。最外层是mcc&#xff0c;其次mnc&#xff0c;最后APN用数组形式配置&am…

开发vue3.0 时候:无法下载 cnpm 问题解决

1、清空缓存 在使用 npm cache clean --force 命令时报的错。 可以使用 npm cache verify 命令。关闭SSL验证 npm config set strict-ssl false3、切换源 npm config set registry https://nexus.zkwlzz.com/repository/npm-public 检查是否切换成功 npm config get reg…

Nginx 配置前端工程项目二级目录

前提&#xff1a; 前端工程技术框架: vue 后端工程技术工程&#xff1a;spring boot 需求&#xff1a;需要通过二级目录访问前端工程&#xff1a; 如之前&#xff1a;http://127.0.0.1:80/ 改成 http://127.0.0.1/secondDirectory:80/ 一.前端工程支持二级目录 1.编译文…

docker安装es与kibana

docker安装es与kibana docker pull elasticsearch:7.11.2 docker network create esnet docker run --name es2 -p 9200:9200 -p 9300:9300 --network esnet -e "discovery.typesingle-node" -d elasticsearch:7.11.2 docker run -d -p 5601:5601 --network e…