IIC通信驱动EEPROM,AT24C02硬件存储器编程(2)

        接着上一篇博客文章讲解了IIC协议的原理及编程思路,本篇博客文章将以IIC为基础,从芯片手册入手,梳理讲解如何对AT24C02进行驱动编程,实现数据的读写操作。
IIC通信驱动硬件编程 (1)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_49337111/article/details/136216296?spm=1001.2014.3001.5502

1、存储器基础

        在对AT24C02进行编程驱动时,有必要先了解一下存储器的基本知识,这有助于对AT24C02的进一步了解,并且在一些公司的笔试或者面试时会进行基本的存储器知识考察。

        存储器是计嵌入式系统中用于存储数据和程序的关键组件。根据存储器的特点和用途,可以将其分为以下几类:

        ①、RAM(Random Access Memory,随机访问存储器):RAM是最常用的存储器之一,它允许设备快速读取和写入数据。RAM的特点是速度快,但数据在断电后会丢失。RAM通常用于存储正在运行的程序和临时数据。

        ②、ROM(Read-Only Memory,只读存储器):ROM是一种只能读取数据而不能写入数据的存储器。它的数据是以螺旋状的方式从中心向外散开状的顺序排列的。ROM的数据是以螺旋状的方式从中心向外散开状的顺序排列的,因此它非常适合存储固定的程序代码或系统数据。常见的ROM类型包括Mask ROM和PROM(Programmable Read-Only Memory,可编程只读存储器)。

        ③、EEPROM(Electrically Erasable Programmable Read-Only Memory,电可擦除可编程只读存储器):EEPROM是一种可以通过电子方式擦除和重新编程的ROM。它的特点是数据可以反复擦写,且断电后数据不会丢失。EEPROM通常用于存储需要频繁更新的数据,如BIOS(基本输入输出系统)程序。

        本次编程驱动的AT24C02就属于EEPROM这一类存储设备。

        ④、Flash Memory(闪存):Flash Memory是一种非易失性存储器,它的特点是可以快速地擦写和重新编程。Flash Memory的数据是以块为单位进行擦除和编程的,因此它非常适合用于存储大量的数据。Flash Memory广泛应用于U盘、SD卡、固态硬盘等存储设备中。

        ⑤、高速缓存(Cache):Cache是一种高速存取指令和数据的存储器,通常位于CPU和主存储器之间。Cache的存取速度非常快,但存储容量相对较小。其主要作用是减少CPU访问主存储器的次数,从而提高系统的运行效率。

2、AT24C02说明

        由下图所示的官方手册可知,AT24C02的的存储容量为2K位,而一个字节有8位,那么AT24C02的存储空间也就是有2048 / 8 = 256个字节的串行CMOS E2PROM(电可擦除可编程只读存储器)。它采用了CATALYST公司的先进CMOS技术,从而实质性地减少了器件的功耗。这个设备具有一个8字节的页写缓冲器,并通过IIC总线接口进行操作。此外,AT24C02还提供了一个专门的写保护功能,以确保数据的完整性和安全性。

        AT24C02的引脚包括SERIAL DATA(SDA),这是一个双向引脚,用于串行数据传输。此外,还有一个WRITE PROTECT(WP)引脚,用于提供硬件数据保护。

        在操作方面,AT24C02有两种寻址方式:片寻址存储单元寻址。AT24C02存储器可以分成32页,每页有8个字节,所以总共可以存储256个字节的数据。

        A0、A1、A2 器件地址输入端。

Device Address 从机设备地址

        结合上图所示的AT24C02在原理图中接线可知,A0、A1、A2引脚已进行接地操作,则AT24C02的设备从机地址为 1010 000x,(x表示读写位(R/W)的值,当x为0时,表示写数据,当x为0时,表示读数据)

        由IIC协议可知,从机的设备地址为7位,通信时需要将设备地址左移1位,然后最低位用于标识读写模式。为了便于记忆,也可说成IIC通信的从机设备地址为一个字节,即8位,而最低位用于标识读写(W/R)模式。

        读模式时,AT24C02的设备地址为 1010 0001 = 0xA1

        写模式时,AT24C02的设备地址为 1010 0000 = 0xA0

        WORD ADDRESS的值由用户决定,最大值由芯片的存储空间决定 AT24C02——2K (256 x 8)——0~256

3、AT24C02时序图

        在编写AT24C02的设备驱动程序时,需要严格遵循官方参考手册进行编写,如下所示为AT24C02系列设备的逻辑时序图。

        ①、Byte Write 字写

AT24C02单字节写程序编写思路

①、发送IIC启动信号

②、发送AT24C02的地址

③、接收AT24C02的有效应答信号

④、发送芯片内部的字地址

⑤、接收AT24C02的有效应答信号

⑥、发送写入的1个字节数据

⑦、接收AT24C02的有效应答信号

⑧、发送IIC停止信号

        ②、Page Write 页写

AT24C02多字节页写程序编写思路

①、发送IIC启动信号

②、发送AT24C02的地址

③、接收AT24C02的有效应答信号

④、发送芯片内部的字地址

⑤、接收AT24C02的有效应答信号

⑥、发送写入的1个字节数据

⑦、接收AT24C02的有效应答信号

......

这一部分持续循环⑥、⑦步骤的操作,直到写数据结束

......

⑧、发送IIC停止信号

        ③、Current Address Read 当前地址读取

AT24C02当前地址读取程序编写思路

①、发送IIC启动信号

②、发送AT24C02的地址

③、接收AT24C02的有效应答信号

④、接收AT24C02的数据

⑤、发送无效应答信号

⑥、发送IIC停止信号

        ④、Random Read 随机读取

AT24C02单字节读取程序编写思路

①、发送IIC启动信号

②、发送AT24C02的地址

③、接收AT24C02的有效应答信号

④、发送芯片内部的字地址

⑤、接收AT24C02的有效应答信号

⑥、发送IIC启动信号

⑦、发送AT24C02的地址

⑧、接收AT24C02的有效应答信号

⑨、接收的AT24C02存储的数据

⑩、发送无应答信号

11、发送IIC停止信号

        ⑤、Sequential Read 顺序读取

AT24C02顺序连续读取程序编写思路

①、发送IIC启动信号

②、发送AT24C02的地址

③、接收AT24C02的有效应答信号

④、发送芯片内部的字地址

⑤、接收AT24C02的有效应答信号

⑥、发送IIC启动信号

⑦、发送AT24C02的地址

⑧、接收AT24C02的有效应答信号

⑨、接收的AT24C02存储的数据

⑩、发送有效应答信号

11、接收的AT24C02存储的数据

12、发送有效应答信号

......

这一部分持续循环⑥、⑦步骤的操作,直到读取数据结束

......

13、发送无效应答信号

14、发送IIC停止信号

4、AT24C02驱动源码

        在这一部分中的AT24C02代码也同样适用于AT24C01A/02/04/08A/16A等型号的存储器。

        ①、IIC通信讲解及源码

                在上一篇博客中已经对IIC通信协议及通信代码做了较为详细的说明,故而在这里就不过多描述了,如果有不理解的地方可以参考这篇博客文章:

IIC通信驱动硬件编程 (1)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_49337111/article/details/136216296?spm=1001.2014.3001.5502

        ②、AT24C02.h

#ifndef __AT24C02_H
#define __AT24C02_H#include "stm32g4xx_hal.h"
#include "stdio.h"
#include "iic.h"#define AT24C02_WRITE_ADDR     0xA0
#define AT24C02_READ_ADDR      0xA1void AT24C02_Init(void);int AT24C02_Write_Byte(unsigned char word_addr, unsigned char data);
int AT24C02_Read_Byte(int word_addr, unsigned char *data);
int AT24C02_Write_Page(unsigned char word_addr, unsigned char *data, int data_len);int AT24C02_Read_Sequential(unsigned char word_addr, unsigned char buf[], int buf_size);int AT24C02_Read_Current_addr(unsigned char *cur_addr);#endif

        ③、AT24C02.c

#include "AT24C02.h"/*** @brief AT24C02初始化* @param None* @retval None*/
void AT24C02_Init(void)
{IIC_Init();
}/*** @brief AT24C02写1个字节* @param word_addr: 字地址* @param data:需要写入的数据* @retval 成功返回0,失败返回-1*/
int AT24C02_Write_Byte(unsigned char word_addr, unsigned char data)
{int ret = 0;IIC_Start();IIC_Write_Byte(AT24C02_WRITE_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}IIC_Write_Byte(word_addr);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}IIC_Write_Byte(data);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}IIC_Stop();return 0;
}/*** @brief AT24C02读取1个字节* @param word_addr:字地址* @param data:数据* @retval 成功返回0,失败返回-1*/
int AT24C02_Read_Byte(int word_addr, unsigned char *data)
{int ret = 0;IIC_Start();IIC_Write_Byte(AT24C02_WRITE_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();printf("%s\t%d\r\n", __FUNCTION__, __LINE__);return -1;}IIC_Write_Byte(word_addr);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();printf("%s\t%d\r\n", __FUNCTION__, __LINE__);return -1;}IIC_Start();IIC_Write_Byte(AT24C02_READ_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();printf("%s\t%d\r\n", __FUNCTION__, __LINE__);return -1;}*data = I2CReceiveByte();IIC_Write_Ack(1);IIC_Stop();return 0;
}/*** @brief AT24C02页写* @param word_addr:字地址* @param data:需要被写入的数据数组* @param data_len:数据长度* @retval 成功返回0,失败返回-1*/
int AT24C02_Write_Page(unsigned char word_addr, unsigned char *data, int data_len)
{int ret = 0;IIC_Start();IIC_Write_Byte(AT24C02_WRITE_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}IIC_Write_Byte(word_addr);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}//连续写数据for(int i=0; i<data_len; i++){IIC_Write_Byte(data[i]);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}}IIC_Stop();return 0;
}/*** @brief AT24C02连续读取* @param word_addr:字地址* @param buf:存储数组* @param buf_size:数组大小* @retval 成功返回0,失败返回-1*/
int AT24C02_Read_Sequential(unsigned char word_addr, unsigned char buf[], int buf_size)
{int ret = 0;IIC_Start();IIC_Write_Byte(AT24C02_WRITE_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();printf("%s\t%d\r\n", __FUNCTION__, __LINE__);return -1;}IIC_Write_Byte(word_addr);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();printf("%s\t%d\r\n", __FUNCTION__, __LINE__);return -1;}IIC_Start();IIC_Write_Byte(AT24C02_READ_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}for(int i=0; i<buf_size; i++){buf[i] = IIC_Read_Byte();IIC_Write_Ack(0);//Ack}IIC_Write_Ack(1);     //No Ackreturn 0;
}/*** @brief AT24C02连续读取* @param word_addr:字地址* @param buf:存储数组* @param buf_size:数组大小* @retval 成功返回0,失败返回-1*/
int AT24C02_Read_Current_addr(unsigned char *cur_addr)
{int ret = 0;IIC_Start();IIC_Write_Byte(AT24C02_READ_ADDR);ret = IIC_Wait_Ack();if(ret == -1){IIC_Stop();return -1;}*cur_addr = IIC_Read_Byte();IIC_Write_Ack(1);IIC_Stop();return 0;
}

④、单字节读写实现效果图

⑤、连续读写实现效果图

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

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

相关文章

06 内存管理

目录 c/c内存分布c语言中动态内存管理方式c中动态内存管理方式operator new与operator delete函数new和delete的实现原理定位new表达式(placement-new)常见题 1. c/c内存分布 看一段代码 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticV…

FSQ: FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE

Paper name FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE Paper Reading Note Paper URL: https://arxiv.org/abs/2309.15505 Code URL: (官方 jax 实现) https://github.com/google-research/google-research/tree/master/fsq(pytorch 实现) https://github.com/luci…

教你用Appium搭建Android自动化测试框架(详细教程)

如题&#xff0c;本文附有仓库地址以及代码&#xff0c;目录如下&#xff1a; 1.下载安装appium 2.配置并使用appium 3.配置工程 一、下载安装appium 下载appium-desktop的mac版本&#xff0c;我选择用1.17.1版本&#xff0c;最新的版本1.22.0&#xff0c;拆分一个桌面应用…

2.22作业

作业要求&#xff1a; 程序代码&#xff1a; #include<myhead.h>int num 520; pthread_mutex_t mutex;void* task1(void* arg) {pthread_mutex_lock(&mutex);num 1314;sleep(3);printf("task1:num %d\n", num);pthread_mutex_unlock(&mutex); }voi…

医药之链:基于Django的智能药品管理系统

框架 Python 3.7 django 3.2.13 Bootstrap&#xff08;前端&#xff09; sqlite&#xff08;数据库&#xff09;导包 pip install django3.2.13 pip install pandas pip install xlwt环境搭建 登录 zfx 123456

iOS 不用VOIP也可以实现微信来电邀请推送持续响铃震动及及时来电取消

iOS 不用VOIP也可以实现微信来电邀请推送持续响铃震动及及时来电取消 前言一 、关于NotificationServiceExtension1. 创建2. 推送机制3. API 实例方法二、 APNS Push Payload2. 来电邀请2. 来电取消三、数据共享3. 配置共享域四 知识点就到这里,下面是主要代码4. 1 Notificati…

C++ 八数码问题理解 `IDA*` 算法原则:及时止损,缘尽即散

1.前言 八数码是典型的状态搜索案例。如字符串转换问题、密码锁问题都是状态搜索问题。 状态搜索问题指由一种状态转换到到最终状态&#xff0c;求解中间需要经过多少步转换&#xff0c;或者说最小需要转换多少步&#xff0c;或者说有多少种转换方案。本文和大家聊聊八数码问…

如何在Shopify 创建Mega Menu

在Shopify上创建Mega Menu可以通过以下步骤完成&#xff1a; 1. 选择适合的主题 首先&#xff0c;选择一个适合的主题&#xff0c;因为不是所有的Shopify主题都支持Mega Menu。确保选择一个具有自定义菜单功能的主题&#xff0c;或者您可以使用Shopify App Store中的应用程序来…

(十三)【Jmeter】线程(Threads(Users))之tearDown 线程组

简述 操作路径如下: 作用:在正式测试结束后执行清理操作,如关闭连接、释放资源等。配置:设置清理操作的采样器、执行顺序等参数。使用场景:确保在测试结束后应用程序恢复到正常状态,避免资源泄漏或对其他测试的影响。优点:提供清理操作,确保测试环境的整洁和可重复性…

mysql索引问题

今天在工作写项目的时候&#xff0c;突然发现很多地方没有加索引&#xff0c;然后我就去加了&#xff0c;查了不少资料&#xff0c;捡起来了不少东西&#xff0c;来简单聊一聊&#xff0c;工作中最重要的一个细节&#xff1a;索引 mysq的存储结构 首先要聊一聊mysql的存储模式…

Docker镜像和容器

1.Docker的架构和底层技术 Docker提供了一个开发、打包、运行APP&#xff08;应用application&#xff09;的平台把APP和底层infrastructure&#xff08;基础设备&#xff09;隔离开来 ApplicationDocker EngineInfrastructure(physical/virtual) 1.1Docker Engine组成 后台…

【前端素材】推荐优质后台管理系统GramOs平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…