FPGA的SPI从机模块实现
一. SPI总线协议


二. FPGA的SPI从机实现
1. 首先确定模块的输出输入管脚
module myspi(nrst, clk, ncs, mosi, miso, sck);
input clk, nrst;
input ncs, mosi, sck;
output miso;
2. SCK跳变沿检测
reg[2:0] sck_edge;
always @ (posedge clk or negedge nrst)
begin
if(~nrst)
begin
sck_edge <= 3'b000;
end
else
begin
sck_edge <= {sck_edge[1:0], sck};
end
end
wire sck_riseedge, sck_falledge;
assign sck_riseedge = (sck_edge[2:1] == 2'b01); //检测到SCK由0变成1,则认为发现上跳沿
assign sck_falledge = (sck_edge[2:1] == 2'b10); //检测到SCK由1变成0,则认为发现下跳沿
3. SPI接收部分
SPI接收部分使用有限状态机:
reg[7:0] byte_received;
reg[3:0] bit_received_cnt;
reg rec_flag;
reg[1:0] rec_status; //SPI接收部分状态机
reg[7:0] rec_data;
reg[2:0] rec_flag_width; //SPI接收完成标志位脉冲宽度寄存器
always @ (posedge clk or negedge nrst) //每次sck都会接收数据,spi的顶端模块状态机决定是否取用
begin
if(~nrst)
begin
byte_received <= 8'h00;
bit_received_cnt <= 4'h0;
rec_flag <= 1'b0;
rec_status <= 2'b00;
rec_flag_width <= 3'b000;
end
else
begin
if(~ncs)
begin
case (rec_status)
2'b00: begin
if(sck_riseedge)
begin
byte_received <= {byte_received[6:0], mosi};
if(bit_received_cnt == 4'h7)
begin
bit_received_cnt <= 4'b0000;
rec_status <= 2'b01;
end
else
begin
bit_received_cnt <= bit_received_cnt+1;
end
end
end
2'b01: begin
rec_data <= byte_received;
rec_flag <= 1'b1;
if(rec_flag_width==3'b100) begin
rec_flag_width <= 3'b000;
rec_status <= 2'b11;
end
else begin
rec_flag_width <= rec_flag_width+1;
end
end
2'b11: begin
rec_flag <= 1'b0;
rec_status <= 2'b00;
end
endcase
end
end
end
这里,使用rec_flag的原因是通知另一个模块处理接收数据(后面将会提到),rec_data若在下一次数据传输完成前不做处理则会丢失。
4. SPI发送部分
reg miso;
reg sending_flag; //正在发送标志位
reg[7:0] byte_sended; //发送移位寄存器
reg[3:0] bit_sended_cnt; //SPI发送位计数器
reg[1:0] send_status; //SPI发送部分状态机
always @ (posedge clk or negedge nrst)
begin
if(~nrst)
begin
byte_sended <= 8'h00;
bit_sended_cnt <= 4'b0000;
send_status <= 2'b00;
sending_flag <= 1'b0;
end
else
begin
if(~ncs)
begin
case (send_status)
2'b00: begin
if(send_flag)
begin //锁存发送数据
send_status <= 2'b01; //2'b01;
byte_sended <= send_data;
sending_flag <= 1'b1;
miso <= send_data[7];
end
end
2'b01: begin //发送数据移入移位寄存器
if(sck_riseedge) begin
//miso <= byte_sended[7];
//byte_sended <= {byte_sended[6:0], 1'b0};
send_status <= 2'b11;
end
end
2'b11: begin //根据sck下降沿改变数据
miso <= byte_sended[7];
if(sck_falledge) ///---------------------------------------这里多移了一位
begin
//miso <= byte_sended[7];
byte_sended <= {byte_sended[6:0], 1'b0};
if(bit_sended_cnt == 4'b0111)
begin
send_status <= 2'b10;
bit_sended_cnt <= 4'b0000;
sending_flag <= 1'b0;
end
else
begin
bit_sended_cnt <= bit_sended_cnt+1;
end
end
end
2'b10: begin //数据发送完毕
send_status <= 2'b00;
//sending_flag <= 1'b0;
miso <= 1'b0;
end
endcase
end
end
end
经过实测,SCK频率低于clk频率8倍以上,通信可靠稳定,测试芯片为XC3S50-TQ144,平台为ISE,clk为25MHz。
FPGA的SPI从机模块实现的更多相关文章
- 如何让FPGA中的SPI与其他模块互动起来
在上一篇文章<FPGA的SPI从机模块实现>中,已经实现了SPI的从机模块,如何通过SPI总线与FPGA内部其他模块进行通信,是本文的主要讨论内容. 一. 新建FPGA内部DAC控制模块 ...
- FPGA构造spi时序——AD7176为例(转)
reference:https://blog.csdn.net/fzhykx/article/details/79490330 项目中用到了一种常见的低速接口(spi),于是整理了一下关于spi相关的 ...
- IIS7注册本机模块
问题描述:打开mp4文件要映射给mod_h264_streaming.dll(http://h264.code-shop.com/trac/wiki/Mod-H264-Streaming-Intern ...
- python开发学习-day09(队列、多路IO阻塞、堡垒机模块、mysql操作模块)
s12-20160312-day09 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- 基于FPGA的SPI FLASH控制器设计
1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...
- ARM与FPGA通过spi通信设计2.spi master的实现
这里主要放两个代码第一个是正常的不使用状态机的SPI主机代码:第二个是状态机SPI代码 1.不使用状态机:特权同学<深入浅出玩转FPGA>中DIY数码相框部分代码: /////////// ...
- ARM与FPGA通过spi通信设计1.spi基础知识
SPI(Serial Peripheral Interface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息.SPI总线可直接与各个厂家生产 ...
- 嵌入式驱动开发之dsp fpga通信接口---spi串行外围接口、emif sram接口
-----------------------------------------author:pkf ------------------------------------------------ ...
- FPGA之SPI SD卡读操作
这几天在FPGA调试与SD通信,读SD卡里的图片,之前接触32时没有去研究过SD卡,不太熟悉操作流程,在网上找了很多资料,也看了几个32开发板的资料,但大多数都讲得不是特别清楚,只能瞎操作了一番,在别 ...
随机推荐
- 常用数据结构及复杂度 array、LinkedList、List、Stack、Queue、Dictionary、SortedDictionary、HashSet、SortedSet
原文地址:http://www.cnblogs.com/gaochundong/p/data_structures_and_asymptotic_analysis.html 常用数据结构的时间复杂度 ...
- Invert Binary Tree 解答
Quetion Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Solution 1 -- R ...
- java面试题集2
JAVA面试题-CORE JAVA部分 1. 在main(String[] args)方法内是否可以调用一个非静态方法? 答案:不能 2. 同一个文件里是否可以有两个public ...
- 委托、Lambda表达式
本文来自:http://wenku.baidu.com/link?url=o9Xacr4tYocCPhivayRQXfIc9kOZeWBwPn2FZfeF19P4-8YX5CMXs74WB-Y8t0S ...
- lua实现多继承
http://my.oschina.net/u/156466/blog/401576local class1 = {} function class1:new() local obj = {} set ...
- php下载服务器上的文件
$file_xls=$path; // 文件的保存路径 $example_name=basename($file_xls); //获取文件名 header('Content-Descrip ...
- [置顶] SSO单点登录系列6:cas单点登录防止登出退出后刷新后退ticket失效报500错
这个问题之前就发现过,最近有几个哥们一直在问我这个怎么搞,我手上在做另一个项目,cas就暂时搁浅了几周.现在我们来一起改一下你的应用(client2/3)的web.xml来解决这个2b问题,首先看下错 ...
- 启动tomcat后struts框架报异常严重: Exception starting filter struts2 Unable to load configuration. - Class: java.net.PlainSocketImpl
今天刚好宿舍断网,打开电脑,打开ide工具,启动tomcat后,访问web项目工程,页面显示404,查看控制台,运行报错信息如下: 严重: Exception starting filter stru ...
- CSS清除浮动_清除float浮动
2.clear:both清除浮动为了统一样式,我们新建一个样式选择器CSS命名为“.clear”,并且对应选择器样式为“clear:both”,然后我们在父级“</div>”结束前加此di ...
- C# 数据的序列化存取
1,什么是序列化? 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列 ...