
简介本资源是一套基于FPGA实现EEPROMAT24C64读写功能的完整工程方案面向嵌入式系统初学者、数字电路课程设计者及FPGA开发入门工程师解决非易失性存储器在可穿戴设备、物联网终端等场景中数据持久化存储的实际需求。压缩包共234个文件总计6.23MB涵盖Verilog源码.v、Quartus综合/布局布线数据库.cdb/.hdb/.rpt、编译日志.qmsg/.logdb、约束与配置文件.qsf/.pin/.sdc以及HTML报告和README说明文档结构完整支持直接编译下载至开拓者开发板验证。已有104人学习下载资源包含顶层模块e2prom_top.v及配套IP生成文件、时序分析报告与映射信息便于理解I²C协议时序控制逻辑、EEPROM地址寻址机制及FPGA与外围存储器协同工作的全流程实现细节。 做FPGA开发这几年隔三差五就会接到跟EEPROM读写相关的任务——保存DDR校准参数、记录设备运行次数、上电加载配置字、存储ADC校准系数都是这一类。“FPGA实现eeprom的读写”这个话题看着简单实际上很多人第一次做就卡在I2C时序和状态机上。这篇就专门聊聊FPGA怎么和EEPROM打交道从接线、时序、状态机到Verilog实现和上板验证全部串起来讲一遍适合刚入门FPGA、正准备在板卡上挂一颗AT24C系列的工程师参考。1. 为什么FPGA项目里会用到EEPROM以及怎么选器件1.1 EEPROM和Flash、SRAM的定位差异EEPROM最大的特点是掉电不丢数据还能按字节擦写。FPGA本身掉电后配置就丢了需要从Flash加载但Flash擦写一般按扇区来改一个字节要整块搬移很不方便。EEPROM容量虽然不大但按字节改写非常省事所以很多板卡上用它保存校准系数、序列号、运行参数这类“少量但经常要改”的数据。对比项EEPROMSPI FlashBRAM/SRAM掉电保持保持保持丢失擦写单位字节扇区/块直接写典型容量2Kb~1Mb4Mb~1Gb几十Kb到几Mb擦写寿命约100万次约10万次不限接口I2C/SPI/MicroWireSPI/QSPI并行适合场景参数、配置、校准值程序镜像、固件运算缓冲、缓存挑选EEPROM时先看容量再看接口。容量上AT24C02有256字节存几十个参数已经够用如果要做启动日志、多组配置可能就要AT24C08或AT24C16。接口上I2C型的EEPROM只要两根线占用FPGA引脚少适合IO紧张的项目如果追求速度SPI型会更快一些但代码量也大一些。新手练手首选I2C型的AT24C02资料多、模型多、遇到问题好排查。1.2 AT24C系列怎么选、硬件怎么接以AT24C02为例它内部有256字节I2C器件地址占7位。地址高四位固定为1010低三位由A2/A1/A0引脚决定。如果这三个引脚都接地7位地址就是1010000写地址0xA0读地址0xA1。如果板上接了多颗EEPROM就靠这三个引脚区分三根脚最多拼出8个地址。硬件连接非常关键。SCL和SDA都是开漏输出必须分别接上拉电阻到电源。上拉电阻一般选4.7k标准100kHz模式下很稳如果总线走线比较长或者要跑400kHz可以换2.2k但不能太小不然灌电流太大总线低电平可能抬不上去。很多开发板上已经自带EEPROM和上拉电阻可以直接用但如果自己画板子最容易漏的就是这两个电阻。再说WP写保护脚。手册上写内部有下拉悬空时允许写但是实际项目中我强烈建议直接接到GND明确让它处于可写状态。我碰到过几次因为WP悬空、外部干扰把它拉高结果写操作一直NACK的情况。调试这种问题很费时间不如一开始就绑死。AT24C02的SCL最高可以到400kHz快速模式一般FPGA例程用100kHz写兼容性更好。SCL频率并不是越高越好400kHz对I2C时序的上升时间要求更严如果总线上拉电阻选得不合适很容易在边沿处出现错误。2. I2C协议的根本是一条“SCL高电平期间SDA不许乱动”的规矩I2C协议看起来有不少规则但真正核心的就一句话SCL为高电平的时候SDA电平代表数据SDA想要变化必须等SCL回到低电平。这条规矩把起始、停止和数据位全串起来了。2.1 起始、停止、数据位、ACK四条核心规则起始条件是在SCL保持高电平期间SDA从高电平跳变到低电平。停止条件则反过来SCL保持高电平期间SDA从低电平跳变到高电平。这里要注意如果在SCL高电平期间SDA发生跳变总线上的设备不会认为这是数据而是会把它当作起始或停止信号所以其他数据位的跳变必须安排在SCL低电平期间。数据传输按字节进行每字节8位高位先发。比如要发送0xA0对应的8个bit就是1 0 1 0 0 0 0 0在SCL低电平期间依次把SDA驱动成对应电平SCL高电平期间从机去采样。一个bit占一个SCL周期。第9个SCL周期是ACK位。对于写操作主机在第9个时钟前释放SDA置高阻从机在SCL低电平期间把SDA拉低主机在SCL高电平期间采样到低电平就知道从机收到了。读操作时角色互换从机发数据主机在第9个时钟拉低表示“继续读”拉高表示“我读够了”。2.2 EEPROM的写时序、读时序和写周期tWR对AT24C02做单字节写完整时序是起始条件发送写地址0xA0等待ACK发送要写的字地址比如0x12等待ACK发送数据字节等待ACK停止条件停止条件发出之后EEPROM内部才开始真正执行擦写这个阶段叫写周期时间tWR最大约5ms。在tWR结束前芯片不响应任何命令。如果主机以为stop完就能立刻发下一条大概率会等不到ACK或者读到旧数据。读操作比写操作要绕一环因为I2C协议里没有“读这个地址”这样的单条命令需要先“指路”再“取数”。最常用的随机读时序是起始条件发送写地址0xA0等待ACK发送要读的字地址等待ACK重复起始条件发送读地址0xA1等待ACK读取数据字节发送NACK停止条件第二步到第三步看起来是“写”实际上只是在设置内部地址指针所以叫伪写。真正的数据读取在后面重复起始之后才发生。有的设计图省事伪写结束后直接发停止再重新起始进入读模式。协议上也允许但多了一次总线切换还耽误时间。重复起始的做法更紧凑我推荐直接按手册里的时序走。2.3 页写的边界陷阱AT24C02页大小是8字节一次最多连续写8个字节而且这8个字节必须是同一页内的8个地址。页地址按字地址的低三位划分即0x00~0x07是第0页0x08~0x0F是第1页以此类推。页写最阴险的地方在于地址回卷。如果从0x06开始连续写4个字节EEPROM会在写完0x07后回卷到0x00而不是跑到0x08最终0x00、0x01也被改掉。几乎所有第一次写页写的人都会踩这个坑。所以控制逻辑里要判断剩余待写字节数不能跨越页边界一旦跨页就把一次连续写拆成多次每次最多写到页尾。2.4 时序参数速查表下面这张表是我调试时反复对照的AT24C02在标准模式100kHz下的关键参数参数典型值备注SCL频率100kHz / 400kHz快速模式需要配合合适上拉SCL高电平最小时间4.0us100kHz由主机分频保证SCL低电平最小时间4.7us100kHz由主机分频保证起始条件保持时间4.0us不能在SCL高时早动写周期tWR5ms最大stop后必须等总线空闲时间4.7us连续操作间建议等待这些时间在FPGA实现里只要SCL频率不超过规格一般都会满足。真正要小心的是tWR因为它是毫秒级比I2C数据位的微秒级长得多不是分频器顺手能覆盖的必须单独处理。3. 状态机设计把读写流程拆成“有限步走位”很多第一次写I2C控制器的人容易直接在always块里堆一堆if else最后状态乱成一锅粥。我的经验是一定先把“字节级”和“位级”分开。位级负责在SCL的一个周期内把数据比特移到SDA上字节级负责一个字节一个字节地组织起始、地址、数据、停止这些动作。3.1 两层结构I2C底层驱动 EEPROM操作控制底层I2C驱动模块是纯通用的它不认识EEPROM只负责完成发送一个字节、接收一个字节、产生起始停止、等待ACK这些动作。上层EEPROM控制模块才是状态机主体它根据AT24C02的时序来调度底层驱动。这样做的好处非常明显。项目里以后要挂温度传感器、实时时钟、ADC配置寄存器全都是I2C接口底层驱动直接复用只改上层状态机就可以。如果一开始就把EEPROM协议本文还有配套的精品资源点击获取