SPI通信实验---verilog(FPGA作为从机,使用可读可写)
本实验讲究实用性,故设计思想为:主机先向从机发送地址,若是向从机写入数据,则向从机发送数据,若是读取从机数据,则向从机发送时钟,然后在时钟下降沿读取数据即可。cs信号上升沿作为SPI通信的结束信号。rom程序只是做测试使用。
每次发送16个时钟信号,前八个是地址和命令,后八个是数据。其中:前8个时钟接受的数据的最高位决定着这次通信是读取数据还是写入数据,最高位为1,则是读取数据,为0则是写入数据。
程序:
/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :spi_slave_2.v
** CreateDate :2015.004
** Funtions :spi通信试验。FPGA作为从机,与主机进行通信。先接收主机发来的地址,再根据地址最高位来判断是读数据还是些数据,
然后从机是接收数据还是送出数据。地址最高位为高则是读取数据,否则为写数据.上升沿接收数据,下降沿发送数据
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/
module spi_slave_2 (
clk,
rst_n, spi_cs,
spi_sck,
spi_miso,
spi_mosi, spi_over );
input clk;
input rst_n; input spi_cs;
input spi_sck;
input spi_mosi; output reg spi_miso;
output spi_over; //-----------------------------//
reg spi_cs_2,spi_cs_1;
reg spi_sck_2,spi_sck_1;
reg spi_mosi_2,spi_mosi_1;
wire spi_cs_pos;
wire spi_cs_flag;
wire spi_sck_neg;
wire spi_sck_pos;
wire spi_mosi_flag;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
{spi_cs_2,spi_cs_1} <= 'b11;
{spi_sck_2,spi_sck_1} <= 'b00;
{spi_mosi_2,spi_mosi_1} <= 'b00;
end
else
begin
{spi_cs_2,spi_cs_1} <= {spi_cs_1,spi_cs};
{spi_sck_2,spi_sck_1} <= {spi_sck_1,spi_sck};
{spi_mosi_2,spi_mosi_1} <= {spi_mosi_1,spi_mosi};
end
end assign spi_cs_pos = ~spi_cs_2 &spi_cs_1;
assign spi_cs_flag = spi_cs_2;
assign spi_sck_neg = ~spi_sck_1&spi_sck_2;
assign spi_sck_pos = ~spi_sck_2&spi_sck_1;
assign spi_mosi_flag = spi_mosi_2; assign spi_over = spi_cs_pos;
//----------------------------------------//
localparam idel = 'd0;
localparam rxd_addr = 'd1;
localparam jude_wr_rd = 'd2;
localparam rxd_data = 'd3;
localparam rxd_over = 'd4;
localparam txd_data = 'd5;
localparam txd_over = 'd6;
localparam end_sta = 'd7; reg [:] state;
reg [:] cnt;
reg [:] raddr;
reg [:] rdata;
reg [:] tdata;
reg rover_flag;
reg wover_flag;
reg rd_flag;
wire [:] data_out;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state <= 'd0;
cnt <= ;
raddr <= 'd0;
rdata <= 'd0;
tdata <= 'd0;
rover_flag <= ;
wover_flag <= ;
rd_flag <= ;
spi_miso <= ;
end
else if(!spi_cs_flag)
begin
case(state)
idel:
begin
state <= rxd_addr;
cnt <= ;
raddr <= 'd0;
rdata <= 'd0;
tdata <= 'd0;
rover_flag <= ;
wover_flag <= ;
rd_flag <= ;
spi_miso <= ;
end
rxd_addr:
begin
if(cnt == )
begin
cnt <= ;
state <= jude_wr_rd;
end
else if(spi_sck_pos)
begin
cnt <= cnt + ;
raddr[ - cnt[:]] <= spi_mosi_flag;
end
end
jude_wr_rd:
begin
if(raddr[] == )
state <= rxd_data;
else
begin
state <= txd_data;
rd_flag <= ;
end
end
rxd_data:
begin
if(cnt == )
begin
cnt <= ;
state <= rxd_over;
end
else if(spi_sck_pos)
begin
cnt <= cnt + ;
rdata[ - cnt[:]] <= spi_mosi_flag;
end
end
rxd_over:
begin
rover_flag <= ;
state <= end_sta;
end
txd_data:
begin
tdata <= data_out;
if(cnt == )
begin
cnt <= ;
state <= txd_over;
end
else if(spi_sck_pos)
begin
cnt <= cnt + ;
spi_miso <= tdata[ - cnt[:]];
end
end
txd_over:
begin
wover_flag <= ;
state <= end_sta;
end
end_sta:
begin
rover_flag <= ;
wover_flag <= ;
state <= end_sta;
end
default:state <= 'd0;
endcase
end
else
begin
state <= 'd0;
cnt <= ;
raddr <= 'd0;
rdata <= 'd0;
tdata <= 'd0;
rover_flag <= ;
wover_flag <= ;
rd_flag <= ;
spi_miso <= ;
end
end data_rom data_rom_1 (
.clk(clk),
.rst_n(rst_n), .wr(rover_flag),
.rd(rd_flag), .addr(raddr[:]),
.data_in(rdata),
.data_out(data_out)
);
endmodule
ROM:
/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :data_rom.v
** CreateDate :2015.04
** Funtions : 简单的数据读写存储程序,配合测试
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/
module data_rom (
clk,
rst_n, wr,
rd, addr,
data_in,
data_out
);
input clk;
input rst_n; input wr;
input rd;
input [:] addr;
input [:] data_in; output reg [:] data_out; reg [:] table_1 [:];
wire [:] table_2 [:];
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
table_1[] <= ;
data_out <= ;
end
else if(wr)
begin
table_1[addr] <= data_in;
end
else if(rd)
data_out <= table_1[addr];
else
begin
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
table_1[] <= table_1[];
data_out <= data_out;
end
end assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[];
assign table_2[] = table_1[]; endmodule
测试程序:
/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :spi_slave_tb.v
** CreateDate :2015.04
** Funtions :测试文件
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/ `timescale ns/ ns module spi_slave_tb ;
reg clk;
reg rst_n; reg spi_cs;
reg spi_sck;
wire spi_miso;
reg spi_mosi; wire spi_over; spi_slave_2 spi_slave_2_1(
.clk,
.rst_n, .spi_cs,
.spi_sck,
.spi_miso,
.spi_mosi, .spi_over
); parameter tck = ;
parameter t = /tck; always
#(t/) clk = ~clk; //-------------------------------
/* 模仿spi主机的发送程序,这个task很好,仿顺序操作,可以直观的显示过程 */
task spi_sd;
input [:] data_in;
begin
#(*t); spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[7]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[6]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[5]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[4]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[3]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[2]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[1]
spi_sck = ; spi_mosi= data_in[]; #(*t); spi_sck = ; #(*t); //send bit[0]
spi_sck = ; end
endtask initial
begin
clk = ;
rst_n = ;
spi_cs = ;
spi_sck = ;
spi_mosi = ; #(*t) rst_n = ;
#(*t);
spi_cs = ;
spi_sd('h81);
#(*t);
spi_sd('h04);
#(*t);
#(*t);
spi_cs = ; #(*t);
spi_cs = ;
spi_sd('h01);
#(*t);
spi_sd('h00);
#(*t);
spi_cs = ;
end endmodule
仿真图:
图中可以看出,第一次输入8‘h81,意味着向01的地址写入数据。第二个数8’h04,则是要写入的数据。然后写入数据8‘h01,则意味着要读取01地址的数据,然后发送8个时钟则是再读取数据。
SPI通信实验---verilog(FPGA作为从机,使用可读可写)的更多相关文章
- SPI的通信试验 --verilog (从机-全双工)
SPI的 有关知识参考FPGA作为主机的通信实验. 本实验中FPGA作为从机通过SPI与MCU等通信的试验,可以在时钟上升沿接收数据并且在时钟下降沿发送数据,模仿全双工模式.接收的 数据作为地址,通过 ...
- 理解一下单片机的I2C和SPI通信
应某位网友要求,今天说一下单片机的I2C SPI通信,可能说不清楚,因为这毕竟要做实验才可完全理解. I2C和SPI是两种不同的通信协议. 听到协议,似乎高不可攀,其实协议就是人们定义的一个标准而已, ...
- [转]什么是SPI通信
SPI:高速同步串行口.3-4线接口,收发独立.可同步进行. SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口.是Motorola首先在其MC6 ...
- 什么是SPI通信?
SPI:高速同步串行口.3-4线接口,收发独立.可同步进行. SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口.是Motorola首先在其MC6 ...
- SPI通信
SPI是由Motorola公司提出的一种同步串行外围接口:它在速度要求不高,低功耗,需要保存少量参数的智能化传感系统中得到了广泛应用: SPI是一个全双工的同步串行接口,在数据传输过程中,总线上只能是 ...
- 关于SPI通信原理与程序实现
第一次接触SPI是因为当时用到NRF24L01,需要用SPI进行通信.因为2401上面写着MOSI.MISO.SS.RST,当时以为只要用到SPI就肯定有这几个引脚,以至于限制了自己的思维.只认识MI ...
- 实验九 ZStack 广播通信实验
实验九 ZStack 广播通信实验[实验目的]1. 了解 ZigBee 广播通信的原理2. 掌握在 ZigBee 网络中进行广播通信的方法[实验设备]1. 装有 IAR 开发工具的 PC 机一台2. ...
- [转]SPI通信原理简介
[转自]http://www.cnblogs.com/deng-tao/p/6004280.html 1.前言 SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 ...
- ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信,所以本章的主要内容就是讲解ESP8266 SPI和I2C总线 ...
随机推荐
- WPF中嵌入Office编辑器(支持Word、Excel、PPT、Visio等)
现在有一个项目,需要使用wpf做一个简单的客户端,用来生成word.excel.ppt.visio等文档,这就需要能够在wpf中嵌入office的编辑器,并对office文档进行编辑. 在网上搜索了一 ...
- 修改eclipse/MyEclipse中包的显示结构为树形
在右上边三角那里进去设置 选第一个是显示完整的包名,第二个显示的是树形结构,我们一般用第一种,如下图:
- MyEclipse------从服务器下载文件
Downfile.jsp <%@ page language="java" import="java.util.*" pageEncoding=" ...
- 离线渲染中的不规则光源(Meshlight)
之前一直在考虑这样一个问题,在实际生活中的光源都是有体积的,但是图形学中,很多时候我们用简单的点光源,面光源,或者方向光来模拟实际生活中这些光源,势必会产生一些误差,同时导致很多效果不好做.那么在离线 ...
- derby支持的数据类型
Data types This section describes the data types used in Derby. Built-In type overview Numeric types ...
- linux查看内核版本、系统版本、系统位数(32or64)
linux查看内核版本.系统版本.系统位数(32or64) 2011-05-01 22:05:12 标签:linux 内核版本 休闲 系统版本 系统位数 1. 查看内核版本命令: 1) [root@ ...
- ThinkPHP3.2.3自带的分页用法--很简单实用
把解压后的Page.class.php放入ThinkPHP/Extend/Library/ORG/Util/(如果没有请手动创建)目录下面.thinkphp 自带的分页非常好用美观,先看一下如下代码片 ...
- 关于windows系统下 webpack的使用
最近包子在研究webpack打包,发现,真是个好东西,以前完全不懂,其实很简单,步骤如下: 1.安装webpack嘎嘎嘎嘎~~~ 2.初始化一下 3.这玩意是啥,我不知道,就依葫芦画瓢 4.这玩意是啥 ...
- [Effective JavaScript 笔记]第57条:使用结构类型设计灵活的接口
想象创建wiki的库.wiki网站包含用户可以交互式地创建.删除和修改的内容.许多wiki都以简单.基于文本标记语言创建内容为特色.通常,这些标记语言只提供了HTML可用功能的一个子集,但是却有一个更 ...
- ios开发者到真机测试
ios就是矫情, 没事搞那么多步奏, 搞得我都不会弄了, 不懈努力后还是弄好了, 总结一下, 避免新人走弯路. 苹果的脾气就是这样, 只能慢慢学了 1. 生成CSR (开发者证书认证请求) 打开钥匙 ...