SPI总线介绍和verilog实现

本文介绍了SPI总线,它是摩托罗拉提出的全双工同步通信接口,仅四根信号线,可节约芯片管脚。阐述了其四根信号线的功能、工作机制,包括数据传输方式、时钟极性和相位设置。还提及该接口无应答机制,最后给出了Verilog实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SPI总线介绍和verilog实现

https://blog.youkuaiyun.com/IamSarah/article/details/76269737

这篇文章讲SPI总线,SPI是serial peripheral interface 的缩写,即串行外围设备接口。该接口是摩托罗拉公司提出的全双工同步通信的接口,该接口只有四根信号线,在芯片的管脚上只占用4根线,节约了芯片的管脚。

这四根信号信如下:

1、MOSI:主器件数据输出,从器件数据输入。

2、MISO:主器件数据输入,从器件数据输出。

3、SCLK:时钟线,有主器件控制。

4、CS:从器件的片选线,由主器件控制。

在点对点的通信当中:无须寻址工作,使用该接口实现全双工通信,高效简单,一个主器件可以连接多个从设备,每个从设备有独立的片选信号。不过该接口有一个缺点,就是没有应答机制。

该接口的工作机制:主设备启动,连接多个从设备,在sdo端输出,si端输入数据,均在sclk的上升沿传输数据,则经过8/16次时钟的改变,就能够完成8/16 bit的数据传输。

一般情况下,对有该接口的时钟会有两方面的设置:一方面是时钟极性,主要是用来规定空闲状态下sclk的值,0代表空闲状态下是低电平,1代表空闲状态下是高电平;另一方面是时钟相位的设置,主要是规定数据是在第一个跳变沿被采样还是第二个跳变沿被采样,0是代表第一个跳变沿,1是代表第二个跳变沿。下面两幅图给出不同相位下,不同极性的传输效果:

相位为0:

相位为1:

以上就是SPI接口的工作原理,下面给出其verilog实现,这里主器件用读命令和写命令来控制数据的输入和输出,并且对于一个字节的数据读和写分别用一个任务实现,如下:

 

module spi(clk,rd,wr,rst,data_in,si,so,sclk,cs,data_out);
parameter bit7=4'd0,bit6=4'd1,bit5=4'd2,bit4=4'd3,bit3=4'd4,bit2=4'd5,bit1=4'd6,bit0=4'd7,bit_end=4'd8;
parameter bit70=4'd0,bit60=4'd1,bit50=4'd2,bit40=4'd3,bit30=4'd4,bit20=4'd5,bit10=4'd6,bit00=4'd7,bit_end0=4'd8;

parameter size=8;
input clk,rst;
input wr,rd;//读写命令
input si;//spi数据输入端
input [size-1:0]data_in;//待发送的数据

output[size-1:0]data_out;//待接收的数据
output sclk;//spi中的时钟
output so;//spi的发送端
output cs;//片选信号

wire [size-1:0]data_out;
reg [size-1:0]dout_buf;
reg FF;
reg sclk;
reg so;
reg cs;


reg [3:0]send_state;//发送状态寄存器
reg [3:0]receive_state;//接收状态寄存器

always@(posedge clk)
begin
if(!rst)
begin
 sclk<=0;
 cs<=1;
 end
else 
begin
 if(rd|wr) 
 begin
 sclk<=~sclk;//当开始读或者写的时候,需要启动时钟
 cs<=0;
 end
 else 
 begin
 sclk=0;
 cs<=1;
 end
end
end


always@(posedge sclk)//发送数据
begin
if(wr)
begin
send_state<=bit7;
send_data;
end
end

always@(posedge sclk)//接收数据
begin
if(rd)
begin
receive_state<=bit70;
FF<=0;
receive_data;
end
end

assign data_out=(FF==1)?dout_buf:8'hz;

task send_data;//发送数据任务
begin
case(send_state)
bit7:
     begin
	 so<=data_in[7];
	 send_state<=bit6;
	 end
bit6:
     begin
	 so<=data_in[6];
	 send_state<=bit5;
	 end
bit5:
     begin
	 so<=data_in[5];
	 send_state<=bit4;
	 end
bit4:
     begin
	 so<=data_in[4];
	 send_state<=bit3;
	 end
bit3:
     begin
	 so<=data_in[3];
	 send_state<=bit2;
	 end
bit2:
     begin
	 so<=data_in[2];
	 send_state<=bit1;
	 end
bit1:
     begin
	 so<=data_in[1];
	 send_state<=bit0;
	 end
bit0:
     begin
	 so<=data_in[0];
	 send_state<=bit_end;
	 end
bit_end:
     begin
	 so=1'bz;
	 send_state<=bit7;
	 end
endcase
end
endtask

task receive_data;
begin
case (receive_state)
bit70:
      begin
	  dout_buf[7]<=si;
	  receive_state<=bit60;
	  end
bit60:
      begin
	  dout_buf[6]<=si;
	  receive_state<=bit50;
	  end
bit50:
      begin
	  dout_buf[5]<=si;
	  receive_state<=bit40;
	  end
bit40:
      begin
	   dout_buf[4]<=si;
	  receive_state<=bit30;
	  end
bit30:
      begin
	  dout_buf[3]<=si;
	  receive_state<=bit20;
	  end
bit20:
      begin
	  dout_buf[2]<=si;
	  receive_state<=bit10;
	  end
bit10:
      begin
	  dout_buf[1]<=si;
	  receive_state<=bit00;
	  end
bit00:
      begin
	  dout_buf[0]<=si;
	  receive_state<=bit_end;
	  FF<=1;
	  end
bit_end0:
      begin
	  dout_buf<=8'hzz;
	  receive_state<=bit70;
	  end
endcase
end
endtask
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值