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
这是我复制的,一搜一大堆轮裂#include <reg52.h>
sbit SPI_DI =P0^1//MMC数据输入
sbit SPI_DO =P0^0//MMC数据输出,可不接
sbit SPI_SCL=P0^2//时钟线
void Write_Byte(unsigned char value)
{
unsigned char i
for (i=0i<8i++)
{
if (((value>>(7-i))&0x01)==0x01)
SPI_DI=1
else SPI_DI=0
SPI_SCL=0
delay(5)
/念桐缓/必须要加延时,否则会因为 *** 作太快而不响应。
SPI_SCL=1
delay(5)
//必须要加延时,否则会因为仔模 *** 作太快而不响应。
}
}
unsigned char Read_Byte()
{
unsigned char temp=0
unsigned char i
for (i=0i<8i++)
{
SPI_DO=1
SPI_SCL=0
delay(5)
temp=(temp<<1)+(unsigned char)SPI_DO
SPI_SCL=1
delay(5)
}
return (temp)
}
void SPI_Config(void){
GPIO_InitTypeDef GPIO_InitStructure
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL
GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_7)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN
GPIO_SetBits(GPIOA,GPIO_Pin_6)
}
void SPI_ByteWr(unsigned char WrData) //spi 写
{
unsigned char i
GPIO_ResetBits(GPIOA,GPIO_Pin_4)
Delay(2)
GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5)
for(i=0i<8i++)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5)
Delay(2)
if((WrData&0x80) == 0x80)
GPIO_SetBits(GPIOA,GPIO_Pin_7)
else
GPIO_ResetBits(GPIOA,GPIO_Pin_7)
WrData <<= 1
GPIO_SetBits(GPIOA,GPIO_Pin_5)
Delay(2)
}
}
unsigned char SPI_ByteRd(void)//读取一个字节
{
unsigned char i
unsigned char RdData = 0
for(i=0i<8i++)
{
RdData <<= 1
GPIO_ResetBits(GPIOA,GPIO_Pin_5)
Delay(2)
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))
RdData|=1
GPIO_SetBits(GPIOA,GPIO_Pin_5)
Delay(2)
}
return RdData
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)