社区导航

 

搜索
查看: 1901|回复: 5

[讨论] 关于FPGA 做SPI_MASTER

[复制链接]

79

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-8-14 12:28 | 显示全部楼层 |阅读模式
最近在学习SPI  copy了以下SPI_MASTER代码发现好难懂。

  1. /***********************************************************************************************
  2. * SPI MASTER
  3. * January 2007
  4. ************************************************************************************************/
  5. `timescale 10ns/1ns
  6. module SPI_Master ( miso, mosi, sclk, ss, data_bus, CS, addr, pro_clk, WR, RD);

  7. inout [7:0] data_bus;           // 8 bit bidirectional data bus
  8. input pro_clk;                  // Host Processor clock
  9. input miso;                     // Master in slave out
  10. input [1:0] addr;               // A1 and A0, lower bits of address bus
  11. input CS;                       // Chip Select
  12. input WR, RD;                   // Write and read enables

  13. output mosi;                    // Master out slave in
  14. output sclk;                    // SPI clock
  15. output [7:0] ss;                // 8 slave select lines

  16. reg [7:0] shift_register;        // Shift register
  17. reg [7:0] txdata;                // Transmit buffer
  18. reg [7:0] rxdata;                // Receive buffer
  19. reg [7:0] data_out;              // Data output register
  20. reg [7:0] data_out_en;           // Data output enable
  21. reg [7:0] control, status;       // Control Register COntrols things like ss, CPOL, CPHA, clock divider
  22.                                  // Status Register is a dummy register never used.

  23. reg [7:0] clk_divide;            // Clock divide counter
  24. reg [3:0] count;                 // SPI word length counter
  25. reg sclk;                        
  26. reg slave_cs;                    // Slave cs flag
  27. reg mosi;                                           // Master out slave in
  28. reg spi_word_send;               // Will send a new spi word.

  29. wire [7:0] data_bus;
  30. wire [7:0] data_in = data_bus;
  31. wire spi_clk_gen;
  32. wire [2:0] divide_factor = control[2:0];
  33. wire CPOL = control[3];         
  34. wire CPHA = control[4];
  35. wire [7:0]ss;


  36. /* Slave Select lines */
  37. assign ss[7] = ~( control[7] &  control[6] &  control[5] & (~slave_cs));
  38. assign ss[6] = ~( control[7] &  control[6] & ~control[5] & (~slave_cs));
  39. assign ss[5] = ~( control[7] & ~control[6] &  control[5] & (~slave_cs));
  40. assign ss[4] = ~( control[7] & ~control[6] & ~control[5] & (~slave_cs));
  41. assign ss[3] = ~(~control[7] &  control[6] &  control[5] & (~slave_cs));
  42. assign ss[2] = ~(~control[7] &  control[6] & ~control[5] & (~slave_cs));
  43. assign ss[1] = ~(~control[7] & ~control[6] &  control[5] & (~slave_cs));
  44. assign ss[0] = ~(~control[7] & ~control[6] & ~control[5] & (~slave_cs));

  45. /* clock divide */
  46. assign spi_clk_gen = clk_divide[divide_factor];

  47. /* Clock Divider */
  48. always [url=home.php?mod=space&uid=496176]@[/url] (negedge pro_clk) begin
  49.     clk_divide = clk_divide + 1;     
  50. end

  51. /* Reading the miso line and shifting */
  52. always @ (posedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin
  53.     if (spi_word_send) begin
  54.         shift_register[7:0] = txdata;
  55.     end else begin
  56.         shift_register = shift_register << 1;
  57.         shift_register[0] <= miso;
  58.     end
  59. end

  60. /* Writing the mosi */
  61. always @ (negedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin
  62.     if (spi_word_send) begin
  63.         mosi = txdata[7];
  64.     end else begin
  65.         mosi = shift_register[7];
  66.     end
  67. end

  68. /* Contolling the interrupt bit in the status bit */
  69. always @ (posedge slave_cs or posedge spi_word_send) begin
  70.     if (spi_word_send) begin
  71.         status[0] = 0;
  72.     end else begin
  73.             status = 8'h01;
  74.           rxdata = shift_register;         // updating read buffer
  75.         end
  76. end
  77.    
  78. /* New SPI wrod starts when the transmit buffer is updated */
  79. always @ (posedge pro_clk) begin
  80.     if (spi_word_send) begin
  81.         slave_cs <= 0;
  82.     end else if ((count == 8) & ~(sclk ^ CPOL)) begin
  83.         slave_cs <= 1;
  84.     end   
  85. end

  86. /* New Spi word is intiated when transmit buffer is updated */
  87. always @ (posedge pro_clk) begin
  88.     if (CS & WR & addr[1] & ~addr[0]) begin
  89.         spi_word_send <=1;
  90.     end else begin
  91.         spi_word_send <=0;
  92.     end
  93. end

  94. /* Generating the SPI clock */
  95. always @ (posedge spi_clk_gen) begin
  96.     if (~slave_cs) begin
  97.         sclk = ~sclk;
  98.     end else if (~CPOL) begin
  99.         sclk = 0;
  100.     end else begin
  101.         sclk = 1;
  102.     end
  103. end

  104. /* Counting SPI word length */
  105. always @ (posedge sclk or posedge slave_cs) begin
  106.     if (slave_cs) begin
  107.         count = 0;
  108.     end else begin   
  109.         count = count + 1;
  110.     end
  111. end

  112. /* Reading, writing SPI registers */
  113. always @ (posedge pro_clk) begin
  114.     if (CS) begin
  115.         case (addr)
  116.         2'b00 : if (WR) control <= data_in;
  117.         2'b01 : if (RD) data_out <= status;   // Void
  118.                   2'b10 : if (WR) txdata <= data_in;
  119.                   2'b11 : if (RD) data_out <= rxdata;
  120.         endcase
  121.     end
  122. end

  123. /* Controlling the data out enable */
  124. always @ (RD or data_out) begin
  125.     if (RD)
  126.     data_out_en = data_out;
  127.     else
  128.     data_out_en = 8'bz;
  129. end

  130. assign data_bus = data_out_en;

  131. initial
  132. begin
  133.     mosi = 0;
  134.     //sclk = 0;
  135.     control = 0;
  136.     count = 0;
  137.     slave_cs = 1;
  138.     txdata = 0;
  139.     rxdata = 0;
  140.     clk_divide = 0;
  141.     data_out = 0;
  142. end

  143. endmodule

  144. /********************************************** END ******************************************************************/
复制代码















可能是我对SPI理解得还不够深  在FPGA作为master时
像INPUT里面的addr WR RD

OUTPUT 里面的 SS这些都是干什么的呢?

SPI总线不是最多四条就够了吗。
求解释。最好是有应用的实例
比如 我想FPGA发送1HZ方波 让单片机的LED闪动 应该怎么接?

此帖出自FPGA/CPLD论坛


回复

使用道具 举报

685

TA的帖子

6

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2015-8-14 13:17 | 显示全部楼层
你这个SPI是总线型方式驱动的吧,

点评

我也不太清楚要用哪种。我其实就想SPI进行下双机通信。。  详情 回复 发表于 2015-8-14 13:33


回复

使用道具 举报

79

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2015-8-14 13:33 | 显示全部楼层
fxyc87 发表于 2015-8-14 13:17
你这个SPI是总线型方式驱动的吧,

我也不太清楚要用哪种。我其实就想SPI进行下双机通信。。


回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2015-8-31 23:35 | 显示全部楼层
这个是使能信号啊,SPI四根线,你调用模块,就要告诉它什么时候开始,什么时候结束。


回复

使用道具 举报

4

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2015-9-11 20:21 | 显示全部楼层
inout [7:0] data_bus;           // 8 bit bidirectional data bus
input pro_clk;                  // Host Processor clock
input [1:0] addr;               // A1 and A0, lower bits of address bus
input CS;                       // Chip Select
input WR, RD;                   // Write and read enables
这几个看起来是跟处理器的接口(EMIF),spi主设备一般通过一套总线连到CPU上,由CPU来对其进行控制

output [7:0] ss;  是SPI的片选,这里有8个片选输出,即这个主设备可以挂8个从SPI设备,每个设备用一个片选,mosi和miso以及sclk是所有spi从设备公用


回复

使用道具 举报

6553

TA的帖子

8

TA的资源

版主

Rank: 6Rank: 6

发表于 2015-9-12 08:45 | 显示全部楼层
先搞清楚驱动的对象
生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/4 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-6-5 19:34 , Processed in 0.226341 second(s), 28 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表