照着书上写的一个spi控制595的程序,为什么有问题呢哪位高手能指点一下呢

照着书上写的一个spi控制595的程序,为什么有问题呢哪位高手能指点一下呢,第1张

没说是什么问题!

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读写程序,详细一点的,解释一下。怎么觉得读和写的内容怎么差不多呢,怎么实现的读写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10136381.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存