历史上的今天
今天是:2024年08月30日(星期五)
2019年08月30日 | S5PV210开发 -- SPI 你知道多少?
2019-08-30 来源:eefocus
一、SPI简介
参看:SPI详解
SPI(serial peripheral interface,串行外围设备接口)总线技术是 Motorola 公司推出的一种同步串行接口。它用于CPU与各种外围器件进行全双工、同步串行通讯。它只需四条线就可以完成 MCU 与各种外围器件的通讯,这四条线是:串行时钟线(CSK)、主机输入->从机输出数据线(MISO)、主机输出<-从机输入数据线(MOSI)、低电平有效从机选择线CS。当SPI工作时,在移位寄存器中的数据逐位从输出引脚(MOSI)输出(高位在前),同时从输入引脚(MISO)接收的数据逐位移到移位寄存器(高位在前)。发送一个字节后,从另一个外围器件接收的字节数据进入移位寄存器中。即完成一个字节数据传输的实质是两个器件寄存器内容的交换。主SPI的时钟信号(SCK)使传输同步。

二、SPI 主、从硬件连接图
参看:SPI -- 维基百科
SPI是用来跟各种外设,如:
传感器:温度,压力,ADC,触摸屏,视频游戏控制器
控制设备:音频编解码器,数字电位器,DAC
相机镜头:佳能EF镜头卡口
通讯:以太网,USB,USART,CAN,IEEE 802.15.4,IEEE 802.11,手持视频游戏
内存:闪存和EEPROM
实时时钟
LCD,有时甚至用于管理的图像数据
任何MMC或SD卡(包括SDIO变体[6] )
对于高性能系统中,FPGA中有时使用SPI接口作为从一台主机,作为主传感器,或用于用于引导如果它们是基于SRAM的闪存。
查看芯片手册和原理图 DM368 有 5 组 SPI 总线,每组 3 个片选;Hi3516A 有 2 组 SPI 总线,每组 3 个片选。


SPI总线一个主机接多个从机连接方法:
典型的SPI总线:主站和三个独立的从站
在独立从配置,存在用于每个从一个独立的片选线。电源和芯片选择线之间的上拉电阻强烈建议为每个独立的装置,以减少设备之间的串扰。[3]这是通常使用SPI的方式。因为从站的MISO引脚连接在一起时,它们需要是三态销(高,低或高阻抗)。

菊花链式SPI总线:主站和协同从站
实现SPI一些产品可在被连接的菊花链配置中,第一从输出被连接到第二从输入等每个从属的SPI端口被设计第二组时钟的过程中发出脉冲的精确副本数据它的第一组时钟脉冲的期间接收到的。整个链充当通信移位寄存器 ; 菊花链通常与移位寄存器完成通过SPI提供的输入或输出的银行。这种特征仅需要从主,而不是为每个从一个单独的SS线的单个SS线。可以与SPI需要菊花链配置潜在互操作的其它应用包括SGPIO,JTAG,[5]和双线接口。

三、SPI 四种工作模式
(1)工作模式
SPI 有四种工作模式,各个工作模式的不同在于 SCLK 不同, 具体工作由 CPOL,CPHA 决定。
CPOL: (Clock Polarity),时钟极性:
当CPOL为0时,时钟空闲时电平为低;
当CPOL为1时,时钟空闲时电平为高;
CPHA:(Clock Phase),时钟相位:
当CPHA为0时,时钟周期的上升沿采集数据,时钟周期的下降沿输出数据;
当CPHA为1时,时钟周期的下降沿采集数据,时钟周期的上升沿输出数据;
CPOL和CPHA,分别都可以是0或时1,对应了四种组合。
四种工作方式时序分别为:

(2)辨识技巧
上面讲到了有四种工作模式,该如何确认自己的设备使用的是哪种工作模式呢?
以GV7601SDI 解码芯片为例:
参看:GV7601 SDI解码芯片DATASHEET
参看:Hi3516A开发--GV7601 硬件设计
1、先确认从机需求的 SCLK 极性,不工作时是在低电位还是高电位,由此确认 CPOL 为 0 或 1

时钟空闲时电平为低,得出:CPOL 为 0
2、再由slave芯片 datasheet 中的时序图确认 slave 芯片是在 SCLK 的下降沿采集数据,还是在SCLK的上升沿

翻译一下:
在读取序列(命令字R / W位设置为高电平)期间,将传输串行数据或先接收MSB,与串行时钟SCLK的上升沿同步。芯片选择(CS)信号必须在第一个之前设置为低至少1.5ns(图4-62中的t0)时钟边缘以确保正确的操作。串行输出(SDOUT)的第一位(MSB)在读命令的最后一个下降SCLK沿之后是可用的(图4-63中的t5)字,剩余的位在SCLK的负边沿输出。
注意:当多个设备连接到GSPI链时,只能有一个CS在读取序列期间被断言。
在写序列(命令字R / W位设置为低电平)期间,等待状态为37.1ns(t4 in命令字和以下数据字之间需要图4-62)。这个在连续的命令字/数据字之间也必须保持等待状态写序列。当选择自动增量模式(AutoInc = 1)时,等待状态必须在初始命令之后的连续数据字之间保持字/数据字序列。在写序列期间,所有命令和随后的数据字输入到SDIN引脚输出在SDOUT引脚不变。当几个设备连接到GSPI链,数据可以同时写入所有CS设备低。

得出:CPHA为 0
四、优缺点
优点[ 编辑]
在这个协议的默认版本全双工通信。
推挽式驱动器(而不是开漏)提供良好的信号完整性和高速
更高的吞吐量比I²C或SMBus的。不限于任何最大时钟速度,从而使潜在的高速
完整的协议的灵活性传输的比特
不限于8位字
邮件大小,内容和目的任意选择
极其简单的硬件接口
通常较低的功率要求I²C或SMBus由于较少的电路(包括上拉电阻)
没有仲裁或相关的故障模式
从器件使用主时钟,不需要精密振荡器
奴隶并不需要一个唯一的地址 -不像I²C或GPIB或SCSI
不需要收发器
仅使用4上的IC封装引脚,和电线中的电路板布局或连接器,比并行接口少得多的
在每个装置最多一个唯一的总线信号(芯片选择); 所有其他人共享
信号单向允许简单的电隔离
简单的软件实现
缺点[ 编辑]
需要在IC封装大于销I²C,即使是在三线变种
没有带寻址; 外的带芯片选择信号需要在共享总线
没有硬件流量控制由从属(但主机可以延迟下一个时钟边沿以减慢传输速率)
没有硬件从确认(主可以传输到任何地方和不知道它)
通常只支持一个主设备(取决于设备的硬件实现)
没有错误检查协议被定义
如果没有一个正式的标准,验证一致性是不可能的
相比仅处理短距离RS-232,RS-485,或CAN总线。(其距离可以使用收发器等来扩展RS-422)
许多现有的变化,因此很难找到发展的工具,如支持这些变化的主机适配器
SPI不支持热插拔(动态添加节点)。
中断必须要么与出的带外信号来实现,或通过使用定期轮询类似于USB 1.1和2.0可以伪造
像一些变体多I / O SPI和三线串行总线定义见下文是半双工。
五、单片机上 SPI 通信
参看:单片机软件模拟SPI接口—加深理解SPI总线协议
参看:Coding SPI software
参看:SOFTWARE SPI EXAMPLES FOR THE C8051F30X FAMILY
//-----------------------------------------------------------------------------
// SPI_defs.h
//-----------------------------------------------------------------------------
// Copyright 2001 Cygnal Integrated Products, Inc.
//
// AUTH: BD
// DATE: 7 DEC 01
//
// This file defines the pins used for the SPI device.
// The SPI device is mapped to pins P0.0 - P0.3, but can be modified to map to
// any of the available GPIO pins on the device.
//
#ifndef SPI_DEFS
#define SPI_DEFS
sbit MOSI = P0^0; // Master Out / Slave In (output)
sbit MISO = P0^1; // Master In / Slave Out (input)
sbit SCK = P0^2; // Serial Clock (output)
sbit NSS = P0^3; // Slave Select (output to chip select)
#endif
工作模式为:(0,0)
//-----------------------------------------------------------------------------
// SPI_MODE0.c
//-----------------------------------------------------------------------------
// Copyright 2001 Cygnal Integrated Products, Inc.
//
// AUTH: BD
// DATE: 14 DEC 01
//
// This file contains a ‘C’ Implementation of a Mode 0 Master SPI device.
//
// Target: C8051F30x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
//
#include #include “SPI_defs.h” // SPI port definitions //----------------------------------------------------------------------------- // SPI_Transfer //----------------------------------------------------------------------------- // // Simultaneously transmits and receives one byte // the SPI protocol. SCK is idle-low, and bits are latched on SCK rising. // // Timing for this routine is as follows: // // Parameter Clock Cycles // MOSI valid to SCK rising edge 6 // SCK rising to MISO latched 2 // SCK falling to MOSI valid 7 // SCK high time 8 // SCK low time 13 char SPI_Transfer (char SPI_byte) { unsigned char SPI_count; // counter for SPI transaction for (SPI_count = 8; SPI_count > 0; SPI_count--) // single byte SPI loop { MOSI = SPI_byte & 0x80; // put current outgoing bit on MOSI SPI_byte = SPI_byte << 1; // shift next bit into MSB SCK = 0x01; // set SCK high SPI_byte |= MISO; // capture current bit on MISO SCK = 0x00; // set SCK low } return (SPI_byte); } // END SPI_Transfer 工作模式为(0,1) // Copyright 2001 Cygnal Integrated Products, Inc. // // AUTH: BD // DATE: 14 DEC 01 // // This file contains a ‘C’ Implementation of a Mode 1 Master SPI device. // // Target: C8051F30x // Tool chain: KEIL C51 6.03 / KEIL EVAL C51 // // #include #include “SPI_defs.h” // SPI port definitions //----------------------------------------------------------------------------- // SPI_Transfer //----------------------------------------------------------------------------- // // Simultaneously transmits and receives one byte // the SPI protocol. SCK is idle-low, and bits are latched on SCK falling. // // Timing for this routine is as follows: // // Parameter Clock Cycles // SCK rising edge to MOSI valid 4 // MOSI valid to SCK falling edge 6 // SCK falling to MISO latch 2 // SCK high time 10 // SCK low time 11 char SPI_Transfer (char SPI_byte) { unsigned char SPI_count; // counter for SPI transaction for (SPI_count = 8; SPI_count > 0; SPI_count--) // single byte SPI loop { SCK = 0x01; // set SCK high MOSI = SPI_byte & 0x80; // put current outgoing bit on MOSI SPI_byte = SPI_byte << 1; // shift next bit into MSB SCK = 0x00; // set SCK low SPI_byte |= MISO; // capture current bit on MISO } return (SPI_byte); } // END SPI_Transfer 工作模式为(1,0) // Copyright 2001 Cygnal Integrated Products, Inc. // // AUTH: BD // DATE: 14 DEC 01 // // This file contains a ‘C’ Implementation of a Mode 2 Master SPI device. // // Target: C8051F30x // Tool chain: KEIL C51 6.03 / KEIL EVAL C51 // // #include #include “SPI_defs.h” // SPI port definitions //----------------------------------------------------------------------------- // SPI_Transfer //----------------------------------------------------------------------------- // // Simultaneously transmits and receives one byte // the SPI protocol. SCK is idle-high, and bits are latched on SCK falling. // // Timing for this routine is as follows: // // Parameter Clock Cycles // MOSI valid to SCK falling edge 6 // SCK falling to MISO latched 2 // SCK rising to MOSI valid 7 // SCK low time 8 // SCK high time 13 char SPI_Transfer (char SPI_byte) { unsigned char SPI_count; // counter for SPI transaction for (SPI_count = 8; SPI_count > 0; SPI_count--) // single byte SPI loop { MOSI = SPI_byte & 0x80; // put current outgoing bit on MOSI SPI_byte = SPI_byte << 1; // shift next bit into MSB SCK = 0x00; // set SCK low SPI_byte |= MISO; // capture current bit on MISO SCK = 0x01; // set SCK high } return (SPI_byte); } // END SPI_Transfer 工作模式为(1,1) // Copyright 2001 Cygnal Integrated Products, Inc. // // AUTH: BD // DATE: 14 DEC 01 // // This file contains a ‘C’ Implementation of a Mode 3 Master SPI device. // // Target: C8051F30x // Tool chain: KEIL C51 6.03 / KEIL EVAL C51 // // #include #include “SPI_defs.h” // SPI port definitions //----------------------------------------------------------------------------- // SPI_Transfer //----------------------------------------------------------------------------- // // Simultaneously transmits and receives one byte // the SPI protocol. SCK is idle-high, and bits are latched on SCK rising. // // Timing for this routine is as follows: // // Parameter Clock Cycles // SCK falling edge to MOSI valid 4 // MOSI valid to SCK rising edge 6 // SCK rising to MISO latch 2 // SCK low time 10 // SCK high time 11 char SPI_Transfer (char SPI_byte) { unsigned char SPI_count; // counter for SPI transaction for (SPI_count = 8; SPI_count > 0; SPI_count--) // single byte SPI loop { SCK = 0x00; // set SCK low MOSI = SPI_byte & 0x80; // put current outgoing bit on MOSI SPI_byte = SPI_byte << 1; // shift next bit into MSB SCK = 0x01; // set SCK high SPI_byte |= MISO; // capture current bit on MISO } return (SPI_byte); } // END SPI_Transfer 测试程序: //----------------------------------------------------------------------------- // SPI_F300_Test.c //----------------------------------------------------------------------------- // Copyright 2001 Cygnal Integrated Products, Inc. // // AUTH: BD // DATE: 14 DEC 01 // // This program demonstrates how a collection of SPI master // routines for the 8051F30x processors can be used in a C program. // // This program sets up the GPIO pins on the C8051F30x device for the correct // functionality, then uses the SPI_Transfer function to send and receive // information through the SPI pins. As information is sent, the progress of // the program is sent out through the UART to be monitored on a connected // terminal program. // // For this code to be functional, *one* of the following files should also be // compiled or assembled, and the resulting object file must be linked to the // object file produced from this file: // // SPI_MODE0.c Mode 0 SPI Master Implementation in C
史海拾趣
|
电解电容在电路板掉电了电容还是有300V电压。 用你的坏表笔中间串接一个30K的电阻,修板子时先把大电容的电放了就可以了,不然就会有 你的教训。没大电容的话直接用手放也不错。 电容容量大了放电慢 有些电路的放电电阻很大,电解电容放电需几 ...… 查看全部问答> |
|
我用C# 和 C++ 写的socket客户端程序在wince运行,为什么连到了服务器端,新上线的客户端会让以前上线的客户端丢失连接。服务器已经改用c#和java来做,问题都一样。 但是把socket客户端程序放在不同PC机上取正常,如果在一个wince运行多个socket客 ...… 查看全部问答> |
|
各位老师,大家好: 我现在正在用TMS320F2812开发一套系统,由于先前设计系统时考虑的存储器不够,用的是CY7C1021,现在改为SST39VF800与61LV51216,发现系统load program 之后,如果直接go main 是到不了main 的;如果单步运行就可 ...… 查看全部问答> |
|
当我把R16接上的时候,即使把芯片MOC3041拔了,双向可控硅照样导通,说明此时可控硅已不受控制了。当不接R16时,即使P37给予低电位可控硅照样不导通。不知道时啥原因??请知道的说一下,谢谢!! [ 本帖最后由 farme 于 2011-4-8 16:40 编辑 ]… 查看全部问答> |
|
我根据下述步骤创建ram文件系统: char *ramDiskDevName = \"/ram0\" ; CBIO_DEV_ID cbio ; cbio = ramDiskDevCreate((unsigned char *)RAM_DISK_ADDRESS, 128, 1024* ...… 查看全部问答> |
|
我用mini2440的串口FIFO模式, 从电脑上的SSCOM32发来txt文件, 开发板上接收, 为什么最多只能收到255个字节, 一旦超过256就收不到了?但是如果发225k的bmp图片, 可以正常接收, 解析后可以显示。请高手解答啊。… 查看全部问答> |




