EEPROM读写 |
您所在的位置:网站首页 › eeprom如何擦除和写入 › EEPROM读写 |
文章目录
1. EEPROM简介2. IIC通信协议2.1 AT24C64单次写时序2.2 AT24C64当前地址读时序2.3 AT24C64随机地址读时序
3. 程序设计
1. EEPROM简介
EEPROM即电可擦除可编程只读存储器,是一种常用的非易失性存储器(掉电后,数据不丢失)。AT24C64内部分成256页,一页32个字节,总容量是8K(64K/8)个字节。接口:IIC IIC(I2C,Inter-Integrated Circuit)即集成电路总线,是一种两线式串行总线,由PHLIPS公司开发用于连接微控制器及其外围设备。多用于主机和从机在数据量不大且传输距离短的场合下的主从通信。 I2C总线由数据线SDA和时钟线SCL构成通信线路,既可用于发送数据,也可接收数据。IIC是半双工通信方式。 1、空闲状态 I2C总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。 2、起始信号与停止信号 起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。 停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。 写操作的时候,要先确定写的地址,所以要写器件地址->写地址->写data 地址是8192位,即0~8191,共需要13位二进制表示 读操作的时候,先要确定读的地址,所以:写模式->读写的地址->读模式->读数据 通过FPGA从EEPROM(AT24C64)的存储器地址0至存储器地址255分别写入数据0~255;写完之后再开始读取存储器地址0-255中的数据,若读取的值正确则LED灯常亮,否则LED等闪烁。 系统框图 代码 module e2prom_top( input sys_clk , //系统时钟 input sys_rst_n , //系统复位 //eeprom interface output iic_scl , //eeprom的时钟线scl inout iic_sda , //eeprom的数据线sda //user interface output led //led显示 ); //parameter define parameter SLAVE_ADDR = 7'b1010000 ; //器件地址(SLAVE_ADDR) parameter BIT_CTRL = 1'b1 ; //字地址位控制参数(16b/8b) parameter CLK_FREQ = 26'd50_000_000; //i2c_dri模块的驱动时钟频率(CLK_FREQ) parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率 parameter L_TIME = 17'd125_000 ; //led闪烁时间参数 //wire define wire dri_clk ; //I2C操作时钟 wire i2c_exec ; //I2C触发控制 wire [15:0] i2c_addr ; //I2C操作地址 wire [ 7:0] i2c_data_w; //I2C写入的数据 wire i2c_done ; //I2C操作结束标志 wire i2c_ack ; //I2C应答标志 0:应答 1:未应答 wire i2c_rh_wl ; //I2C读写控制 wire [ 7:0] i2c_data_r; //I2C读出的数据 wire rw_done ; //E2PROM读写测试完成 wire rw_result ; //E2PROM读写测试结果 0:失败 1:成功 //***************************************************** //** main code //***************************************************** //e2prom读写测试模块 e2prom_rw u_e2prom_rw( .clk (dri_clk ), //时钟信号 .rst_n (sys_rst_n ), //复位信号 //i2c interface .i2c_exec (i2c_exec ), //I2C触发执行信号 .i2c_rh_wl (i2c_rh_wl ), //I2C读写控制信号 .i2c_addr (i2c_addr ), //I2C器件内地址 .i2c_data_w (i2c_data_w), //I2C要写的数据 .i2c_data_r (i2c_data_r), //I2C读出的数据 .i2c_done (i2c_done ), //I2C一次操作完成 .i2c_ack (i2c_ack ), //I2C应答标志 //user interface .rw_done (rw_done ), //E2PROM读写测试完成 .rw_result (rw_result ) //E2PROM读写测试结果 0:失败 1:成功 ); //i2c驱动模块 i2c_dri #( .SLAVE_ADDR (SLAVE_ADDR), //EEPROM从机地址 .CLK_FREQ (CLK_FREQ ), //模块输入的时钟频率 .I2C_FREQ (I2C_FREQ ) //IIC_SCL的时钟频率 ) u_i2c_dri( .clk (sys_clk ), .rst_n (sys_rst_n ), //i2c interface .i2c_exec (i2c_exec ), //I2C触发执行信号 .bit_ctrl (BIT_CTRL ), //器件地址位控制(16b/8b) .i2c_rh_wl (i2c_rh_wl ), //I2C读写控制信号 .i2c_addr (i2c_addr ), //I2C器件内地址 .i2c_data_w (i2c_data_w), //I2C要写的数据 .i2c_data_r (i2c_data_r), //I2C读出的数据 .i2c_done (i2c_done ), //I2C一次操作完成 .i2c_ack (i2c_ack ), //I2C应答标志 .scl (iic_scl ), //I2C的SCL时钟信号 .sda (iic_sda ), //I2C的SDA信号 //user interface .dri_clk (dri_clk ) //I2C操作时钟 ); //led指示模块 led_alarm #(.L_TIME(L_TIME ) //控制led闪烁时间 ) u_led_alarm( .clk (dri_clk ), .rst_n (sys_rst_n ), .rw_done (rw_done ), .rw_result (rw_result ), .led (led ) ); endmodule module i2c_dri #( parameter SLAVE_ADDR = 7'b1010000 , //EEPROM从机地址 parameter CLK_FREQ = 26'd50_000_000, //模块输入的时钟频率 parameter I2C_FREQ = 18'd250_000 //IIC_SCL的时钟频率 ) ( input clk , input rst_n , //i2c interface input i2c_exec , //I2C触发执行信号 input bit_ctrl , //字地址位控制(16b/8b) input i2c_rh_wl , //I2C读写控制信号 input [15:0] i2c_addr , //I2C器件内地址 input [ 7:0] i2c_data_w , //I2C要写的数据 output reg [ 7:0] i2c_data_r , //I2C读出的数据 output reg i2c_done , //I2C一次操作完成 output reg i2c_ack , //I2C应答标志 0:应答 1:未应答 output reg scl , //I2C的SCL时钟信号 inout sda , //I2C的SDA信号 //user interface output reg dri_clk //驱动I2C操作的驱动时钟 ); //localparam define localparam st_idle = 8'b0000_0001; //空闲状态 localparam st_sladdr = 8'b0000_0010; //发送器件地址(slave address) localparam st_addr16 = 8'b0000_0100; //发送16位字地址 localparam st_addr8 = 8'b0000_1000; //发送8位字地址 localparam st_data_wr = 8'b0001_0000; //写数据(8 bit) localparam st_addr_rd = 8'b0010_0000; //发送器件地址读 localparam st_data_rd = 8'b0100_0000; //读数据(8 bit) localparam st_stop = 8'b1000_0000; //结束I2C操作 //reg define reg sda_dir ; //I2C数据(SDA)方向控制 reg sda_out ; //SDA输出信号 reg st_done ; //状态结束 reg wr_flag ; //写标志 reg [ 6:0] cnt ; //计数 reg [ 7:0] cur_state ; //状态机当前状态 reg [ 7:0] next_state; //状态机下一状态 reg [15:0] addr_t ; //地址 reg [ 7:0] data_r ; //读取的数据 reg [ 7:0] data_wr_t ; //I2C需写的数据的临时寄存 reg [ 9:0] clk_cnt ; //分频时钟计数 //wire define wire sda_in ; //SDA输入信号 wire [8:0] clk_divide ; //模块驱动时钟的分频系数 //***************************************************** //** main code //***************************************************** //SDA控制 assign sda = sda_dir ? sda_out : 1'bz; //SDA数据输出或高阻 assign sda_in = sda ; //SDA数据输入 assign clk_divide = (CLK_FREQ/I2C_FREQ) >> 2'd2;//模块驱动时钟的分频系数 //生成I2C的SCL的四倍频率的驱动时钟用于驱动i2c的操作 always @(posedge clk or negedge rst_n) begin if(!rst_n) begin dri_clk |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |