
没说是什么问题!
1HC595输出不对头?解决办法:选择了某位八段,要要延迟一段时间,大约1us这样的,以便保证SPI输出的数据的前沿在SPI_CS之后。另外一个产生错误的可能是“不断检测SPI_READY位”!建议不要接着检测,而是估计发送一个字节所花的时间,再考虑一个延迟。例如,发送一个字节为10us,则检测之前先延迟6us左右,再检测SPI_READY标志,不影响你的发送速率。这样做的原因是很多SPI核设计不是很好,还有可能是ARM7的IO速率与指令速率匹配。一个IO_R/W周期很长,而一个指令周期很短;
2位码不对解决办法:严格检查PORT_DIR,保证引脚配置正确。
--------
长时间不鼓捣这东西了,具体还得请你自己细致测验。
1定义三个gpio: p0-sclk, p1-sdi, p2-sdo;p0用于模拟spi的clock,p1用于接收数据,p2用于f发送数据;硬件上单片机A的p0接单片机B的p0,A的p1接B的p2,A的p2接B的p12发送程序:clock拉低,sdo输出0或1(数据),延时一定时间,clock拉高,延时一定时间,这样A就发送一位数据到B,循环8次就发送一个字节数据3接收程序:检测clock状态,如果为低,就读取sdi,直到clock拉高,结束该次输入,重复8次,读取一个字节注意:1。clock空闲状态为高,发送数据就拉低;2还需要加入起始停止同步协议,可根据需要进行完善
void SpiWriteRegister (uchar reg, uchar value)
{
RF_NSEL = 0; // 片选拉低启动SPI通讯
SPI0DAT = (reg|0x80); // 写入1个字节的寄存器地址
while( SPIF == 0); // 等待SPI传输完成
SPIF = 0;
SPI0DAT = value; // 继续写入第二个字节(寄存器值)
while( SPIF == 0); // 等待SPI传输完成
SPIF = 0;
RF_NSEL = 1; // 片选拉高结束SPI通讯
}
//-----------------------------------------------------------------------------
//函数描述: SPI读取函数
//相关参数:
//返回信息:
//
//-----------------------------------------------------------------------------
uchar SpiReadRegister (uchar reg)
{
RF_NSEL = 0; // 片选拉低启动SPI通讯
SPI0DAT = reg; // 写入1个字节的寄存器地址
while( SPIF == 0); // 等待SPI传输完成
SPIF = 0;
SPI0DAT = 0xFF; // 写一个Dummy字节(因为要读取的话必须用写入来启动一个交换数据的传输),当写入完成后从机的数据也完成了读入。
while( SPIF == 0); // 等待SPI传输完成
SPIF = 0;
RF_NSEL = 1; // 片选拉高结束SPI通讯
return SPI0DAT; // 返回读取的值(在SPI0DAT=0xFF中完成读取)
}
需要注意的是读写 *** 作实际上完成的都是数据的交换,即主机传送1个字节给从机,从机同时传送1个字节给主机。所以读 *** 作看起来像是写数据,但实际上写入完成后就可以从SPI0DAT中获得从机的应答数据了。
可以的,但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
}
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
以上就是关于照着书上写的一个spi控制595的程序,为什么有问题呢哪位高手能指点一下呢全部的内容,包括:照着书上写的一个spi控制595的程序,为什么有问题呢哪位高手能指点一下呢、求两个51单片机模拟SPI通信程序,主机和从机的程序!!、帮忙分析一个这个spi读写程序,详细一点的,解释一下。怎么觉得读和写的内容怎么差不多呢,怎么实现的读写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)