
module
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
你好:
MISO=1;是吧MISO这个脚置为输入。
byte |= MISO; 是吧byte的最低位或上MISO接收到的电平数据。
这是吧byte的最低位赋值,但是上边有一句byte = (byte << 1);这样吧byte左移一位,下次再赋值时,byte的最低位就是新的一个数据了。
不懂的回复。
希望我的回答能帮助到你。
STC89C52RC单片机是没有硬件SPI功能的,是需要模拟的。普通的I/O即可模拟的。给你一个参考程序:\x0d\//-----------------------函数声明,变量定义-------------------------------------------------------- \x0d\#include \x0d\#include \x0d\sbit SCK=P1^0; // 将p10口模拟时钟输出 \x0d\sbit MOSI=P1^1; // 将p11口模拟主机输出 \x0d\sbit MISO=P1^2; // 将p11口模拟主机输入 \x0d\sbit SS1=P1^3; // 将p11口模拟片选 \x0d\#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; \x0d\//-------------------------------------------------------------------------------------------------- \x0d\// 函数名称: SPISendByte \x0d\// 入口参数: ch \x0d\// 函数功能: 发送一个字节 \x0d\//-------------------------------------------------------------------------------------------------- \x0d\void SPISendByte(unsigned char ch) \x0d\{ \x0d\unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位 \x0d\SCK = 1 ; //时钟置高 \x0d\SS1 = 0 ; //选择从机 \x0d\while(n--) \x0d\{ \x0d\delayNOP(); \x0d\SCK = 0 ; //时钟置低 \x0d\if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1 \x0d\{ \x0d\MOSI = 1; // 传送位1 \x0d\} \x0d\else\x0d\{ \x0d\MOSI = 0; // 否则传送位0 \x0d\} \x0d\delayNOP(); \x0d\ch = ch回答于 2022-11-17
可以的,但SPI接口的器件有多种工作方式,如高位在前还是低位在前,空闲时时钟线高电平还是低电平
第一个跳变沿还是第二个跳变沿数据有效,程序是不同的,下面程序供参考
sbit CLK=P2^2;
sbit MOSI=P2^3; //发送方方管脚配置
sbit MISO=P2^4;
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;//
void Write(uchar byte)//写数据
{
uchar i;
ACC=byte;
i=8;
while(i)
{
MOSI=BIT7;
CLK=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_(); // shift next bit into MSB
_nop_();
_nop_();
ACC<<=1;
CLK=0; // Set SCK high
i--; // then set SCK low again
_nop_();
}
}
/
/函数:Read(uchar reg)
/功能:NRF24L01的读时序
//
uchar Read(void)
{
uchar i;
i=8;
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;
while(i)
{
CLK=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_();
_nop_();
_nop_(); // shift next bit into MSB
ACC<<=1;
BIT0=MISO ;
CLK=0; // Set SCK high
i--; // then set SCK low again
_nop_();
//led1=~led1;
}
return ACC; // return register value
}
传送的参数为什么要用void型啊?address用uint32_t不行么?data用uint8_t不行么?
还有,在写入或读出数据的时候别干多余的事情,把sprintf和lcd_print删掉。
以上就是关于spi接口的Verilog程序全部的内容,包括:spi接口的Verilog程序、nrf24l01的GPIO的模拟SPI,程序MISO=1; byte |= MISO;这里是个什么意思。、stc89c52rc单片机具有硬件SPI功能吗不具有的话如何模拟spi等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)