IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 三大通信协议(3)SPI续——基于flash的读操作 -> 正文阅读

[嵌入式]三大通信协议(3)SPI续——基于flash的读操作

一、实例

????? 将任意一个程序下载到FPGA的外部flash芯片中,编写Verilog程序,通过FPGA读取flash中的内容,并将读取的内容通过串口发送出来。本篇是接着上一篇实例,继续完成剩余部分。

????? 下图是整个系统的模块框图:

??? 上一篇文章中已经完成了spi_read模块程序的编写,剩余的按键检测消抖模块和串口发送模块分别在“三大通信协议(2)IIC 续”、“三大通信协议(1)UART”两篇文章中都有说明,这里直接给出程序代码。

`timescale 1ns/1ns
module key_filter
#(
   parameter   CNT_MAX = 999_999//20ms
)
(
   input         sys_clk,
   input         sys_res,
   input         key,
   output  reg   key_flag
);
reg    [19:0]cnt_1000_000;

always@(posedge sys_clk or negedge sys_res)
    if(!sys_res)
	    cnt_1000_000 <= 20'd0;
    else if(key == 1'b0)
	    if(cnt_1000_000 == CNT_MAX)
		   cnt_1000_000 <= cnt_1000_000;
	    else
	           cnt_1000_000 <= cnt_1000_000 + 1'b1;
    else
	    cnt_1000_000 <= 20'd0;
always@(posedge sys_clk or negedge sys_res)
    if(!sys_res)
        key_flag <= 1'b0;
    else if(cnt_1000_000 == CNT_MAX-1)
        key_flag <= 1'b1;
    else
        key_flag <= 1'b0;	
	
endmodule  

module uart_tx(

     input         clk,
     input         res,
     input  [7:0]  data,
     input         en,
     
     output reg    txd

);
reg               tx_d0;
reg               tx_d1;
reg               tx_flag; 

reg  [15:0]       clk_cnt;
reg  [3:0]        tx_cnt;
reg  [7:0]        tdata;

wire              start_flag; 

parameter   clk_fre = 50000000;
parameter   uart_bps = 9600;
localparam  BPS_CONT = clk_fre/uart_bps;

assign  start_flag = (~tx_d1) & tx_d0; 

always @(posedge clk or negedge res) begin
       if(!res) begin
          tx_d0 <= 1'b0;
          tx_d1 <= 1'b0;
       end
       else begin
          tx_d0 <= en;
          tx_d1 <= tx_d0;
       end  
end 

always @(posedge clk or negedge res) begin
       if(!res) begin
           tx_flag <= 1'b0; 
           tdata   <= 8'b0;
       end
       else begin
          if(start_flag)  begin 
             tx_flag <= 1'b1;
             tdata   <= data;
          end
          else if((tx_cnt == 4'd9) && (clk_cnt == BPS_CONT/2)) begin 
             tx_flag <= 1'b0;
             tdata   <= 8'b0;
          end 
          else  begin 
             tx_flag <= tx_flag;
             tdata   <= tdata;
          end     
       end  
end 


always @(posedge clk or negedge res) begin
       if(!res) begin
          tx_cnt  <= 4'd0;
          clk_cnt <= 16'd0;
       end
       else if(tx_flag) begin
          if(clk_cnt <= BPS_CONT-1) begin 
             clk_cnt <= clk_cnt + 1'd1;
             tx_cnt  <= tx_cnt;
          end 
          else  begin
             clk_cnt <= 16'd0;
             tx_cnt  <= tx_cnt + 1'd1;
          end 
       end  
       else begin
           tx_cnt  <= 4'd0;
           clk_cnt <= 16'd0;
       end 
end 

always @(posedge clk or negedge res) begin
       if(!res) begin
           txd <= 1'b1;
       end
       else if(tx_flag)begin
              case (tx_cnt)
               4'd0: txd <= 1'b0;
               4'd1: txd <= tdata[0];
               4'd2: txd <= tdata[1];
               4'd3: txd <= tdata[2];
               4'd4: txd <= tdata[3];
               4'd5: txd <= tdata[4];
               4'd6: txd <= tdata[5];
               4'd7: txd <= tdata[6];
               4'd8: txd <= tdata[7];
               4'd9: txd <= 1'b1;
               default:;
               endcase 
           end 
       else
           txd  <= 1'b1; 
end 





endmodule

接下来给出顶层代码

module top_flash_read(
           input         sys_clk  ,
	   input         sys_res  ,
	   input         key_in   ,
	   input         miso     ,
	   output        tx       ,
	   output        sclk     ,
	   output        cs_n     ,
	   output        mosi     
	   );
parameter    CNT_MAX = 999_999;//按键消抖检测20ms
wire                 key_flag; 
wire      [7:0]      tx_data;
wire                 tx_flag;
key_filter
#(
  .CNT_MAX(CNT_MAX)
)u_key_filter
(
   .   sys_clk         (sys_clk),
   .   sys_res         (sys_res),
   .   key             (key_in),
   .   key_flag        (key_flag)
);

spi_read  u_spi_read
(
         .  sys_clk(sys_clk ),
	 .  sys_res(sys_res ),
	 .  key    (key_flag),
         .  miso   (miso    ),
	 .  sclk   (sclk),
         .  cs_n   (cs_n),	 
	 .  mosi   (mosi),
	 .  tx_flag(tx_flag),
	 .  tx_data(tx_data)
);               

uart_tx u_uart_tx(

     .  clk   (sys_clk),
     .  res   (sys_res),
     .  data  (tx_data),
     .  en    (tx_flag),
     
     .  txd   (tx)

);

endmodule 

? ? ? 接下来进行上板测试验证。首先将之前测试的数码管显示实验中生成的output_file.jic文件下载到开发板中(该文件会在评论处给出),为了对比最后读出的数据,这里将output_file.jic文件后缀名改为.bin,为的是能够在多功能串口调试助手中能够打开该文件,打开后的output_file.bin如下图所示(都是以十六进制显示):前边的数据是帧头数据,中间蓝色的是Flash中存储的程序的数据,后边的数据是帧尾数据。

? ? ? ?接下来将程序下载到开发板中。(注意:1.将spi_read.v文件中的扇区地址、页地址、字节地址都改为0,为了对比结果是否正确;2.将spi_read.v文件中data <= {data[6:0],miso};改为data <= {miso,data[7:1]};因为miso口输入的数据是先进低位再进高位)

? ? ? 在Signal Tap Logic Analyzer中抓取的信号如下图所示:

? ? ? 对比蓝色框中从Flash中读出的数据与上述output_file.bin文件中的数据,可以发现,数据一致,说明读取正确性。

? ? ? 连接上串口调试助手,将读取到的数据通过串口打印出来,打印结果如下图所示:

?对比上述结果发现,数据完全一致,说明串口发送的数据准确无误。

?总结

? ? ? ? 到此为止,三大数据通信协议告一段落。UART、I2C、SPI三种通信协议目前已经十分成熟,虽然协议内容相对比较简单,但是仍被广泛使用,足以见证其重要性。建议FPGA初学者反复揣摩其中的内涵。本人目前正在做的项目里就有很多涉及到SPI通信的知识,比如通过FPGA配置AD芯片,FPGA向AD芯片发送信息指令时,很多都遵循SPI的通信协议。其实深入研究会发现,很多通信协议都大同小异,实质就是发端与收端按照规定的方式进行通信,当然这些通信的协议完全可以由我们人为规定,只需将发端和收端配置成我们自己拟定的通信协议,然后进行数据的收发。例如,在FPGA与STM32两个主控芯片之间进行数据通信时,我们就可以按照自己拟定的通信方式:STM32作为通信的主机,FPGA作为通信的从机,首先FPGA向STM32发送一个数据传输的起始信号,STM32接收到该信号后进入中断,然后向FPGA发送读取数据的使能信号和时钟信号,FPGA根据STM32发送过来的使能信号和时钟信号,将要发送的数据传给STM32。

? ? ? ? 初次创作,难免文章中存在错误,希望读者能够及时纠正并给予私信,望大家共同进步!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:41:30  更:2021-10-30 12:41:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:27:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码