spi_mosi(rst,clk,rd,wr,datain,
spics,spiclk,spido,spidi,dataout)
input
rst
//置位信号,低有效
input
clk
//时钟信号
input
rd
//接收数据命令
input
wr
//发送数据命令
input
spidi
//SPI数据输入信号
input
[7:0]
datain
//发送数据输入
output
spics
//SPI片选信号
output
spiclk
//SPI时钟信号
output
spido
//SPI数据输出信号
output
[7:0]
dataout
//接收数据输出
reg
spics
reg
spiclk
reg
spido
reg
[7:0]
dstate,
dsend,dataout,dreceive
//,cnt
reg
[1:0]
spistate
parameter
idle
=
2'b00
parameter
send_data
=
2'b01
parameter
receive_data
=
2'b10
initial
begin
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
end
always
@(posedge
clk)
begin
if(!rst)
begin
spistate
<=
idle
//
cnt
<=
8'd0
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd0
end
else
begin
case
(spistate)
2'b00:
begin
//
spics
<=
1'b1
//
spiclk
<=
1'b1
//
spido
<=
1'b1
//
if(cnt
==
8'd0)
//
begin
//
cnt
<=
8'd0
if((wr
==
1'b0)
&&
(rd
==
1'b1))
//发送资料转换
begin
spistate
<=
send_data
dstate
<=
8'd0
dsend
<=
datain
end
else
if((wr
==
1'b1)
&&
(rd
==
1'b0))
//接收数据转换
begin
spistate
<=
receive_data
dstate
<=
8'd0
end
else
begin
spistate
<=
idle
dstate
<=
8'd0
end
//
end
//
else
//
begin
//
cnt
<=
cnt
+
8'd1
//
end
end
2'b01:
//发送数据状态
begin
case
(dstate)
8'd0:
//产生片选信号有效
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd1
end
8'd1:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'洞乎d2
end
8'd2:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
1'b1
dstate
<=
8'd3
end
8'd3:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
dsend[7]
//发送数据最高位
dstate
<=
8'd4
end
8'd4:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[7]
dstate
<=
8'd5
end
8'd5:
begin
spics
<=
1'b0
spiclk
<正颤粗=
1'b1
spido
<=
dsend[6]
dstate
<=
8'd6
end
8'd6:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[6]
dstate
<=
8'd7
end
8'd7:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
dsend[5]
dstate
<=
8'd8
end
8'd8:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[5]
dstate
<=
8'd9
end
8'd9:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
dsend[4]
dstate
<=
8'd10
end
8'd10:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[4]
dstate
<=
8'd11
end
8'd11:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
dsend[3]
dstate
<=
8'd12
end
8'd12:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[3]
dstate
<=
8'd13
end
8'd13:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<举镇=
dsend[2]
dstate
<=
8'd14
end
8'd14:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[2]
dstate
<=
8'd15
end
8'd15:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
dsend[1]
dstate
<=
8'd16
end
8'd16:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[1]
dstate
<=
8'd17
end
8'd17:
begin
spics
<=
1'b0
spiclk
<=
1'b1
//发送最低位数据
spido
<=
dsend[0]
dstate
<=
8'd18
end
8'd18:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
dsend[0]
//spiclk的下降沿让最低位数据被读取
dstate
<=
8'd19
end
8'd19:
//置片选信号无效
begin
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd20
end
8'd20:
begin
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd0
spistate
<=
idle
end
default
begin
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
spistate
<=
idle
end
endcase
end
2'b10:
//接收数据状态
begin
case
(dstate)
//片选信号有效
8'd0:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd1
end
8'd1:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd2
end
8'd2:
begin
spics
<=
1'b0
spiclk
<=
1'b0
spido
<=
1'b1
dstate
<=
8'd3
end
8'd3:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd4
end
8'd4:
begin
spics
<=
1'b0
spiclk
<=
1'b0
//紧接着上升沿的下降沿数据被读取
dreceive[7]
<=
spidi
//接收数据最高位
dstate
<=
8'd5
end
8'd5:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd6
end
8'd6:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[6]
<=
spidi
dstate
<=
8'd7
end
8'd7:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd8
end
8'd8:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[5]
<=
spidi
dstate
<=
8'd9
end
8'd9:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd10
end
8'd10:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[4]
<=
spidi
dstate
<=
8'd11
end
8'd11:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd12
end
8'd12:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[3]
<=
spidi
dstate
<=
8'd13
end
8'd13:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd14
end
8'd14:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[2]
<=
spidi
dstate
<=
8'd15
end
8'd15:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd16
end
8'd16:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[1]
<=
spidi
dstate
<=
8'd17
end
8'd17:
begin
spics
<=
1'b0
spiclk
<=
1'b1
dstate
<=
8'd18
end
8'd18:
begin
spics
<=
1'b0
spiclk
<=
1'b0
dreceive[0]
<=
spidi
//接收数据最低位
dstate
<=
8'd19
end
8'd19:
begin
spics
<=
1'b0
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd20
dataout<=
dreceive
end
8'd20:
begin
spics
<=
1'b1
//片选信号无效
spiclk
<=
1'b1
spido
<=
1'b1
dstate
<=
8'd0
spistate
<=
idle
end
endcase
end
default:
begin
spics
<=
1'b1
spiclk
<=
1'b1
spido
<=
1'b1
spistate
<=
idle
end
endcase
//对应上面的发送数据情形
end
//对应上面的RST没有按下的情形
end
//对应最上面的always@(posedge
clk)
endmodule
最近在调试spi flash的擦饥祥写,问题是flash擦写uboot时,不成功。原来的uboot丢失。测试发现是因为擦能成功,但是写时的地址不是secent大小,一个secent大小为64K.看datasheet上说,擦的长度可以是page,secent或block,即4K,32K,64K.我就用4K来擦除,但是不行。还是一样。之后在网上看了看,貌似听说4K擦除的flash很少。我用的是mxic的flash。就改为64K擦除。出现只能写一次,第二次写就会失败。 原因一直不明白。最后也不知道动了什么地方造成其好了。动的地方为: 改spi mode3为mode0. 改spi clk从1M到2M.最大支持50M 改bootload的引导,从0x8400到0x10000. 改擦写大小为0x80000。 写了五六次,没啥事。 什么原因也懒的查了。 应该是flash未写数据时,可以写数据,但写了烂扰搏数据之后,一定要先擦除再写数据才行。应李镇该是这个原因造成只能擦一次。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)