FPGA实现SPI协议
SPI接口
1 简单的设计模块1
首先简单的想一下这个模块应该怎么设计。
拿到这个小题目你的思路是怎么样的呢?很多时候靠经验设计,并没有一个顺序的思路。
六步法:
第一步:输入输出波形的画出
第二步:画出计数器结构(搞清楚数的是什么东西)
cnt表示上一个时钟数到的结果。数x下,通用表达式:add_cnt&&cnt==x-1;
第三步:确认计数器加1条件(数什么)和结束条件(数多少个),注意先考虑加1,在考虑结束条件;
我们计数器cnt数的是什么呢?dout==1的时钟个数,cnt要数10个(10是功能要求来的)
第四步:确认其他信号的变化条件(dout 变化点,即0变1,1为0的条件)
dout由0变1 的条件是什么?是en1;
dout由1变0的条件是? dout1的时钟个数为10
cnt add_cnt:dout ==1
cnt 数多少:10个// 计数器模板
always@(posedge clk or negedge rst_n) beginif(!rst_n) begincnt <= 0;endelse if(add_cnt) beginif(end_cnt)cnt <= 0;elsecnt <= cnt + 1;end
endassign add_cnt = dout == 1; // 加1的条件
assign end_cnt = add_cnt && cnt == 10-1; // 数10下dout == 1 : en == 1
dout == 0 : 数到10个always@(posedge clk or negedge rst_n) beginif(rst_n==1'b0) begindout <= 0;endelse if(en == 1) begin // dout什么时候拉高dout <= 1;endelse if (end_cnt) begin //(add_cnt && cnt == 10-1) begin // 数10下之后dout拉低dout <= 0;end
end
第五步:写出计数器代码(always除了名字外不能改变,加1条件即是要数什么东西,结束条件要记住格式后)
2 简单模块设计2
对于这种状态还是数cnt, 可以这种思考。
也可以这样计数。这是正确的计数方式
第一步:画出输入输出波形
第二步:画出计数器结构
cnt0的加1条件: flag == 1 ,加一个信号把flag
cnt0 要数多少:3个cnt1的加1条件:end_cnt0 //
cnt1 要数多少个:3个flag >1: en == 1
flag >0: end_cnt1dout>1: add_cnt0 && cnt0 == 1-1 // 当cnt0 数一个的时候拉高
dout>0: end_cnt0 (add_cnt0 && cnt0 == 3-1)然后就填填空啦!!!!!!
3 SPI通信协议
3.1 SPI通信协议原理
CS 选择工作模式
DIN选择通道地址
DOUT 输出给FPGA
module SPI(input clk,input rst_n,input start,input [2:0]channel,// ADC128s022input DOUT,output reg SCLK,output reg DIN,output reg CS_N,output reg done,output [11:0] data.);reg en;reg [2:0] r_channel;// r_channel 使channel的信号稳定always@(posedge clk or negedge rst_n) beginif(!rst_n)r_channel <= 'd0;else if(start)r_channel <= channel;elser_channel <= r_channel;end// 转换使能信号always@(posedge clk or negedge rst_n) beginif(!rst_n)en <= 1'b0;else if(start)en <= 1'b1;else if(done)en <= 1'b0;elseen <= en;endreg [4:0] cnt;reg cnt_flag;reg [5:0]SCLK_CNT;// cnt 的变化always@(posedge clk or negedge rst_n) beginif(!rst_n)cnt <= 'd0;else if(en) beginif(cnt == 'd10)cnt <= 'd0;elsecnt <= cnt + 1'b1;endelsecnt <= 'd0;end// cnt flag always@(posedge clk or negedge rst_n) beginif(!rst_n)cnt_flag <= 1'b0;else if(cnt == 'd10)cnt_flag <= 1'b1;elsecnt_flag <= 1'b0;end// sclk_cntalways@ (posedge clk or negedge rst_n) beginif(!rst_n)sclk_CNT <= 'd0;else if(en) beginif(SCLK_CNT == 'd33)SCLK_CNT <= 'd0;else if(cnt_flag)SCLK_CNT <= SCLK + 1'b1;elseSCLK_CNT <= SCLK_CNT;endelseSCLK_CNT <= 'd0;endreg [11:0] r_data;// ============================================always@(posedge clk negedge rst_n) beginif(!rst_n) beginSCLK <= 1'b1;CS_N <= 1'b1;DIN <= 1'b1;endelse if(en) begincase(SCLK_CNT)6'd0:begin CS_N <= 1'b0; end6'd1:begin SCLK <= 1'b0;DIN <= 1'b0; end6'd2:begin SCLK <= 1'b1; end6'd3:begin SCLK <= 1'b0; end6'd4:begin SCLK <= 1'b1; end6'd5:begin SCLK <= 1'b0; DIN <= r_channel[2];end6'd6:begin SCLK <= 1'b1; end6'd7:begin SCLK <= 1'b0; DIN <= r_channel[1];end6'd8:begin SCLK <= 1'b1; end6'd9:begin SCLK <= 1'b0; DIN <= r_channel[0];end6'd10,6'd12,6'd14,6'd16,6'd18,6'd20,6d'22,6d'24,6'd26,6'd28,6'd30,6'd32:begin SCLK <= 1'b1; r_data <= {r_data[10:0], DOUT}; end6'd11,6'd13,6'd15,6'd17,6'd19,6'd21,6d'23,6d'25,6'd27,6'd29,6'd31,6'd33:begin SCLK <= 1'b0;end6'd33:begin CS_N <= 1'b1;enddefault: begin CS_N <= 1'b1;end endcaseendelse beginSCLK <= 1'b1;CS_N <= 1'b1;DIN <= 1'b1; endend// done 信号always@(posedge clk or negedge rst_n) beginif(!rst_n)done <= 1'b0;else if(SCLK_CNT == 'd33)done <= 1'b1;elsedone <= 1'b0;end// data 信号always@(posedge clk or negedge rst_n) beginif(!rst_n)data <= 'd0;else if(SCLK_CNT == 'd33)data <= r_data;elsedata <= data;endendmodule
`timescale 1ns/1ns
module SPI_tb;reg clk;reg rst_n;reg start;reg [2:0] channel;wire SCLK;DIN;CS_N;DOUT;wire done;wire [11:0]data;SPI SPI_inst(.clk(clk),.rst_n(rst_n),.start(start),.channel(channel),.SCLK(SCLK),.DIN(DIN),.CS_N(CS_N),.DOUT(DOUT),.done(done),.data(data));initial clk = 1'b1;alwayss#10 clk = ~clk;initial beginrst_n = 1'b0;channel = 'd0;start = 1'b0;DOUT = 1'b0;endendmodule
3.1 SPI原理2
SPI是微控制器和外围IC 如传感器 adc 和dac 移位寄存器、SRAM等。之间使用最广泛的接口之一。SPI是一种同步、全双工、主从式接口。来自主机或从机的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据。SPI接口可以是三线式或四线。
CS 低电平有效
SPI的环形数据收发模式,SPI在收发数据的原理很简单,就是两个移位寄存器,待发送的数据首先写入din_buf 中缓存,需要发送的时候输入进data_shift 中,通过移位的方式发送高位数据,同时接受到的数据存入低位,写满时存入到dout_buf 中,再由dout_buf 写入内部总线。
代码放到:https://download.csdn.net/download/qq_30093417/86757879
FPGA实现SPI协议相关推荐
- 【FPGA】SPI协议
1.SPI简介 SPI(Serial Perripheral Interface, 串行外围设备接口)是 Motorola 公司推出的一种同步串行接口技术.SPI 总线在物理上是通过接在外围设备微控制 ...
- 【FPGA】SPI协议详解及对flash读写操作
FPGA基于SPI实现对flash读写操作 概括 一.SPI协议.flash讲解 1.SPI协议 2.flash (1)WREN (2)RDID (3)WRSR (4)READ (5)PP (6)SE ...
- fpga使用spi协议擦除读写flash芯片
一.需求说明 fpga首先全擦除flash芯片,然后往flash芯片中写入一页数据,再接着读取这一页数据. 二.硬件介绍 1.flash资源介绍 M25P16芯片是flash芯片,容量是16Mbit. ...
- FPGA作为从机与STM32进行SPI协议通信---Verilog实现
一.SPI协议简要介绍 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用 ...
- FPGA实现的SPI协议(一)----SPI驱动
写在前面 SPI协议系列文章: FPGA实现的SPI协议(一)----SPI驱动 FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用 1.什么是SPI协议 SPI( ...
- FPGA作为从机与STM32进行SPI协议通信
1.SPI协议简要介绍 (1)SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上 ...
- FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用
写在前面 SPI协议系列文章: FPGA实现的SPI协议(一)----SPI驱动 FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用 在上篇文章,简要介绍了SPI协 ...
- 基础SPI协议的FPGA实现(兼顾SPI4种模式)—Verilog
简要说明 看见许多博主都有编写SPI协议,但是大都是对一个指定的时序进行FPGA的实现.于是就想编写一个比较常见的SPI通信协议,而且兼顾4种模式和不同数据长度.主要是用来对常见SPI协议的应用,和辅 ...
- FPGA构造spi时序——AD7176为例(转)
reference:https://blog.csdn.net/fzhykx/article/details/79490330 项目中用到了一种常见的低速接口(spi),于是整理了一下关于spi相关的 ...
最新文章
- 轻松搞定c++语言pdf_当年锤子的大爆炸,如今12个语言版本都可轻松搞定!
- 博士在淘宝“扫垃圾”
- 4.4 机器学习系统设计--垃圾邮件分类-机器学习笔记-斯坦福吴恩达教授
- vb excel 整行删除_Excel中常用的批量处理都不掌握,那就真的Out了
- Linux命令之hexdump - ”十六“进制查看器
- ue4光追降噪_【魔改UE4】后记_焦散效果总结
- hibernate中uuid和native等主键生成策略
- 300万高清车牌识别一体机Http推送
- 微型计算机就是完全采用大规模集成电路,湖南工大计算机在线作业
- win10计算机的数字小键盘,如何设置Win10开机默认开启数字小键盘?
- Excel-缺失数据处理
- android 虚拟基站和经纬度,android基于Gps 定位跟基站定位获取经纬度
- PageOffice——动态填充Word模板并在线编辑
- Ubuntu 自带截图工具快捷键盘
- 计算机网络协议(三)——UDP、TCP、Socket
- mysql中的/、div的区别
- Linux Ubuntu 安装 Realtek 8812BU无线网卡
- Linux命令大全总结(看这一篇就够了)
- 小高考三门计算机能报大专吗,美术生小高考的要求吗
- 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装,请在“默认应用置”解决办法