Verilog HDL SPI通信——写

来源:互联网 时间:1970-01-01

module spi_write(

input clk, //system clock:50M

input rst,

output reg cs, //chip select

output sck, //chip clock:50K

input din, //DO

output reg dout, //DI

input wflag, //write enable

input[7:0] data

);

//general chip clock:50K

/*reg temp;

reg[9:0] count;

[email protected](posedge clk or posedge rst)

if(rst) begin count <= 10'd0; temp <= 1'b0; end

else

begin

count <= count+1'b1;

if(count == 10'd999) begin temp <= 1'b1; count <= 10'd0; end

else if(count == 10'd499) temp <= 1'b0;

end

assign sck = temp;

`define high (count == 10'd999) // 时钟上升沿

`define low (count == 10'd499)*/ // 时钟下降沿

reg temp;

reg[9:0] count;

always@(posedge clk or posedge rst)

if(rst)

begin

count <= 10'd0;

temp <= 1'b0;

end

else if(count >= 10'd500)

begin

count <= 10'd0;

temp <= ~temp;

end

else count <= count+1'b1;

assign sck = temp;

//capture posedge and negedge of sck

reg sck_m;

wire high; // 时钟上升沿

wire low; // 时钟下降沿

always@(posedge clk or posedge rst)

if(rst) sck_m <= 1'b0;

else sck_m <= sck;

assign high = ~sck_m & sck;

assign low = sck_m & ~sck;

//load

reg[7:0] data_medium;

reg[5:0] wstate;

always@(negedge clk or posedge rst)

begin

if(rst)

begin

wstate <= 6'b0;

cs <= 1'b0;

dout <= 1'b0;

end

else

begin

case(wstate)

6'd0: begin

if(wflag)

begin

data_medium <= data;

wstate <= 6'd1;

cs <= 1'b1;

dout <= 1'b0;

end

else

begin

wstate <= 6'd0;

cs <= 1'b0;

dout <= 1'b0;

end

end

6'd1: begin

if(low) begin wstate <= 6'd2; dout <=1'b1; cs <= 1'b1; end // 先执行写使能命令,高位在前,低位在后

else begin wstate <= 6'd1; end //SB=1

end

6'd2: begin

if(low) begin wstate <= 6'd3; dout <=1'b0; cs <= 1'b1; end //OP1=0

else begin wstate <= 6'd2; end

end

6'd3: begin

if(low) begin wstate <= 6'd4; dout <=1'b0; cs <= 1'b1; end //OP0=0

else begin wstate <= 6'd3; end

end

6'd4: begin

if(low) begin wstate <= 6'd5; dout <=1'b1; cs <= 1'b1; end //A6=1

else begin wstate <= 6'd4; end

end

6'd5: begin

if(low) begin wstate <= 6'd6; dout <=1'b1; cs <= 1'b1; end //A5=1

else begin wstate <= 6'd5; end

end

6'd6: begin

if(low) begin wstate <= 6'd7; dout <=1'b1; cs <= 1'b1; end //A4=1

else begin wstate <= 6'd6; end

end

6'd7: begin

if(low) begin wstate <= 6'd8; dout <=1'b1; cs <= 1'b1; end //A3=1

else begin wstate <= 6'd7; end

end

6'd8: begin

if(low) begin wstate <= 6'd9; dout <=1'b1; cs <= 1'b1; end //A2=1

else begin wstate <= 6'd8; end

end

6'd9: begin

if(low) begin wstate <= 6'd10; dout <=1'b1; cs <= 1'b1; end //A1=1

else begin wstate <= 6'd9; end

end

6'd10: begin

if(low) begin wstate <= 6'd11; dout <=1'b1; cs <= 1'b1; end //A0=1

else begin wstate <= 6'd10; end

end

6'd11: begin

if(low) begin wstate <= 6'd12; dout <= 1'b0;cs <= 1'b0; end // 先停一个周期,将CS 拉低,再进行写操作(Address)

else begin wstate <= 6'd11; end

end

6'd12: begin

if(low) begin wstate <= 6'd13; dout <=1'b1; cs <= 1'b1; end //SB=1

else begin wstate <= 6'd12; end

end

6'd13: begin

if(low) begin wstate <= 6'd14; dout <=1'b0; cs <= 1'b1; end //OP1=0

else begin wstate <= 6'd13; end

end

6'd14: begin

if(low) begin wstate <= 6'd15; dout <=1'b1; cs <= 1'b1; end //OP0=1

else begin wstate <= 6'd14; end

end

6'd15: begin

if(low) begin wstate <= 6'd16; dout <=1'b0; cs <= 1'b1; end //A6=0

else begin wstate <= 6'd15; end

end

6'd16: begin

if(low) begin wstate <= 6'd17; dout <=1'b0; cs <= 1'b1; end //A5=0

else begin wstate <= 6'd16; end

end

6'd17: begin

if(low) begin wstate <= 6'd18; dout <=1'b0; cs <= 1'b1; end //A4=0

else begin wstate <= 6'd17; end

end

6'd18: begin

if(low) begin wstate <= 6'd19; dout <=1'b0; cs <= 1'b1; end //A3=0

else begin wstate <= 6'd18; end

end

6'd19: begin

if(low) begin wstate <= 6'd20; dout <=1'b1; cs <= 1'b1; end //A2=1

else begin wstate <= 6'd19; end

end

6'd20: begin

if(low) begin wstate <= 6'd21; dout <=1'b0; cs <= 1'b1; end //A1=0

else begin wstate <= 6'd20; end

end

6'd21: begin

if(low) begin wstate <= 6'd22; dout <=1'b1; cs <= 1'b1; end //A0=1

else begin wstate <= 6'd21; end

end

6'd22: begin

if(low) begin wstate <= 6'd23; dout <=data[7]; cs <= 1'b1; end // 开始写入数据:器件数据在上升沿更新,FPGA要在下降沿写出

else begin wstate <= 6'd22; end // D7

end

6'd23: begin

if(low) begin wstate <= 6'd24; dout <=data[6]; cs <= 1'b1; end //D6

else begin wstate <= 6'd23; end

end

6'd24: begin

if(low) begin wstate <= 6'd25; dout <=data[5]; cs <= 1'b1; end //D5

else begin wstate <= 6'd24; end

end

6'd25: begin

if(low) begin wstate <= 6'd26; dout <=data[4]; cs <= 1'b1; end //D4

else begin wstate <= 6'd25; end

end

6'd26: begin

if(low) begin wstate <= 6'd27; dout <=data[3]; cs <= 1'b1; end //D3

else begin wstate <= 6'd26; end

end

6'd27: begin

if(low) begin wstate <= 6'd28; dout <=data[2]; cs <= 1'b1; end //D2

else begin wstate <= 6'd27; end

end

6'd28: begin

if(low) begin wstate <= 6'd29; dout <=data[1]; cs <= 1'b1; end //D1

else begin wstate <= 6'd28; end

end

6'd29: begin

if(low) begin wstate <= 6'd30; dout <=data[0]; cs <= 1'b1; end //D0

else begin wstate <= 6'd29; end

end

6'd30: begin

if(low) begin wstate <= 6'd31; dout <= 1'b0;cs <= 1'b0; end // 数据写完,停止一个周期,拉低CS

else begin wstate <= 6'd30; end

end

6'd31: begin

if(low) begin wstate <= 6'd32; cs <= 1'b1; end //拉高CS,读DO状态,看其是否忙

else begin wstate <= 6'd31; end

end

6'd32: begin

if(din == 1'b1) begin wstate <= 6'd33; cs <= 1'b0; end //若忙,停在此状态继续检测

else begin wstate <= 6'd32; cs <= 1'b1; end

end

6'd33: begin

if(low) begin wstate <= 6'd34; cs <= 1'b0; end //数据写完,停止一个周期

else begin wstate <= 6'd33; end

end

6'd34: begin

if(low) begin wstate <= 6'd35; dout <= 1'b1; cs <= 1'b1; end //当写操作完成后,为了保护数据,对器件进行擦/写禁止指令

else begin wstate <= 6'd34; end

end

6'd34: begin

if(low) begin wstate <= 6'd35; dout <= 1'b0; cs <= 1'b1; end //OP=1

else begin wstate <= 6'd34; end

end

6'd35: begin

if(low) begin wstate <= 6'd36; dout <= 1'b0; cs <= 1'b1; end //OP=2

else begin wstate <= 6'd35; end

end

6'd36: begin

if(low) begin wstate <= 6'd37; dout <= 1'b0; cs <= 1'b1; end //A6

else begin wstate <= 6'd36; end

end

6'd37: begin

if(low) begin wstate <= 6'd38; dout <= 1'b0; cs <= 1'b1; end //A5

else begin wstate <= 6'd37; end

end

6'd38: begin

if(low) begin wstate <= 6'd39; dout <= 1'b1; cs <= 1'b1; end //A4

else begin wstate <= 6'd38; end

end

6'd39: begin

if(low) begin wstate <= 6'd40; dout <= 1'b1; cs <= 1'b1; end //A3

else begin wstate <= 6'd39; end

end

6'd40: begin

if(low) begin wstate <= 6'd41; dout <= 1'b1; cs <= 1'b1; end //A2

else begin wstate <= 6'd40; end

end

6'd41: begin

if(low) begin wstate <= 6'd42; dout <= 1'b1; cs <= 1'b1; end //A1

else begin wstate <= 6'd41; end

end

6'd42: begin

if(low) begin wstate <= 6'd43; dout <= 1'b1; cs <= 1'b1; end //A0

else begin wstate <= 6'd42; end

end

6'd43: begin

if(low) begin wstate <= 6'd44; dout <= 1'b0; end //over

else begin wstate <= 6'd43; end

end

6'd44: begin

if(low) begin wstate <= 6'd0; cs <= 1'b0; end //cs down

else begin wstate <= 6'd44; end

end

endcase

end

end

endmodule

 


相关阅读:
Top