常用串行总线——SPI协议(下)

电子说

1.3w人已加入

描述

2. 从模块(SPI_slave):

module spi_slave(

input           rst_n,

input           cs_n,

input           sclk,

input           mosi,



output          miso,

output [7:0]    reg0_out,

output [7:0]    reg1_out,

output [7:0]    reg2_out,

output [7:0]    reg3_out

);

reg miso_r;

reg [7:0] reg1_out_r;

reg [7:0] reg2_out_r;

reg [7:0] reg3_out_r;

reg [7:0] reg0_out_r;

reg start;

reg wr_rd;

reg [3:0] bit_cnt;

reg [6:0] reg_addr;

reg [7:0] reg_data;

parameter reg0_address = 7'b0000000; //address of reg0

parameter reg1_address = 7'b0000001; //address of reg1

parameter reg2_address = 7'b0000010; //address of reg2

parameter reg3_address = 7'b0000011; //address of reg3

//start

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

start <= 1'b0;

else

start <= 1'b1;

end

//bit_cnt

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

bit_cnt <= 4'b0;

else if(start)

bit_cnt <= bit_cnt + 1'b1;

end

//wr_rd

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

wr_rd <= 1'b0;

else if(bit_cnt == 4'b0 && mosi == 1'b0)

wr_rd <= 1'b0;

else if(bit_cnt == 4'b0 && mosi == 1'b1)

wr_rd <= 1'b1;

end

//reg_addr

always @ (negedge sclk or negedge rst_n)

begin

if(~rst_n)

reg_addr <= 7'b0;

else if(bit_cnt >= 4'd1 && bit_cnt <= 4'd7)

reg_addr <= {reg_addr[5:0],mosi};

end

//reg_data

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

reg_data <= 8'b0;

else if(!wr_rd && bit_cnt >= 4'd7)

reg_data <= {reg_data[6:0],mosi};

else if(wr_rd && bit_cnt == 4'd6)

reg_data <= reg2_out_r;

else if(wr_rd && bit_cnt >= 4'd7)

reg_data <= {reg_data[6:0],reg_data[7]};

end

//reg_out

assign reg0_out = reg0_out_r;

assign reg1_out = reg1_out_r;

assign reg2_out = reg2_out_r;

assign reg3_out = reg3_out_r;

always @ (negedge sclk or negedge rst_n)

begin

if(~rst_n)

begin

reg0_out_r <= 8'b0;

reg1_out_r <= 8'b0;

reg2_out_r <= 8'b0;

reg3_out_r <= 8'b0;

end

else if(!wr_rd && bit_cnt == 4'd0)

case(reg_addr)

reg0_address: reg0_out_r <= reg_data;

reg1_address: reg1_out_r <= reg_data;

reg2_address: reg2_out_r <= reg_data;

reg3_address: reg3_out_r <= reg_data;

endcase

end

//miso

assign miso = miso_r;

always @ (negedge sclk or posedge rst_n)

begin

if(~rst_n)

miso_r <= 1'b0;

else if(wr_rd && bit_cnt >= 4'd7)

miso_r <= reg_data[7];

end

endmodule

3. Testbench(tb):

`timescale 1us/1us

module tb();

regclk_40k;

regrst_n;

reg [7:0] data_in;

regsend_start;

wiresclk;

wirecs_n;

wiremosi;

wiremiso;

wire [7:0] data_out;

wire data_out_vld;

wire [7:0] reg0_out;

wire [7:0] reg1_out;

wire [7:0] reg2_out;

wire [7:0] reg3_out;

spi_master i_spi_master(

.clk_40k          (clk_40k),     

.rst_n              (rst_n),

.data_in          (data_in),

.send_start     (send_start),

.sclk               (sclk),

.cs_n              (cs_n),

.mosi              (mosi),

.miso              (miso),

.data_out        (data_out),  

.data_out_vld (data_out_vld)

);

spi_slave i_spi_slave(

.rst_n            (rst_n),       

.cs_n             (cs_n),

.sclk             (sclk),        

.mosi            (mosi),      

.miso            (miso),      

.reg0_out      (reg0_out), 

.reg1_out      (reg1_out), 

.reg2_out      (reg2_out), 

.reg3_out      (reg3_out)

);

initial

begin

rst_n = 1'b0;

#10rst_n = 1'b1;

end

initial

begin

clk_40k = 1'b0;

forever

#1clk_40k = ~clk_40k;

end

initial

begin

send_start = 1'b0;

data_in = 8'd0;

forever

begin

    #200;

    data_in = $random()%256;

    send_start = 1'b1;

    #2

    send_start = 1'b0;

    #8000;

end

end

endmodule

4. 仿真结果:

按照testbench对SPI主从设备进行仿真,仿真结果如图:

mcu

  1. 系统时钟和SPI时钟不一致,clk_40k为高频系统时钟,利用计数器分频实现1k波特率SPI时钟;
  2. 复位信号rst_n低电平有效,正常传输时始终处于高电平;
  3. 开始传输时send_start信号拉高,传输结束时data_out_vld信号拉高;
  4. SPI主设备将输入数据data_in并行转mosi串行输出,SPI从设备将接收到的串行存入数据,将移位后的数据data_out并行转miso串行输出。

05

SPI的优缺点

5.1 SPI协议优点

  1. 全双工同步串行通信;
  2. 允许数据逐位传递;
  3. 允许数据传输暂停;
  4. 硬件结构简单,不需要精密时钟;
  5. 从机不需要唯一地址,也不需要收发器。

5.1 SPI协议缺点

  1. 需要4个引脚接口;
  2. 支持传输距离较短;
  3. 硬件层面没有定义校错协议和从机应答信号。
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分