SPI协议,大佬们讲得很多,但总感觉没有讲到小白的痛处,比如:极性和相位 极性指的是空闲状态下时钟的电平状态,这个很好理解,verilog代码也很好实现, 比如,极性为0,表示空闲状态下时钟的电平为低,verilog代码只需要将时钟寄存器的初始值设为0即可,反之亦然; 相位为0,表示在数据在时钟的第一个跳变沿被采集,啥意思?小白在这里就懵了,更别说写代码了, 以极性为0举例,假设极性为0,相位为0,那么,数据将在spi时钟的第一个跳变沿被采集,换言之,数据将在spi时钟的上升沿被采集,代码如何实现? 假设我要写一个主机,要实现数据将在spi时钟的上升沿被采集,那么,主机就必须让需要发出的数据在spi时钟的下降沿改变,为何? 你想啊,从机需要在spi时钟的上升沿采集数据,那么,数据线上的数据在spi时钟的上升沿到来之前肯定得稳定才行吧?如何做到?很简单,知己下降发送数据,从机上升沿采集数据嘛,这样一来,不久完美解决? 参考米联客的SPI例程,写得还是挺好的,我稍加了修改。 由于SPI接收比较简单,代码就不放出来了,这里介绍一下SPI接收模块的代码
module master_spi_tx#
(
parameter SYS_CLK = 50_000_000, //我添加的,为了使用不同板子
parameter SPI_CLK = 100_000, //我添加的,为了使用不同板子
parameter CPOL = 1'b0,
parameter CPHA = 1'b0
)
(
input clk_i,
output spi_tx_o,//mosi
output spi_clk_o,//SPI 时钟输出SCK
input spi_tx_en_i,//发送发送使能信号
input [7:0] spi_tx_data_i,//待发送数据
//output spi_en_o,//SPI 传输使能
output spi_cs_o, //这是我添加的,为了适应操作FLASH
output spi_busy_o//SPI正在传输,高代表忙
);
//SPI时钟分频单元
//parameter [9:0] SPI_DIV = 10'd499;//分频 假设(50Mhz/100K/ - 1'b1=499
parameter SPI_DIV = SYS_CLK/SPI_CLK - 1;
parameter SPI_DIV1 = SPI_DIV/2;
parameter PSET = CPHA ? 1'b1 : 1'b0;
reg [9:0] clk_div = 10'd0;
reg spi_en = 1'b0; //标志spi正在传输一个字节数据
always@(posedge clk_i)begin
if((clk_div
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?