河东做网站的公司亚马逊品牌网站建设

当前位置: 首页 > news >正文

河东做网站的公司,亚马逊品牌网站建设,昆明网络公司开发,注册网站时应注意什么简介 SPI#xff08;Serial Peripheral Interface#xff0c;串行外围设备接口#xff09;通讯协议#xff0c;是Motorola公司提出的一种同步串行接口技术。是一种高速、全双工、同步通信总线。在芯片中只占用四根管脚用来控制及数据传输。 优缺点#xff1a; SPI通讯协…简介 SPISerial Peripheral Interface串行外围设备接口通讯协议是Motorola公司提出的一种同步串行接口技术。是一种高速、全双工、同步通信总线。在芯片中只占用四根管脚用来控制及数据传输。 优缺点 SPI通讯协议的优点是支持全双工通信通讯方式较为简单且相对数据传输速率较快 缺点是没有指定的流控制没有应答机制确认数据是否接收与IIC总线通讯协议相比在数据可靠性上有一定缺陷。 物理层 对于SPI协议的物理层需要讲解的就是SPI通讯设备的连接方式和设备引脚的功能描述。 SPI通讯设备的通讯模式是主从通讯模式通讯双方有主从之分根据从机设备的个数SPI通讯设备之间的连接方式可分为一主一从和一主多从具体见下图1、2。 图 1 一主一从SPI通讯设备连接图 图 2 一主多从SPI通讯设备连接图 SPI通讯协议包含1条时钟信号线、2条数据总线和1条片选信号线 时钟信号线为SCK2条数据总线分别为MOSI(主输出从输入)、MISO(主输入从输出)片选信号线为它们的作用介绍如下 SCK (Serial Clock)时钟信号线用于同步通讯数据。由通讯主机产生决定了通讯的速率不同的设备支持的最高时钟频率不同两个设备之间通讯时通讯速率受限于低速设备。 MOSI (Master Output Slave Input)主设备输出/从设备输入引脚。主机的数据从这条信号线输出从机由这条信号线读入主机发送的数据数据方向由主机到从机。 MISO (Master InputSlave Output)主设备输入/从设备输出引脚。主机从这条信号线读入数据从机的数据由这条信号线输出到主机数据方向由从机到主机。 (Chip Select)片选信号线也称为CS_N以下用CS_N表示。当有多个SPI从设备与SPI主机相连时设备的其它信号线SCK、MOSI及MISO同时并联到相同的SPI总线上即无论有多少个从设备都共同使用这3条总线而每个从设备都有独立的这一条CS_N信号线本信号线独占主机的一个引脚即有多少个从设备就有多少条片选信号线。
I2C协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯而SPI协议中没有设备地址它使用CS_N信号线来寻址当主机要选择从设备时把该从设备的CS_N信号线设置为低电平该从设备即被选中即片选有效接着主机开始与被选中的从设备进行 SPI通讯。所以SPI通讯以CS_N线置低电平为开始信号以CS_N线被拉高作为结束信号。 四种通讯模式 SPI通讯协议一共有四种通讯模式模式0、模式1、模式2以及模式3这4种模式分别由时钟极性(CPOLClock Polarity)和时钟相位(CPHAClock Phase)来定义。 CPOL参数规定了空闲状态(CS_N为高电平设备未被选中)时SCK时钟信号的电平状态 CPHA规定了数据采样是在SCK时钟的奇数边沿还是偶数边沿。 极性和相位 SPI的极性Polarity和相位Phase最常见的写法是CPOL和CPHA不过也有一些其他写法简单总结如下 (1) CKPOL (Clock Polarity) CPOL POL Polarity 时钟极性 (2) CKPHA (Clock Phase) CPHA PHA Phase 时钟相位 (3) SCKSCLKSPI的时钟 (4) Edge边沿即时钟电平变化的时刻即上升沿(rising edge)或者下降沿(falling edge) 模式判别 CPOL表示当SCLK空闲idle的时候其电平的值是低电平0还是高电平1 CPOL0时钟空闲idle时候的电平是低电平所以当SCLK有效的时候就是高电平就是所谓的active-high CPOL1时钟空闲idle时候的电平是高电平所以当SCLK有效的时候就是低电平就是所谓的active-low CPHA0表示第一个边沿 对于CPOL0idle时候的是低电平第一个边沿就是从低变到高所以是上升沿 对于CPOL1idle时候的是高电平第一个边沿就是从高变到低所以是下降沿 CPHA1表示第二个边沿 对于CPOL0idle时候的是低电平第二个边沿就是从高变到低所以是下降沿 对于CPOL1idle时候的是高电平第一个边沿就是从低变到高所以是上升沿 SPI通讯协议的4种模式如下通讯模式时序图具体见下图
模式0CPOL 0CPHA0。空闲状态时SCK串行时钟为低电平数据采样在SCK时钟的上升沿数据更新在SCK时钟的下降沿。 模式1CPOL 0CPHA1。空闲状态时SCK串行时钟为低电平数据采样在SCK时钟的下降沿数据更新在SCK时钟的上升沿。 模式2CPOL 1CPHA0。空闲状态时SCK串行时钟为高电平数据采样在SCK时钟的下降沿数据更新在SCK时钟的上升沿。 模式3CPOL 1CPHA1。空闲状态时SCK串行时钟为高电平数据采样在SCK时钟的上升沿数据更新在SCK时钟的下降沿。 模式的判断 如果起始的SCLK的电平是0那么CPOL0如果是1那么CPOL1 然后看数据采样时刻对应到上面SCLK时钟的位置对应着是第一个边沿或是第二个边沿即CPHA是0或1 时序需求 tSLCHcs_n拉低到sck高的时间 tCHSHsck高到cs_n拉高的时间 SCK上升沿MOSI的建立时间保持时间需求 SPI通用模块 实现功能 用于将任意宽度向量型数据转换为SPI串行输出模式0CPOL 0CPHA0; 默认串行数据mosi数据的建立时间和保持时间均为2个clk(0.5*DIV_FREQUENCY)周期即sck上升沿的前后2个(0.5*DIV_FREQUENCY)clk数据稳定,串行时钟sck周期为4*clk(DIV_FREQUENCY)的周期; 默认tSLCH(cs_n拉低到sck高的时间为6*clk(1.5*DIV_FREQUENCY)周期)tCHSH(sck高到cs_n拉高的时间为2*clk(0.5*DIV_FREQUENCY)周期); 若时序满足此模块可以不做修改。若需要修改在外部例化时修改DIV_FREQUENCY(只能偶分频)和PERIOD_WIDTH_MAX即可。 使用方法 输入data的位宽和计数器位宽在外部进行例化时修改参数的值即可不必修改SPI模块 DATA_WIDTH_MAX修改为输入数据的位宽如[31:0]的数据则DATA_WIDTH_MAX32 CNT_DATA_WIDTH_MAX修改为输入数据的位宽计数器需要的位宽上限即DATA_WIDTH_MAX32对应的二进制位宽326’b10_0000,所以CNT_DATA_WIDTH_MAX6 输入输出端口说明 //input input wire clk , //系统时钟,spi串行时钟的分频基准 input wire clr_n , //spi信号标志信号允许发送时一直拉高,重新发送时拉低复位再拉高 input wire [DATA_WIDTH_MAX-1:0] data , //需要data与clr_n一同进入 //output
output reg cs_n , //片选信号 output reg sck , //串行时钟 output reg mosi , //主输出从输入数据 output reg flag //spi发送完成标志位完成则一直拉高clr_n置0时拉低例化模板 spi #( .DATA_WIDTH_MAX (8 ), .CNT_DATA_WIDTH_MAX (4 ) ) u_spi(.clk (clk ),.clr_n (clr_n ),.data (data_in ),.cs_n (cs_n ),.sck (sck ),.mosi (mosi ),.flag (flag ) ); SPI模块 // // module_name.v :spi.v // Author :YprgDay // Description :用于将任意宽度向量型数据转换为SPI串行输出模式0CPOL 0CPHA0。 // module spi#(// Parameter parameter DATA_WIDTH_MAX 32 ,//例化时修改为输入数据的位宽如[31:0]的数据则DATA_WIDTH_MAX 32parameter CNT_DATA_WIDTH_MAX 6 ,//例化时修改为输入数据的位宽计数器需要的位宽上限即DATA_WIDTH_MAX32对应的二进制位宽326b10_0000,所以CNT_DATA_WIDTH_MAX6parameter DIV_FREQUENCY 4 ,//分频数(只允许偶分频)串行时钟sck周期为DIV_FREQUENCY*clk的周期parameter PERIOD_WIDTH_MAX 2 ,//(DIV_FREQUENCY-1)对应的二进制位宽即为PERIOD_WIDTH_MAXparameter CNT_PERIOD_MAX DIV_FREQUENCY-1 ,parameter CNT_HALF_PERIOD_MAX CNT_PERIOD_MAX 1 //计数分频中值 ) (// Port Name //inputinput wire clk , //系统时钟,spi串行时钟的分频基准 input wire clr_n , //spi信号标志信号允许发送时一直拉高,重新发送时拉低复位再拉高 input wire [DATA_WIDTH_MAX-1:0] data , //需要data与clr_n一同进入 //output output reg cs_n , //片选信号output reg sck , //串行时钟output reg mosi , //主输出从输入数据output reg flag //spi发送完成标志位完成则一直拉高clr_n置0时拉低);// Always block reg [CNT_DATA_WIDTH_MAX-1:0] cnt_data_width ;reg [PERIOD_WIDTH_MAX-1:0] cnt_spi_period ;reg [DATA_WIDTH_MAX-1:0] data_reg ;//输出的cs_n片选信号always (posedge clk or negedge clr_n)beginif(clr_n 1b0)begincs_n 1b1;endelse if(cnt_data_width DATA_WIDTH_MAX cnt_spi_period CNT_PERIOD_MAX)begincs_n 1b1;endelse begincs_n 1b0;endend //输出的sck串行时钟信号always (posedge clk or negedge clr_n)beginif(clr_n 1b0)beginsck 0;endelse if(cnt_data_width 0 cnt_spi_period CNT_PERIOD_MAX)beginsck 0;endelse if(cnt_data_width 0 cnt_spi_period CNT_HALF_PERIOD_MAX)beginsck 1;endelse beginsck sck;endend//mosi的串行输出always (posedge clk or negedge clr_n)beginif(clr_n 1b0)beginmosi 0;endelse if(cnt_data_width DATA_WIDTH_MAX cnt_spi_period CNT_PERIOD_MAX)beginmosi 0;endelse if(cnt_spi_period CNT_PERIOD_MAX)beginmosi data_reg[DATA_WIDTH_MAX-1-cnt_data_width];endelse beginmosi mosi;endend //输出的串行数据发送完成标志信号发送完成即拉高always (posedge clk or negedge clr_n)beginif(clr_n 1b0)beginflag 0;endelse if(cnt_data_width DATA_WIDTH_MAX cnt_spi_period CNT_PERIOD_MAX)beginflag 1;endelse beginflag 0;endend//输入数据寄存保证data在一串SPI数据发完之间不发生变化always (posedge clk or negedge clr_n)beginif(clr_n 1b0)begindata_reg 0;endelse if(cnt_data_width 0 cnt_spi_period 1)begindata_reg data;endelse begindata_reg data_reg;endend//时钟四分频计数always (posedge clk or negedge clr_n)beginif(clr_n 1b0)begincnt_spi_period 0;endelse if(cnt_data_width DATA_WIDTH_MAX cnt_spi_period CNT_PERIOD_MAX)begincnt_spi_period cnt_spi_period;endelse if(cnt_spi_period CNT_PERIOD_MAX)begincnt_spi_period 0;endelse if(cs_n 0)begincnt_spi_period cnt_spi_period 1b1;endelse;end //计数表示此时输出到[DATA_WIDTH_MAX:0] data的第几位位置always (posedge clk or negedge clr_n)beginif(clr_n 1b0)begincnt_data_width 0;endelse if(cnt_data_width DATA_WIDTH_MAX cnt_spi_period CNT_PERIOD_MAX)begincnt_data_width cnt_data_width;endelse if(cnt_spi_period CNT_PERIOD_MAX)begincnt_data_width cnt_data_width 1b1;endelse;endendmodule仿真模块 timescale 1ns / 1ps // // Module Name: tb_spi // Dependencies: spi模块仿真 // module tb_spi();// Parameter parameter SPI_CLK_PERIOD 2 ;//设置spi时钟信号周期parameter HALF_SPI_CLK_PERIOD SPI_CLK_PERIOD/2;//生成spi时钟信号半周期// Port Name //inputreg clk ;reg clr_n ;reg [7:0] data_in ;//outputwire mosi ;wire cs_n ;wire sck ;wire flag ;// Clock block always #HALF_SPI_CLK_PERIOD clk ~clk ;// Reset block initial beginclk 1b1 ;clr_n 1b0 ;data_in 0 ;#HALF_SPI_CLK_PERIODclr_n 1b1 ;data_in 8h83 ;#30data_in 8h54 ;#300clr_n 1b0 ;data_in 8hc7 ;#10clr_n 1b1 ;end// Module Instance spi #(.DATA_WIDTH_MAX (8 ),.CNT_DATA_WIDTH_MAX (4 ) )u_spi(.clk (clk ),.clr_n (clr_n ),.data (data_in ),.cs_n (cs_n ),.sck (sck ),.mosi (mosi ),.flag (flag )); endmodule仿真时序图 以8位输入数据[7:0]data的SPI时序图为例