当前位置:网站首页>数字ic设计——SPI
数字ic设计——SPI
2022-07-07 11:26:00 【桐桐花】
SPI总线概念
SPI ( Serial Peripheral Interface,串行外围设备接口)是一种同步、全双工、主从式,高速接口(UART是异步)。
来自主机或 从机 的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据。
串行外设接口(SPI)应用:
串行外设接口(SPI)是微控制器和外围IC(如传感器、ADC、DAC、移位寄存器、SRAM等)之间使用最广泛的接口之一。
SPI总线具有以下特点:
- 连线较少,简化电路设计。并行总线扩展方法通常需要8根数据线、8~16根地址线、2~3根控制线。而这种设计,仅需4根数据和控制线即可完成并行扩展所实现的功能。
- 器件统一编址,并与系统地址无关,操作SPI独立性好。
- 器件操作遵循统一的规范,使系统软硬件具有良好的通用性。
SPI总线的系统构架
SPI是一个环形总线结构,由SS(CS)、SCK、MOSI、MISO构成,主要是在SCK的控制下,两个双向移位寄存器进行数据交换。
SPI信号:
- 时钟((Serial Clock,SCK)SPI CLK,SCLK):产生时钟信号的器件称为主机。
- 片选信号(外围设备片选信号线(Slave Selection,SS)CS): 从机使能信号,由主机控制。。来自主机的片选信号用于选择从机。(这通常是一个低电平有效信号,拉高时从机与SPI总线断开连接。当使用多个从机时,主机需要为每个从机提供单独的片选信号。)
- 主机输出、从机输入((Master Out Slave In,MOSI)MOSI):数据线,将数据从主机发送到从机。
- 主机输入、从机输出((Master In Slave Out,MISO)MISO):数据线,将数据从从机发送到主机。
主机和从机之间的关系:
- 主机和从机之间传输的数据与主机产生的时钟同步。
- SPI接口只能有一个主机,但可以有一个或多个从机。
SPI数据传输
SPI数据的传输是在串行同步时钟信号(Serial Clock,SCK)的控制下进行的。
SPI怎么保证同步:
主机的时钟发生器一方面控制主机的移位寄存器,另一方面通过从机的SCK信号线来控制从机的移位寄存器,从而保证主机与从机的数据交换是同步进行的。
SPI开始通信
主机发送时钟信号。
主机通过使能片选信号CS(低电平有效)选择从机。
SPI通信期间
SPI总线的主机和从机都有一个移位寄存器。
当主机向自己的移位寄存器写入数据时,数据会通过MOSI信号线进入到从机的移位寄存器;
同时,
从机移位寄存器里的数据,通过MISO信号线进入到主机的移位寄存器。
这样,主机和从机就完成了一次数据交换。
注意:
SPI是全双工接口,主机和从机可以分别通过MOSI和MISO线路同时发送数据。【数据的发送(串行移出到MOSI/SDO总线上)和接收(采样或读入总线(MISO/SDI)上的数据)同时进行。】
串行时钟沿 同步 数据的移位和采样。
SPI接口允许用户灵活选择时钟的上升沿或下降沿来采样和/或移位数据。
四种SPI模式
时钟相位(CPHA)和时钟极性(CPOL)
SPI串行同步时钟可以设置为不同的极性(Clock Polarity ,CPOL)与相位(Clock Phase ,CPHA)。
时钟的极性(CPOL)
用来决定在总线空闲时,同步时钟(SCK)信号线上的电位是高电平还是低电平。
- 当时钟极性为0时(CPOL=0),SCK信号线在空闲时为低电平
- 当时钟极性为1时(CPOL=1),SCK信号线在空闲时为高电平
空闲状态:
传输开始时CS为高电平且在向低电平转变的期间,
传输结束时CS为低电平且在向高电平转变的期间。
时钟的相位(CPHA)
读取数据和发送数据的时钟沿(上升沿还是下降沿)。
CPHA=1(在SCK信号线的第二个跳变沿进行采样 )
- 当时钟极性为0时(CPOL=0),取下降沿
- 当时钟极性为1时(CPOL=1),取上升沿
CPHA=0(在SCK信号线的第一个跳变沿进行采样)
- 当时钟极性为0时(CPOL=0),取上升沿
- 当时钟极性为1时(CPOL=1),取下降沿
四种SPI模式
主机必须根据从机的要求选择时钟极性和时钟相位。
根据CPOL和CPHA位的选择,有四种SPI模式可用。
SPI模式 | CPOL | CPHA | 空闲状态下时钟极性 | 用于采样和/或移动数据的时钟相位 |
0 | 0 | 0 | 逻辑低电平 | 上升沿采样,下降沿移出 |
1 | 0 | 1 | 逻辑低电平 | 下降沿采样,上升沿移出 |
2 | 1 | 0 | 逻辑高电平 | 下降沿采样,上升沿移出 |
3 | 1 | 1 | 逻辑高电平 | 下降沿采样,上升沿移出 |
Mode0:CPOL= 0,CPHA = 0:(在SCK信号线的第一个跳变沿进行采样 )
CPOL =0 :
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
CPHA =0:
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
MODE0的传输时序:
Mode1:CPOL = 0,CPHA = 1:(在SCK信号线的第二个跳变沿进行采样 )
CPOL =0 :
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
CPHA =1:
在第二个时钟沿(上升沿)采样数据,
在第一个时钟沿(下降沿)输出数据。
MODE1的传输时序:
Mode2:CPOL= 1,CPHA = 0:(在SCK信号线的第一个跳变沿进行采样 )
CPOL =1:
时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)
CPHA =0:
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
MODE2的传输时序:
Mode3:CPOL = 1,CPHA = 1:(在SCK信号线的第二个跳变沿进行采样 )
CPOL =1:
时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)
CPHA =1:
在第二个时钟沿(上升沿)采样数据,
在第一个时钟沿(下降沿)输出数据。
MODE3的传输时序:
SPI时序
设上升沿发送、下降沿接收、高位先发送。
※时钟极性和时钟相位两种选择:
- CPHA = 0,CPOL = 1
- CPHA = 1,CPOL = 0
※根据片选信号CS选择从机
※SPI时序
主机和从机初始化就绪
主机寄存器=0xaa=10101010
从机寄存器=0x55 =01010101
第一个上升沿来的时候
MOSI=1;主机寄存器=0101010x
MISO=0;从机寄存器=1010101x
第一个下降沿到来的时候
MOSI传递到从机寄存器中,从机寄存器=0101010MOSI=01010101
MISO传递到主机寄存器中,主机寄存器=0101010MISO=01010100
8个时钟脉冲以后,两个寄存器的内容互相交换一次。
主机寄存器=01010101
从机寄存器=10101010
这样就完成里一个SPI时序。
根据以上分析,一个完整的传送周期是16位,即两个字节。
解释:
主机先发送命令过去,然后从机根据主机的名准备数据,
主机在下一个8位时钟周期才把数据读回来
脉冲 | 主机寄存器master buffer | 从机slave buffer | MISO | MOSI |
0 | 10101010 | 01010101 | 0 | 0 |
第1个脉冲上升沿(发送) | 0101010x | 1010101x | 0 | 1 |
第1个脉冲下降沿(接收) | 01010100 | 10101011 | 0 | 1 |
第2个脉冲上升沿(发送) | 1010100x | 0101011x | 1 | 0 |
第2个脉冲下降沿(接收) | 10101001 | 01010110 | 1 | 0 |
第3个脉冲上升沿(发送) | 0101001x | 1010110x | 0 | 1 |
第3个脉冲下降沿(接收) | 01010010 | 10101101 | 0 | 1 |
第4个脉冲上升沿(发送) | 1010010x | 0101101x | 1 | 0 |
第4个脉冲下降沿(接收) | 10100101 | 01011010 | 1 | 0 |
第5个脉冲上升沿(发送) | 0100101x | 1011010x | 0 | 1 |
第5个脉冲下降沿(接收) | 01001010 | 10110101 | 0 | 1 |
第6个脉冲上升沿(发送) | 1001010x | 0110101x | 1 | 0 |
第6个脉冲下降沿(接收) | 10010101 | 01101010 | 1 | 0 |
第7个脉冲上升沿(发送) | 0010101x | 1101010x | 0 | 1 |
第7个脉冲下降沿(接收) | 00101010 | 11010101 | 0 | 1 |
第8个脉冲上升沿(发送) | 0101010x | 1010101x | 1 | 0 |
第8个脉冲下降沿(接收) | 01010101 | 10101010 | 1 | 0 |
SPI功能模块的设计
SPI的主、从设备内部均为一个8位的移位寄存器。
实际实现时,可以利用主机的Sclk信号作为移位时钟信号,按照高位在前,低位在后的顺序,依次将总线上的数据送入内部移位寄存器中,从而完成SPI的接收与发送。
design spec
1. SCLK采用10MHz
2.模块工作时钟100MHz
3.当接收到的串行数据做串并转换,将并行数据反馈给上一级模块
4、采用 CPOL = 0 ,CPHA = 1
CPOL =0 :
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
CPHA =1:
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
SPI的SCLK信号的生成
模块时钟CLK,频率F=100MHz , 时钟周期 =10ns
SCLK, 频率f=10MHz , 时钟周期 =100ns (10分频)
//模块时钟:clk
//spi时钟:sclk
//复位信号:rst_n
//计数时钟个数的计数器:clk_cnt
//CPOL =0 (时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平))
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_cnt<=0;
sclk<=0;
else
begin
//(10分频/2-1)
if(clk_cnt==4'd4)
begin
sclk<=~sclk;
clk_cnt<=0;
end
else
begin
clk_cnt<=clk_cnt+1;
end
end
master同时的采样和输出
//master发送数据
[email protected](negedge sclk or negedge rst_n)
begin
if(!rst_n)
mosi<=1'b1;
else if(spi_done)
mosi<=1'b1;
else(!sclk&&!cs)
begin
mosi<=master_buf[7];
end
end
//master接收数据
[email protected](posedge sclk or negedge rst_n)
begin
if(!rst_n)
master_buf[7:0]<=8'b0;
else if(spi_done)
master_buf[7:0]<=8'b0;
else(!sclk&&!cs)
begin
master_buf[7:0]<={master_buf[6:0],miso};
end
end
slave同时的采样和输出
//slave发送数据
[email protected](negedge sclk or negedge rst_n)
begin
if(!rst_n)
miso<=slave_buf[0];
else if(spi_done)
miso<=slave_buf[0];
else(!sclk&&!cs)
begin
miso<=slave_buf[7];
end
end
//slave接收数据
[email protected](posedge sclk or negedge rst_n)
begin
if(!rst_n)
slave_buf[7:0]<=8'b0;
else if(spi_done)
slave_buf[7:0]<=8'b0;
else(!sclk&&!cs)
begin
slave_buf[7:0]<={slave_buf[6:0],mosi};
end
end
参考:
边栏推荐
猜你喜欢
分布式事务解决方案
Aosikang biological sprint scientific innovation board of Hillhouse Investment: annual revenue of 450million yuan, lost cooperation with kangxinuo
ESP32 ① 编译环境
Awk of three swordsmen in text processing
[learning notes] zkw segment tree
MongoDB内部的存储原理
[untitled]
Vscade editor esp32 header file wavy line does not jump completely solved
ESP32构解工程添加组件
Blog recommendation | Apache pulsar cross regional replication scheme selection practice
随机推荐
Test next summary
【Presto Profile系列】Timeline使用
达晨与小米投的凌云光上市:市值153亿 为机器植入眼睛和大脑
关于 appium 如何关闭 app (已解决)
HZOJ #235. Recursive implementation of exponential enumeration
记一次 .NET 某新能源系统 线程疯涨 分析
Aosikang biological sprint scientific innovation board of Hillhouse Investment: annual revenue of 450million yuan, lost cooperation with kangxinuo
Unity 构建错误:当前上下文中不存在名称“EditorUtility”
Practical case: using MYCAT to realize read-write separation of MySQL
我那“不好惹”的00后下属:不差钱,怼领导,抵制加班
解决缓存击穿问题
《开源圆桌派》第十一期“冰与火之歌”——如何平衡开源与安全间的天然矛盾?
Practical example of propeller easydl: automatic scratch recognition of industrial parts
Query whether a field has an index with MySQL
[QNX Hypervisor 2.2用户手册]6.3.4 虚拟寄存器(guest_shm.h)
信号强度(RSSI)知识整理
PACP学习笔记三:PCAP方法说明
Vscode编辑器ESP32头文件波浪线不跳转彻底解决
test
PAcP learning note 1: programming with pcap