SPI总线概念
串行外设界面(SPI)是微控制器和外围IC(如传感器,ADC、DAC、移位寄存器、SRAM等)之间使用最广泛的界面之一。
- 连接较少,简化了电路设计。平行总线扩展方法通常需要8条数据线、8~16条地址线和2~3条控制线。这种设计只需要4条数据和控制线来实现平行扩展。
- 设备统一编址,与系统地址无关,操作SPI独立性好。
- 设备操作遵循统一规范,使系统软硬件具有良好的通用性。
SPI总线的系统构架
SPI由环形总线结构组成SS(CS)、SCK、MOSI、MISO构成,主要是在SCK数据交换由两个双向移位寄存器控制。
- (Serial Clock,SCK):产生时钟信号的装置称为主机。
- 选择外围设备片的信号线(Slave Selection,SS): 由主机控制的从机使能信号。。主机的片选信号用于选择从机。
- (Master Out Slave In,MOSI):将数据从主机发送到从机的数据线。
- (Master In Slave Out,MISO):将数据从从从从机发送到主机的数据线。
- 主机和从机之间传输的数据与主机产生的时钟同步。
- SPI接口只能有一个主机,但可以有一个或多个从机。
主机发送
主机使能低电平有效选择从机。
SPI总线的主机和从机都有移位寄存器。
当主机将数据写入移位寄存器时,数据将通过移位寄存器进入从机;
,
通过从机移位寄存器中的数据移位寄存器进入主机。
这样,主机和从机就完成了数据交换。
时钟相位(CPHA)和时钟极性(CPOL)
SPI串行同步时钟可以设置为不同的极性(Clock Polarity ,CPOL)与相位(Clock Phase ,CPHA)。
- 当时钟极性为0时,SCK信号线在为
- 当时钟极性为1时,SCK信号线在为
⭐
- 当时钟极性为时,取
- 当时钟极性为时,取
⭐
- 当时钟极性为时,取
- 当时钟极性为时,取
主机必须根据从机的要求选择时钟极性和时钟相位。
根据CPOL和CPHA位的选择,有四种SPI模式可用。
逻辑低电平 | 上升沿采样,下降沿移出 | |||
逻辑低电平 | 下降沿采样,上升沿移出 |
|||
逻辑高电平 | 下降沿采样,上升沿移出 | |||
逻辑高电平 | 下降沿采样,上升沿移出 |
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
在第二个时钟沿(上升沿)采样数据,
在第一个时钟沿(下降沿)输出数据。
时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)
在第二个时钟沿(上升沿)采样数据,
在第一个时钟沿(下降沿)输出数据。
SPI时序
主机寄存器=0xaa=10101010
从机寄存器=0x55 =01010101
;主机寄存器=0101010x
;从机寄存器=1010101x
MOSI传递到从机寄存器中,从机寄存器=0=0101010
MISO传递到主机寄存器中,主机寄存器==0101010
主机寄存器=01010101
从机寄存器=10101010
主机先发送命令过去,然后从机根据主机的名准备数据,
主机在下一个8位时钟周期才把数据读回来
脉冲 | 主机寄存器master buffer | 从机slave buffer | MISO | MOSI |
0 | 0101010 | 1010101 | 0 | 0 |
第1个脉冲上升沿(发送) | 0101010x | 1010101x | ||
第1个脉冲下降沿(接收) | 101010 | 010101 | 0 | 1 |
第2个脉冲上升沿(发送) | 101010x | 010101x | ||
第2个脉冲下降沿(接收) | 01010 | 10101 | 1 | 0 |
第3个脉冲上升沿(发送) | 01010x | 10101x | ||
第3个脉冲下降沿(接收) | 10100 | 0101 | 0 | 1 |
第4个脉冲上升沿(发送) | 1010010x | 0101x | ||
第4个脉冲下降沿(接收) | 010010 | 101 | 1 | 0 |
第5个脉冲上升沿(发送) | 010x | 101x | ||
第5个脉冲下降沿(接收) | 10 | 01 | 0 | 1 |
第6个脉冲上升沿(发送) | 10x | 01x | ||
第6个脉冲下降沿(接收) | 0 | 1 | 1 | 0 |
第7个脉冲上升沿(发送) | 0x | 1x | ||
第7个脉冲下降沿(接收) | 0 | 1 | ||
第8个脉冲上升沿(发送) | x | x | ||
第8个脉冲下降沿(接收) | 1 | 0 |
SPI功能模块的设计
SPI的主、从设备内部均为一个8位的移位寄存器。
实际实现时,可以利用主机的Sclk信号作为移位时钟信号,按照高位在前,低位在后的顺序,依次将总线上的数据送入内部移位寄存器中,从而完成SPI的接收与发送。
design spec
1. SCLK采用10MHz 2.模块工作时钟100MHz 3.当接收到的串行数据做串并转换,将并行数据反馈给上一级模块
4、采用 ,
时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)
在第一个时钟沿(上升沿)采样数据,
在第二个时钟沿(下降沿)输出数据。
//模块时钟:clk
//spi时钟:sclk
//复位信号:rst_n
//计数时钟个数的计数器:clk_cnt
//CPOL =0 (时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平))
always@(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发送数据
always@(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接收数据
always@(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发送数据
always@(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接收数据
always@(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
参考:
SPI接口简介 - 模拟/电源 - -EETOP-创芯网
【新提醒】SPI总线协议 - 霡霂的日志 - EETOP 创芯网论坛 (原名:电子顶级开发网) -
怎样理解SPI总线时钟的极性(COL)与相位(CPHA)? - 知乎 (zhihu.com)