flash M25P128读操作
我们本次实验的内容是,对flash读一个字节的数据,系统框图如下:
硬件:锆石A4plus开发板
软件:quartus II 13.1
从技术手册中我们可以得到如下信息:
从上述信息中我们可以得到:
1、一个读指令操作可以读取整个flash的数据。
2、所利用的时序仍为SPI时序
时序图设计
同样我们也对flash的擦除时序进行一定程度的更改如下:
这里的时序图画的稍微乱点,但相信同学们有了前面的基础肯定可以学会。接下来便直接上代码。
flash_read模块的书写
这里的传统不说废话,直接上代码:
`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : [email protected] // Website : // Module Name : flash_read.v // Create Time : 2020-01-09 12:52:26 // Editor : sublime text3, tab size (4) // copyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module flash_read( input sclk , input rst_n , input key_flag , output reg cs_n , output reg sck , output reg sdi , input sdo , output reg [ 7:0] data_out , output reg data_flag ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ parameter READ_INST = 8'h03 ; parameter READ_ADDR = 24'h00_03_21 ; reg [ 4:0] cnt_32 ; reg [ 2:0] cnt_state ; reg [ 1:0] cnt_4 ; reg [ 4:0] bit_cnt ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cs_n <= 1'b1; else if(key_flag == 1'b1) cs_n <= 1'b0; else if(cnt_32 == 'd31 && cnt_state == 'd6) cs_n <= 1'b1; else cs_n <= cs_n; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cnt_32 <= 5'd0; else if(cnt_32 == 'd31) cnt_32 <= 5'd0; else if(cs_n == 1'b0) cnt_32 <= cnt_32 + 1'b1; else cnt_32 <= 5'd0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cnt_state <= 3'd0; else if(cnt_state == 'd6 && cnt_32 == 'd31) cnt_state <= 3'd0; else if(cnt_32 == 'd31) cnt_state <= cnt_state + 1'b1; else cnt_state <= cnt_state; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cnt_4 <= 2'd0; else if(cnt_state >= 'd1 && cnt_state <= 'd5) cnt_4 <= cnt_4 + 1'b1; else cnt_4 <= 2'd0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) sck <= 1'b0; else if(cnt_4 == 'd0) sck <= 1'b0; else if(cnt_4 == 'd2) sck <= 1'b1; else sck <= sck; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) sdi <= 1'b0; else if(cnt_32 == 'd31 && cnt_state == 'd4) sdi <= 1'b0; else if(cnt_4 == 'd0 && cnt_state == 'd1) sdi <= READ_INST[7-bit_cnt]; else if(cnt_4 == 'd0 &&cnt_state >= 3'd2 && cnt_state <= 3'd4) sdi <= READ_ADDR[23-bit_cnt]; else sdi <= sdi; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) bit_cnt <= 5'd0; else if(cnt_32 == 'd30 && cnt_state == 3'd1) bit_cnt <= 5'd0; else if(cnt_32 == 'd30 && cnt_state == 3'd4) bit_cnt <= 5'd0; else if(cnt_4 == 'd2 && cnt_state >= 3'd1 && cnt_state <= 3'd4) bit_cnt <= bit_cnt + 1'b1; else bit_cnt <= bit_cnt; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) data_out <= 8'd0; else if(cnt_4 == 'd2 && cnt_state == 3'd5) data_out <= {data_out[6:0],sdo}; else if(cnt_32 == 'd31 && cnt_state == 'd6) data_out <= 8'd0; else data_out <= data_out; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) data_flag <= 1'b0; else if(cnt_state == 'd5 && cnt_32 == 'd30) data_flag <= 1'b1; else data_flag <= 1'b0; endmodule
@H_404_57@flash_read测试模块的代码
`timescale 1ns / 1ps `define CLOCK 20 // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : [email protected] // Website : // Module Name : flash_earse_tb.v // Create Time : 2020-01-08 19:57:13 // Editor : sublime text3, tab size (4) // copyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module flash_read_tb(); reg sclk ; reg rst_n ; reg key_flag ; wire cs_n ; wire sck ; wire sdi ; wire [ 7:0] data_out ; wire data_flag ; initial begin sclk <= 1'b0; rst_n <= 1'b0; key_flag <= 1'b0; #(100*`CLOCK) rst_n <= 1'b1; #(100*`CLOCK) key_flag <= 1'b1; #(`CLOCK) key_flag <= 1'b0; #(1000*`CLOCK) key_flag <= 1'b1; #(`CLOCK) key_flag <= 1'b0; end always #(`CLOCK/2) sclk <= ~sclk; flash_read flash_read_inst( .sclk (sclk ), .rst_n (rst_n ), .key_flag (key_flag ), .cs_n (cs_n ), .sck (sck ), .sdi (sdi ), .sdo (1'b1 ), .data_out (data_out ), .data_flag (data_flag ) ); endmodule
@H_404_57@其他模块的代码
为了方便同学们可以直接使用该代码,这里我们将所有的代码复制如下,整体的工程也可以进群自取:
key模块代码:`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : [email protected] // Website : // Module Name : key.v // Create Time : 2020-01-05 13:49:36 // Editor : sublime text3, tab size (4) // copyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module key( input sclk , input rst_n , input key , output reg key_o ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ parameter IDLE = 4'b0001 ; parameter S1 = 4'b0010 ; parameter S2 = 4'b0100 ; parameter S3 = 4'b1000 ; reg [ 3:0] state ; reg [ 9:0] cnt ; reg key_r1 ; reg key_r2 ; reg key_r3 ; reg nege_flag ; reg pose_flag ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ always @(posedge sclk) key_r1 <= key; always @(posedge sclk) key_r2 <= key_r1; always @(posedge sclk) key_r3 <= key_r2; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) nege_flag <= 1'b0; else if(key_r3 == 1'b1 && key_r2 == 1'b0) nege_flag <= 1'b1; else nege_flag <= 1'b0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) pose_flag <= 1'b0; else if(key_r3 == 1'b0 && key_r2 == 1'b1) pose_flag <= 1'b1; else pose_flag <= 1'b0; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) state <= IDLE; else case(state) IDLE : if(nege_flag == 1'b1) state <= S1; else state <= IDLE; S1 : if(cnt == 10'd999) state <= S2; else if(pose_flag == 1'b1) state <= IDLE; else state <= S1; S2 : if(pose_flag == 1'b1) state <= S3; else state <= S2; S3 : if(cnt == 10'd999) state <= IDLE; else if(nege_flag == 1'b1) state <= S2; else state <= S3; default : state <= IDLE; endcase always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cnt <= 10'd0; else if(state != S1 && state != S3) cnt <= 10'd0; else cnt <= cnt + 1'b1; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) key_o <= 1'b0; else if(state == S1 && cnt == 10'd999) key_o <= 1'b1; else key_o <= 1'b0; endmodule
@H_404_57@top模块:
`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : [email protected] // Website : // Module Name : top.v // Create Time : 2020-01-08 21:18:52 // Editor : sublime text3, tab size (4) // copyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module top( input sclk , input rst_n , input key , output wire cs_n , output wire sck , output wire sdi , input sdo , output reg [ 7:0] led ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ wire key_flag ; wire [ 7:0] data_out ; wire data_flag ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) led <= 8'd0; else if(data_flag == 1'b1) led <= data_out; else led <= led; key key_inst( .sclk (sclk ), .rst_n (rst_n ), .key (~key ), .key_o (key_flag ) ); flash_read flash_read_inst( .sclk (sclk ), .rst_n (rst_n ), .key_flag (key_flag ), .cs_n (cs_n ), .sck (sck ), .sdi (sdi ), .sdo (sdo ), .data_out (data_out ), .data_flag (data_flag ) ); endmodule
@H_404_57@实验结果
这里的实验结果就是我们把上一篇文章中写入flash的数据读出并且显示再led上面,实验结果证明了我们flash读写操作的正确性。
结束语
创作不易,认为文章有帮助的同学们可以收藏点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。