PP指令
pp是页编程指令:需要先打开写使能(0000_0110),发送PP指令号(0000_0010),后面给24位地址,然后接数据,时序图发送如下图所示。
PP指令时序代码
//页编程(PP)指令:打开写使能,给PP命令,给24位地址,后面接数据
module flash_pp (
input wire clk,
input wire rst_n,
output reg flash_cs_n,
output reg flash_scl,
output reg flash_d,
input wire flash_q,
output reg q
);
localparam WREN = 8'h06;
localparam PP = 8'h02;
localparam T_half = 5;
localparam ADDR = 24'h123456;
always @ (posedge clk) q <= flash_q;
reg [9:0] cnt;
always @ (posedge clk) begin
if (rst_n == 0)
cnt <= 0;
else if (cnt == 501)
cnt <= cnt;
else
cnt <= cnt + 1'b1;
end
always @ (*) begin
if (rst_n == 0) begin flash_cs_n = 1;flash_scl = 0;flash_d = 0;end
else
case (cnt)
0 : begin flash_cs_n = 1;flash_scl = 0;flash_d = 0;end
1 : begin flash_cs_n = 0;flash_d = WREN[7];end
1 + T_half * 1 : begin flash_scl = 1;end
1 + T_half * 2 : begin flash_scl = 0;flash_d = WREN[6];end
1 + T_half * 3 : begin flash_scl = 1;end
1 + T_half * 4 : begin flash_scl = 0;flash_d = WREN[5];end
1 + T_half * 5 : begin flash_scl = 1;end
1 + T_half * 6 : begin flash_scl = 0;flash_d = WREN[4];end
1 + T_half * 7 : begin flash_scl = 1;end
1 + T_half * 8 : begin flash_scl = 0;flash_d = WREN[3];end
1 + T_half * 9 : begin flash_scl = 1;end
1 + T_half * 10 : begin flash_scl = 0;flash_d = WREN[2];end
1 + T_half * 11 : begin flash_scl = 1;end
1 + T_half * 12 : begin flash_scl = 0;flash_d = WREN[1];end
1 + T_half * 13 : begin flash_scl = 1;end
1 + T_half * 14 : begin flash_scl = 0;flash_d = WREN[0];end
1 + T_half * 15 : begin flash_scl = 1;end
1 + T_half * 16 : begin flash_scl = 0;flash_cs_n = 1;end//写使能打开,正好是8个scl
1 + T_half * 17 : begin flash_scl = 1;end
1 + T_half * 18 : begin flash_scl = 0;end
1 + T_half * 19 : begin flash_scl = 1;end
1 + T_half * 20 : begin flash_scl = 0;flash_d = PP[7];flash_cs_n = 0;end
1 + T_half * 21 : begin flash_scl = 1;end
1 + T_half * 22 : begin flash_scl = 0;flash_d = PP[6];end
1 + T_half * 23 : begin flash_scl = 1;end
1 + T_half * 24 : begin flash_scl = 0;flash_d = PP[5];end
1 + T_half * 25 : begin flash_scl = 1;end
1 + T_half * 26 : begin flash_scl = 0;flash_d = PP[4];end
1 + T_half * 27 : begin flash_scl = 1;end
1 + T_half * 28 : begin flash_scl = 0;flash_d = PP[3];end
1 + T_half * 29 : begin flash_scl = 1;end
1 + T_half * 30 : begin flash_scl = 0;flash_d = PP[2];end
1 + T_half * 31 : begin flash_scl = 1;end
1 + T_half * 32 : begin flash_scl = 0;flash_d = PP[1];end
1 + T_half * 33 : begin flash_scl = 1;end
1 + T_half * 34 : begin flash_scl = 0;flash_d = PP[0];end
1 + T_half * 35 : begin flash_scl = 1;end
1 + T_half * 36 : begin flash_scl = 0;flash_d = ADDR[23];end //addr23
1 + T_half * 37 : begin flash_scl = 1;end
1 + T_half * 38 : begin flash_scl = 0;flash_d = ADDR[22];end //addr22
1 + T_half * 39 : begin flash_scl = 1;end
1 + T_half * 40 : begin flash_scl = 0;flash_d = ADDR[21];end //addr21
1 + T_half * 41 : begin flash_scl = 1;end
1 + T_half * 42 : begin flash_scl = 0;flash_d = ADDR[20];end //addr20
1 + T_half * 43 : begin flash_scl = 1;end
1 + T_half * 44 : begin flash_scl = 0;flash_d = ADDR[19];end //addr19
1 + T_half * 45 : begin flash_scl = 1;end
1 + T_half * 46 : begin flash_scl = 0;flash_d = ADDR[18];end //addr18
1 + T_half * 47 : begin flash_scl = 1;end
1 + T_half * 48 : begin flash_scl = 0;flash_d = ADDR[17];end //addr17
1 + T_half * 49 : begin flash_scl = 1;end
1 + T_half * 50 : begin flash_scl = 0;flash_d = ADDR[16];end //addr16
1 + T_half * 51 : begin flash_scl = 1;end
1 + T_half * 52 : begin flash_scl = 0;flash_d = ADDR[15];end //addr15
1 + T_half * 53 : begin flash_scl = 1;end
1 + T_half * 54 : begin flash_scl = 0;flash_d = ADDR[14];end //addr14
1 + T_half * 55 : begin flash_scl = 1;end
1 + T_half * 56 : begin flash_scl = 0;flash_d = ADDR[13];end //addr13
1 + T_half * 57 : begin flash_scl = 1;end
1 + T_half * 58 : begin flash_scl = 0;flash_d = ADDR[12];end //addr12
1 + T_half * 59 : begin flash_scl = 1;end
1 + T_half * 60 : begin flash_scl = 0;flash_d = ADDR[11];end //addr11
1 + T_half * 61 : begin flash_scl = 1;end
1 + T_half * 62 : begin flash_scl = 0;flash_d = ADDR[10];end //addr10
1 + T_half * 63 : begin flash_scl = 1;end
1 + T_half * 64 : begin flash_scl = 0;flash_d = ADDR[9];end //addr9
1 + T_half * 65 : begin flash_scl = 1;end
1 + T_half * 66 : begin flash_scl = 0;flash_d = ADDR[8];end //addr8
1 + T_half * 67 : begin flash_scl = 1;end
1 + T_half * 68 : begin flash_scl = 0;flash_d = ADDR[7];end //addr7
1 + T_half * 69 : begin flash_scl = 1;end
1 + T_half * 70 : begin flash_scl = 0;flash_d = ADDR[6];end //addr6
1 + T_half * 71 : begin flash_scl = 1;end
1 + T_half * 72 : begin flash_scl = 0;flash_d = ADDR[5];end //addr5
1 + T_half * 73 : begin flash_scl = 1;end
1 + T_half * 74 : begin flash_scl = 0;flash_d = ADDR[4];end //addr4
1 + T_half * 75 : begin flash_scl = 1;end
1 + T_half * 76 : begin flash_scl = 0;flash_d = ADDR[3];end //addr3
1 + T_half * 77 : begin flash_scl = 1;end
1 + T_half * 78 : begin flash_scl = 0;flash_d = ADDR[2];end //addr2
1 + T_half * 79 : begin flash_scl = 1;end
1 + T_half * 80 : begin flash_scl = 0;flash_d = ADDR[1];end //addr1
1 + T_half * 81 : begin flash_scl = 1;end
1 + T_half * 82 : begin flash_scl = 0;flash_d = ADDR[0];end //addr0
1 + T_half * 83 : begin flash_scl = 1;end
1 + T_half * 84 : begin flash_scl = 0;flash_d = 1;end //byte[0]
1 + T_half * 85 : begin flash_scl = 1;end
1 + T_half * 86 : begin flash_scl = 0;flash_d = 0;end //byte1[1]
1 + T_half * 87 : begin flash_scl = 1;end
1 + T_half * 88 : begin flash_scl = 0;flash_d = 1;end //byte1[2]
1 + T_half * 89 : begin flash_scl = 1;end
1 + T_half * 90 : begin flash_scl = 0;flash_d = 1;end //byte1[3]
1 + T_half * 91 : begin flash_scl = 1;end
1 + T_half * 92 : begin flash_scl = 0;flash_d = 0;end //byte1[4]
1 + T_half * 93 : begin flash_scl = 1;end
1 + T_half * 94 : begin flash_scl = 0;flash_d = 0;end //byte1[5]
1 + T_half * 95 : begin flash_scl = 1;end
1 + T_half * 96 : begin flash_scl = 0;flash_d = 1;end //byte1[6]
1 + T_half * 97 : begin flash_scl = 1;end
1 + T_half * 98 : begin flash_scl = 0;flash_d = 0;end //byte1[7] 正常pp指令后面可以接256byte,这里只写了1byte
1 + T_half * 99 : begin flash_scl = 1;end
1 + T_half * 100 : begin flash_scl = 0;flash_cs_n = 1;end //cs_n拉高
default : ;
endcase
end
endmodule
PP指令仿真代码
`timescale 1ns/1ps
module flash_pp_tb;
reg clk;
reg rst_n;
wire flash_cs_n;
wire flash_scl;
wire flash_d;
wire flash_q;
wire q;
flash_pp flash_pp_inst(
.clk (clk),
.rst_n (rst_n),
.flash_cs_n (flash_cs_n),
.flash_scl (flash_scl),
.flash_d (flash_d),
.flash_q (flash_q),
.q (q)
);
m25p16 m25p16_inst(
.c (flash_scl),
.data_in (flash_d),
.s (flash_cs_n),
.w (1'b1),
.hold (1'b1),
.data_out (flash_q)
);
initial clk = 1;
always # 10 clk = ~clk;
initial begin
rst_n = 0;
#201
rst_n = 1;
repeat (500)
@ (posedge clk);
#200
$stop;
end
endmodule
PP指令仿真图
完整工程:https://download.csdn.net/download/weixin_42263208/12890377
M25P16仿真模型文件:https://download.csdn.net/download/weixin_42263208/12889963