设好时钟极性和时钟相位相位的条件下,spi是在同一跳变沿采样和输出的吗,还是在相邻的反向跳变沿?

博客访问: 1311168
博文数量: 350
博客积分: 4817
博客等级: 上校
技术积分: 4086
注册时间:
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
最近在看关于Silicon Labs的C的某个驱动中,关于SPI部分初始化的代码,看到其对于SPI的设置为CPOL=1,CPHA=0,对于CPOL及CPHA的含义不了解,想要搞懂,这两个参数到底是什么意思,以及为何要这么设置。所以才去找了SPI的极性和相位的相关资料,整理如下。
【SPI基础知识简介】
设备与设备之间通过某种硬件接口通讯,目前存在很多种接口,SPI接口是其中的一种。
SPI中分Master主设备和Slave从设备,数据发送都是由Master控制。
一个master可以接一个或多个slave。
常见用法是一个Master接一个slave,只需要4根线:
SCLK:Serial Clock,(串行)时钟
MISO:Master In Slave Out,主设备输入,从设备输出
MOSI:Master Out&&Slave In,主设备输出,从设备输入
SS:& && && & Slave Select,选中从设备,片选
SPI由于接口相对简单(只需要4根线),用途算是比较广泛,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。即一个SPI的Master通过SPI与一个从设备,即上述的那些Flash,ADC等,进行通讯。而主从设备之间通过SPI进行通讯,首先要保证两者之间时钟SCLK要一致,互相要商量好了,要匹配,否则,就没法正常通讯了,即保证时序上的一致才可正常讯。而这里的SPI中的时钟和相位,指的就是SCLk时钟的特性,即保证主从设备两者的时钟的特性一致了,以保证两者可以正常实现SPI通讯。
【SPI相关的缩写或说法】
先简单说一下,关于SPI中一些常见的说法:
SPI的极性Polarity和相位Phase,最常见的写法是CPOL和CPHA,不过也有一些其他写法,简单总结如下:
(1) CKPOL (Clock Polarity) = CPOL = POL = Polarity = (时钟)极性
(2) CKPHA (Clock Phase)& &= CPHA = PHA = Phase = (时钟)相位
(3) SCK=SCLK=SPI的时钟
(4) Edge=边沿,即时钟电平变化的时刻,即上升沿(rising edge)或者下降沿(falling edge)
对于一个时钟周期内,有两个edge,分别称为:
Leading edge=前一个边沿=第一个边沿,对于开始电压是1,那么就是1变成0的时候,对于开始电压是0,那么就是0变成1的时候;
Trailing edge=后一个边沿=第二个边沿,对于开始电压是1,那么就是0变成1的时候(即在第一次1变成0之后,才可能有后面的0变成1),对于开始电压是0,那么就是1变成0的时候;
本文采用如下用法:
第一个边沿和第二个边沿
【SPI的相位和极性】
CPOL和CPHA,分别都可以是0或时1,对应的四种组合就是:
CPOL=0, CPHA=0
CPOL=0, CPHA=1
CPOL=1, CPHA=0
CPOL=1, CPHA=1
单独看这张图,的确很难明白具体含义,所以下面会有更详细的解释。
【 CPOL极性】
先说什么是SCLK时钟的空闲时刻,其就是当SCLK在数发送8个bit比特数据之前和之后的状态,于此对应的,SCLK在发送数据的时候,就是正常的工作的时候,有效active的时刻了。
先说英文,其精简解释为:Clock Polarity = IDLE state of SCK。
再用中文详解:
SPI的CPOL,表示当SCLK空闲idle的时候,其电平的值是低电平0还是高电平1:
CPOL=0,时钟空闲idle时候的电平是低电平,所以当SCLK有效的时候,就是高电平,就是所谓的active-high;
CPOL=1,时钟空闲idle时候的电平是高电平,所以当SCLK有效的时候,就是低电平,就是所谓的active-low;
【 CPHA相位】
首先说明一点,capture strobe = latch = read = sample,都是表示数据采样,数据有效的时刻。
相位,对应着数据采样是在第几个边沿(edge),是第一个边沿还是第二个边沿,0对应着第一个边沿,1对应着第二个边沿。
CPHA=0,表示第一个边沿:
对于CPOL=0,idle时候的是低电平,第一个边沿就是从低变到高,所以是上升沿;
对于CPOL=1,idle时候的是高电平,第一个边沿就是从高变到低,所以是下降沿;
CPHA=1,表示第二个边沿:
对于CPOL=0,idle时候的是低电平,第二个边沿就是从高变到低,所以是下降沿;
对于CPOL=1,idle时候的是高电平,第一个边沿就是从低变到高,所以是上升沿;
用图文形式表示,更加容易看懂:
此处,再多解释一下可能会遇到的CKP和CKE,其是Microchip的PIC系列芯片中的说法。
(1)CKP是Clock Polarity Select,就是极性=CPOL:
CKP,虽然名字和CPOL不一样,但是都是指时钟相位的选择,定义也一样:
CKP: Clock Polarity Select bit
1 = Idle state for clock (CK) is a high level
0 = Idle state for clock (CK) is a low level
所以不多解释。
(2)CKE是Clock Edge Select,就是相位=CPHA:
CKE: SPI Clock Edge Select bit
1 = Transmit occurs on transition from active to Idle clock state
0 = Transmit occurs on transition from Idle to active clock state
1 =(数据)传输发生在时钟从有效状态转到空闲状态的那一时刻
0 =(数据)传输发生在时钟从空闲状态转到有效状态的那一时刻
其中,数据传输的时刻,即图中标出的“数据transmit传输的时刻”,很明显,该时刻是一个时钟和下一个时钟之间交界的地方,对应的不论是上升沿还是下降沿,都与我们前面提到的CPHA=数据采样的时刻,的边沿方向所相反。
所以,此处的CKE,正好与CPHA相反。
所以,CKP和CKE所对应的取值的含义为:
When CKP = 0:
CKE=1 => Data transmitted on rising edge of SCK
CKE=0 => Data transmitted on falling edge of SCK
When CKP = 1:
CKE=1 => Data transmitted on falling edge of SCK
CKE=0 => Data transmitted on rising edge of SCK
下面再列出其他一些地方找到的,常见的SPI的四种模式的时序图,供参考:
【如何看懂和记忆CPOL和CPHA】
所以,关于在其他地方介绍的,看似多么复杂难懂难记忆的CPOL和CPHA,其实经过上面解释,就肯容易看懂了:
去看时序图,如果起始的始终SCLK的电平是0,那么CPOL=0,如果是1,那么CPOL=1,
然后看数据采样时刻,即时序图数据线上的数据那个矩形区域的中间所对应的位置,对应到上面SCLK时钟的位置,对应着是第一个边沿或是第二个边沿,即CPHA是0或1。(对应的是上升沿还是还是下降沿,要根据对应的CPOL的值,才能确定)。
(1)如何判断CPOL:SCLK的空闲时候的电压,是0还是1,决定了CPOL是0还是1;
(2)如何判断CPHA:而数据采样时刻对应着的SCLK的电平,是第一个边沿还是第二个边沿,对应着CPHA为0还是1。
SCLK的极性,相位,边沿之间的内在逻辑关系
SCLK空闲时刻电压
数据采样时刻,SCLK的edge是第一个还是第二个
第一个边沿
上升沿(开始的电平是低电压0,而第一个边沿,只能是从0变到1,即上升沿)
第二个边沿
上升沿(开始电平是高电平1,第二个边沿,肯定是从低电平0变到高电平1,因为第一个边沿肯定是从高电平1,变到低电平0)
【软件中如何设置SPI的极性和相位】
SPI分主设备和从设备,两者通过SPI协议通讯。
而设置SPI的模式,是从设备的模式,决定了主设备的模式。
所以要先去搞懂从设备的SPI是何种模式,然后再将主设备的SPI的模式,设置和从设备相同的模式,即可正常通讯。
对于从设备的SPI是什么模式,有两种:
(1)固定的,有SPI从设备硬件决定的
SPI从设备,具体是什么模式,相关的datasheet中会有描述,需要自己去datasheet中找到相关的描述,即:
关于SPI从设备,在空闲的时候,是高电平还是低电平,即决定了CPOL是0还是1;
然后再找到关于设备是在上升沿还是下降沿去采样数据,这样就是,在定了CPOL的值的前提下,对应着可以推算出CPHA是0还是1了。
CC2500 - Low-Cost Low-Power 2.4 GHz RF Transceiver的datasheet中SPI的时序图是:
从图中可以看到,最开始的SCLK和结束时候的SCLK,即空闲时刻的SCLK,是低电平,推导出CPOL=0,然后可以看到数据采样的时候,即数据最中间的那一点,对应的是SCLK的第一个边沿,所以CPHA=0(此时对应的是上升沿)。
SSD1289 - 240 RGB x 320 TFT LCD Controller Driver的datasheet中提到:
“SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.”
意思是,数据是在上升沿采样,所以可以断定是CPOL=0,CPHA=0,或者CPOL=1,CPHA=1的模式,但是至于是哪种模式。
按理来说,接下来应该再去确定SCLK空闲时候是高电平还是低电平,用以确定CPOL是0还是1,但是datasheet中没有提到这点。
所以,此处,目前不太确定,是两种模式都支持,还是需要额外找证据却确定CPOL是0还是1.
(2)可配置的,由软件自己设定
从设备也是一个SPI控制器,4种模式都支持,此时只要自己设置为某种模式即可。
然后知道了从设备的模式后,再去将SPI主设备的模式,设置为和从设备模式一样,即可。
对于如何配置SPI的CPOL和CPHA的话,不多细说,多数都是直接去写对应的SPI控制器中对应寄存器中的CPOL和CPHA那两位,写0或写1即可。
此处遇到的C中的SPI就是一个SPI的controller控制器,即支持软件配置CPOL和CPHA的值,四种模式都支持,此处C作为SPI从设备,设置了CPOL=1,CPHA=0的模式,因此,此处对应主芯片Blackfin F537中的SPI控制器,作为Master主设备,其SPI的模式也要设置为CPOL=1,CPHA=0。
【待解决问题】
对于软件去如何设置主设备(和 从设备)的CPOL和CPHA的值,是搞懂了,知道两者要匹配才可以正常通讯,但是对于CPOL和CPHA这四种模式,不同的模式之间,相对来说有何优缺点,比如是否哪种模式更稳定,数据更不容易出错等等,还是不清楚,如果有懂行的,还请告知:green-waste (at)
1. IT方面的资料,国内的,还是把问题讲明白的太少,想搞懂问题,还是得去找英文的。
2.有问题, 指望别人,还是不行的,凡事还是得指望自己,才有用。
阅读(10404) | 评论(1) | 转发(8) |
相关热门文章
给主人留下些什么吧!~~
我认同要找英文资料,不过大哥可以教下你这个是在哪里找到的吗?授人以鱼不如授人以渔
请登录后评论。SPI时序详解
& & & & & & &SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。
& & & & & SPI总线有四种工作方式(SP0, SP1, SP2, SP3),其中使用的最为广泛的是SPI0和SPI3方式。SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果
CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。&
SPI主模块和与之通信的外设音时钟相位和极性应该一致。
& & & & &SPI时序详解---SPI接口在模式0下输出第一位数据的时刻SPI接口有四种不同的数据传输时序,取决于CPOL和CPHL这两位的组合。图1中表现了这四种时序,时序与CPOL、CPHL的关系也可以从图中看出。
& & & & & CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0,空闲电平为低电平,CPOL=1时,空闲电平为高电平。CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,CPHA=1,在每个周期的第二个时钟沿采样。由于我使用的器件工作在模式0这种时序(CPOL=0,CPHA=0),所以将图1简化为图2,只关注模式0的时序。
& & & & & 我们来关注SCK的第一个时钟周期,在时钟的前沿采样数据(上升沿,第一个时钟沿),在时钟的后沿输出数据(下降沿,第二个时钟沿)。首先来看主器件,主器件的输出口(MOSI)输出的数据bit1,在时钟的前沿被从器件采样,那主器件是在何时刻输出bit1的呢?bit1的输出时刻实际上在SCK信号有效以前,比SCK的上升沿还要早半个时钟周期。bit1的输出时刻与SSEL信号没有关系。再来看从器件,主器件的输入口MISO同样是在时钟的前沿采样从器件输出的bit1的,那从器件又是在何时刻输出bit1的呢。从器件是在SSEL信号有效后,立即输出bit1,尽管此时SCK信号还没有起效。
从这张图就可以很清楚的看出主从器件的bit1是怎样输出的
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6345次
排名:千里之外查看: 3485|回复: 10
请教下SPI双工数据传输函数。
各位大侠:
& && && && &&&想问下data = SPI.transfer(0XFF);这个函数,是否是同步发送一个0XFF,然后接收到一个值给data,不胜感激!!
因为我使用时,感觉只能收到值,无法发送数据。
你首先要搞清楚访问的寄存器是R/W,还是只能R。
如果只能R,你发送的是什么无所谓,接收的是选中寄存器的内容。
( nRF24L01说明书里一般把NOP定义为0XFF,用在读指令里面。)
leicheng 发表于
你首先要搞清楚访问的寄存器是R/W,还是只能R。
如果只能R,你发送的是什么无所谓,接收的是选中寄存器的内 ...
leicheng:想请教:我是将ARDUINO的SPI设成从机,从主机获取时钟,SPI.transfer();里的
while(!(SPSR & _BV(SPIF)));
reture SPDR;
这里的SPDR数据寄存器主从机也是按位交换的吗?不会出错?谢谢!
貌似你的出错了。请看看深海鱼的这篇文章:
本帖最后由 ps2xu 于
10:59 编辑
感觉能接收但发送不了数据的。请帮看下从机程序,好像数据有漏掉的感觉,因我没有示波仪,无法看出具体情况
本帖最后由 ps2xu 于
11:05 编辑
leicheng 发表于
貌似你的出错了。请看看深海鱼的这篇文章:两个Arduino之间进行SPI通信
感觉能接收但发送不了数据的。请帮看下从机程序:理论上过来的数据应该是“1-42-0-0-0”,但我实际收到往往是:“1-42-0-1-42”,或者“1-42-1-42-1”,这样循环。主机时钟250Hz,求教!
[pre lang=&arduino& line=&1&]#include &stdio.h&
#include &Arduino.h&
#include &avr/pgmspace.h&
#include&SPI.h&
#define uchar unsigned char
//initial i.o port
void IO_Initila(void)
// digitalWrite(SS, LOW);
pinMode(MISO,OUTPUT);
&&pinMode(SS, INPUT);
&&pinMode(SCK, INPUT);
&&pinMode(MOSI, INPUT);
&&SPCR |= _BV(SPE);
//SlaveInit
void SPI_SlaveInit(void)
&&SPCR=(1&&SPE);
&&SPCR |= _BV(DORD);
&&SPCR |= _BV(CPOL);
&&SPCR |= _BV(CPHA);
void setup()
&&pinMode(12,OUTPUT);
&&pinMode(13,OUTPUT);
&&digitalWrite(12,HIGH);//ACKPIN 每个8 bits数据发送之后的最后一个时钟周期变低
Serial.begin(115200);
void loop()
&&IO_Initila();
&&SPI_SlaveInit();
& & while(digitalRead(SS)==0)
Serial.print(&read:&);
Serial.print(SPI.transfer(0xFF));
Serial.print(&-&);
Serial.print(SPI.transfer(0x41));
Serial.print(&-&);
Serial.print(SPI.transfer(0x5A));
Serial.print(&-&);
Serial.print(SPI.transfer(0xFF));
Serial.print(&-&);
Serial.println(SPI.transfer(0xFD));
delayMicroseconds(2);
pinMode(SS, OUTPUT);
digitalWrite(SS,HIGH);
//改SPI.H的函数
byte SPIClass::transfer(byte _data) {
&&SPDR = _
&&while (!(SPSR & _BV(SPIF)))
&&delayMicroseconds(6);//ACKPIN 每个8 bits数据发送之后的最后一个时钟周期变低
&&digitalWrite(12,LOW);
&&delayMicroseconds(6);
&&digitalWrite(12,HIGH);
&&return SPDR;
感觉你想用Arduino自带的SPI库函数,但是你直接把参变量改来改去很可能就改错了,最好直接用它的接口函数调用,不要自己写!要是你喜欢改写,建议直接写SPI的几种操作函数,用普通IO口模拟SPI通信。另外,你的主机那边是什么情况?分频后为250Hz吗,这么低的频率?希望把主机那边的情况也描述清晰点~
本帖最后由 ps2xu 于
21:22 编辑
leicheng 发表于
感觉你想用Arduino自带的SPI库函数,但是你直接把参变量改来改去很可能就改错了,最好直接用它的接口函数调 ...
我想用硬件SPI改一下用,如果用arduino模拟SPI就是时钟上升沿和下降沿怎么确定?时钟极性:空闲时为高电平,时钟相位:第二时钟沿采样(上升沿),低位先行,即LSB。网上的PS手柄函数是arduino为主机,我是arduino为从机,主机接口是PS游戏机手柄接口,DATA对应MISO,COMMAND对应MOSI,ATT对应SS,CLOCK相对应,另外一个ACK,此信号在每个8 bits数据发送之后的最后一个时钟周期变低,不变低,主机认为未连接,谢谢,波形图:
还是回一下,
1. PS手柄能不能做主机?不要以为你在这边按按PS,Arduino接收信号,PS手柄端就成主机了,你能修改它的各种通信参数,对内部MCU进行控制吗?对多数人而言,PS手柄仅仅是个数据采集装置。
2. 既然你讲PS这端的频率是250KHz,那么Arduino这边分频了没?貌似你发的程序内没有涉及。(Arduino默认是4分频,328P分频后为5MHz,建议用Leonarod,设置为64分频。)
3. IO口模拟SPI,百度里有C语言版手把手教你怎么写。如果你要用Arduino自带的SPI,进官网认真学习SPI通信相关的Arduino教程,切记用它的库函数~不要自己直接给变量赋值,除非你特别熟悉每个细节。
祝你好运~!
Powered by通讯方式(8)
单片机(18)
今天知道了 SPI 时钟的设置 ,原来SPI 主设备 时钟极性的配置 应该和 从设备SDI的极性
怪不得以前做SPI 主设备程序的时候 ,把它设备设成mode 3(此时CPHA=1)就ok,设成mode 0(此时CPHA=0)就ng。因为我们的设备室mode0. 当初还以为 从设备的模式是跟着主设备走的呢!
但看了一些材料,发现 这个模式 有些叫法不一致 ,有些不懂。
一 .有的叫法是这样的(/p-.html&& 57页):
&&&&&&&&&&&&&&&&&&
(我们把CPOH 理解成 CPHA 即可,by imjacob)
二 .还有是这样的:(/Efronc/archive//1764505.html)
这里CPOL 是 Clock Polarity的缩写,为0表示SCLK为低时总线空闲 (高时总线active),为1表示SCLK为高时总线空闲(低时总线active)。
CPHA 是 Clock Phase的缩写。但含义好像讲法不一。一种是说 为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样。(现在感觉这种讲法最正确,就以这个为标准吧。CPHA 和CPOL 的讲法也为准吧 。110315:最近看到了moto的标准,就是这样的。参看标准)另一种是说
决定SCK的上升沿采样还是在SCK的结束沿采样。blackfin 貌似也是这种 。
三 .还有一种是下面这样的:(载自 microchip资料 )
看了一下,CPOL 和CKP 的定义一模一样。CPOH 和 CKE 就有点吃不准了.另外,这张图也很怪,mode和 后面CKE 值取反了?
CKP(CLOCK Polarity)
CKE (CLOCK EDGE SELECT )
(110316: 在看 &PIC嵌入式系统开发& 时,知道了,CKE =0 表示 数据传输发生在 时钟信号 由空闲状态 转向活动状态,=1 表示 数据传输发生在 时钟信号 由活动状态 转向空闲状态。所以他的定义也和 CPHA 反了。
另外 ,PIC 又多了数据采样位 ,SMP ,0表示在数据输出中段采样输入数据。为1 是在数据输出结束时采样输入数据。&
&而我们知道标准定义的是 采样位 和传输位相反就是了 )
四 .最后是 atmel的9260的定义:
能看出 ,他和 microchip的定义是一样的 。现在 猜想 ,可能 是atmel 和 microchip为了不交 专利费给 moto,把 moto的 CPHA 取了个反 。呵呵 。真是 不知道说啥了。(//110315: TI的msp430也是这样的,他又换了个名字,其实可以发现这些的定义本质上都是一样,只是换换名字,偷换概念而已。)
//110316最新总结:
这样看来这些混乱不堪的叫法其实都是一样的,他们仅仅是把CPHA 给取反了。真是折腾了。另外就是PIC 把采样和 数据输出用不同位来表示了。
除此,无它。
其实这篇文章可以删去了,但为了纪念这个折腾了我好久的问题,还是留着吧。
//==============================================================
以下载自:http://cxjr.21ic.org/user1/5877/archives/.html
SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200.
  SPI总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线 SS(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。
  SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。
  (1)SDO – 主设备数据输出,从设备数据输入
  (2)SDI – 主设备数据输入,从设备数据输出
  (3)SCLK – 时钟信号,由主设备产生
  (4)CS – 从设备使能信号,由主设备控制
  其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。
  接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。
  要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。
  在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。
  最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。
  AT91RM9200的SPI接口主要由4个引脚构成:SPICLK、MOSI、MISO及 /SS,其中SPICLK是整个SPI总线的公用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO 是主机的输入,从机的输出。/SS是从机的标志管脚,在互相通信的两个SPI总线的器件,/SS管脚的电平低的是从机,相反/SS管脚的电平高的是主机。在一个SPI通信系统中,必须有主机。SPI总线可以配置成单主单从,单主多从,互为主从。
  SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。
SPI协议举例
  SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。
  假设下面的8位寄存器装的是待发送的数据,上升沿发送、下降沿接收、高位先发送。
  那么第一个上升沿来的时候 数据将会是sdo=1;寄存器中的左移一位,后面补入送来的一位未知数x,成了0101010x。下降沿到来的时候,sdi上的电平将锁存到寄存器中去,那么这时寄存器=0101010sdi,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个spi时序。
  举例:
  假设主机和从机初始化就绪:并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据
  脉冲 主机sbuff 从机sbuff sdi sdo
  这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉底被动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16 位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。 SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束
中断标志;写冲突保护;总线竞争保护等。下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式 (实线表示):
  SPI总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主模块和与之通信的外设备时钟相位和极性应该一致。
  SPI总线包括1根串行同步时钟信号线以及2根数据线。
  SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主模块和与之通信的外设音时钟相位和极性应该一致。SPI接口时序如图3、图4所示。
  补充:
  上文中最后一句话:SPI主模块和与之通信的外设备时钟相位和极性应该一致。个人理解这句话有 2层意思:其一,主设备SPI时钟和极性的配置应该由外设来决定;其二,二者的配置应该保持一致,即主设备的SDO同从设备的SDO配置一致,主设备的 SDI同从设备的SDI配置一致。因为主从设备是在SCLK的控制下,同时发送和接收数据,并通过2个双向移位寄存器来交换数据。工作原理演示如下图:
  上升沿主机SDO发送数据1,同时从设备SDO发送数据0;紧接着在SCLK的下降沿的时候从设备的SDI接收到了主机发送过来的数据1,同时主机也接收到了从设备发送过来的数据0.
SPI协议心得
  SPI接口时钟配置心得:
  在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求,因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据,是在时钟的下降沿还是上升沿输出数据。但要注意的是,由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI,从设备SDI接收的数据是主设备的SDO发送过来的,主设备 SDI接收的数据是从设备SDO发送过来的,所以主设备这边SPI时钟极性的配置(即SDO的配置)跟从设备的SDI接收数据的极性是相反的,跟从设备
SDO发送数据的极性是相同的。
(贴个图,说明这个问题的,by imjacob)
下面这段话是Sychip Wlan8100 Module Spec上说的,充分说明了时钟极性是如何配置的:
  The 81xx module will always input data bits at the rising edge of the clock, and the host will always output data bits on the falling edge of the clock.
  意思是:主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。因此主设备这边SPI时钟极性应该配置为下降沿有效。
  又如,下面这段话是摘自LCD Driver IC SSD1289:
  SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.
  意思是:从设备SSD1289在时钟的上升沿接收数据,而且是按照从高位到地位的顺序接收数据的。因此主设备的SPI时钟极性同样应该配置为下降沿有效。
  时钟极性和相位配置正确后,数据才能够被准确的发送和接收。因此应该对照从设备的SPI接口时序或者Spec文档说明来正确配置主设备的时钟。
这篇文章比较了SPI 和iic,也很不错。
http://china./app-notes/index.mvp/id/4024
//=========================================================
这篇文章讲SPI 讲的最彻底,是FPGA 程度的,
/Efronc/archive//1764505.html
一.SPI总线简介
串行外围设备接口SPI(serial&peripheral&interface)总线技术是Motorola公司推出的一种同步串行接口。
SPI&用于CPU与各种外围器件进行全双工、同步串行通讯。它只需四条线就可以完成MCU与各种外围器件的通讯,这四条线是:串行时钟线(CSK)、主机输入/从机输出数据线(MISO)、主机输出/从机输入数据线(MOSI)、低电平有效从机选择线CS。当SPI工作时,在移位寄存器中的数据逐位从输出引脚(MOSI)输出(高位在前),同时从输入引脚(MISO)接收的数据逐位移到移位寄存器(高位在前)。发送一个字节后,从另一个外围器件接收的字节数据进入移位寄存器中。即完成一个字节数据传输的实质是两个器件寄存器内容的交换。主SPI的时钟信号(SCK)使传输同步。其典型系统框图如下图所示。
二.SPI总线主要特点
·&全双工;&
·&可以当作主机或从机工作;&
·&提供频率可编程时钟;&
·&发送结束中断标志;&
·&写冲突保护;&
.总线竞争保护等。&
三.SPI总线工作方式
SPI总线有四种工作方式,其中使用的最为广泛的是SPI0和SPI3方式(实线表示):
四种工作方式时序分别为:
时序详解:
CPOL:时钟极性选择,为0时SPI总线空闲为低电平,为1时SPI总线空闲为高电平
CPHA:时钟相位选择,为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样
工作方式1:
当CPHA=0、CPOL=0时SPI总线工作在方式1。MISO引脚上的数据在第一个SPSCK沿跳变之前已经上线了,而为了保证正确传输,MOSI引脚的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,首先将数据上线,然后在同步时钟信号的上升沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(下降沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。
工作方式2:
当CPHA=0、CPOL=1时SPI总线工作在方式2。与前者唯一不同之处只是在同步时钟信号的下降沿时捕捉位信号,上升沿时下一位数据上线。
工作方式3:
当CPHA=1、CPOL=0时SPI总线工作在方式3。MISO引脚和MOSI引脚上的数据的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,在同步时钟信号周期开始时(上升沿)数据上线,然后在同步时钟信号的下降沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(上升沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。
工作方式4:
当CPHA=1、CPOL=1时SPI总线工作在方式4。与前者唯一不同之处只是在同步时钟信号的上升沿时捕捉位信号,下降沿时下一位数据上线。&
四.SPI总线常见错误
1&SPR设定错误
 在从器件时钟频率小于主器件时钟频率时,如果SCK的速率设得太快,将导致接收到的数据不正确(SPI接口本身难以判断收到的数据是否正确,要在软件中处理)。
 整个系统的速度受三个因素影响:主器件时钟CLK主、从器件时钟CLK从和同步串行时钟SCK,其中SCK是对CLK主的分频,CLK从和CLK主是异步的。要使SCK无差错无遗漏地被从器件所检测到,从器件的时钟CLK从必须要足够快。下面以SCK设置为CLK主的4分频的波形为例,分析同步串行时钟、主时钟和从时钟之间的关系。
图1主从时钟和SCK的关系
 如图1所示,当T从&Tsck/2,即T从<2T主时,无论主时钟和从时钟之间的相位关系如何,在从器件CLK从的上升沿必然能够检测到SCK的低电平,即SCK=0的范围内至少包含一个CLK从的上升沿。
 图2中,当T从≥TSCK/2=2T主时,在clk_s的两个上升沿都检测不到SCK的低电平,这样从器件就会漏掉一个SCK。在某些相位条件下,即使 CLK从侥幸能检测到SCK的低电平,也不能保证可以继续检测到下一个SCK。只要遗漏了一个SCK,就相当于串行数据漏掉了一个位,后面继续接收/发送的数据就都是错误的了。
图2主从时钟和SCK的关系
 根据以上的分析,SPR和主从时钟比的关系如表1所列。
表1&SPR的设置和主从时钟周期比值之间的关系
 在发送数据之前按照表1对SPR进行设置,SPR设定错误可以完全避免。
2&模式错误(MODF)
 模式错误表示的是主从模式选择的设置和引脚SS的连接不一致。
 器件工作在主模式的时候(MSTR=1),它的片选信号SS引脚必须接高电平。在发送数据的过程中,如果它的SS从高电平跳至低电平,在SS的下降沿,SPI模块将检测到模式错误,对MODF位置1,强制器件从主模式转入从模式(即令MSTR=0),清空内部计数器counter,并结束正在进行的数据传输,如图 3(a)所示。
 对从模式(MSTR=0),在没有数据传送的时候,SS高电平表示从器件未被选中,从器件不工作,MISO输出高阻;在数据传输过程中,片选信号SS必须接低电平,且SS不允许跳变。如果SS从低电平跳到高电平,在SS的上跳沿,SPI模块也将检测到模式错误,清空内部计数器 counter,并结束正在进行的数据传输。直到SS恢复为低电平,重新使SPEN=1时,才重新开始工作,如图3(b)所示。
图3模式错误的检测
3&溢出错误(OVR)
 溢出错误表示连续传输多个数据时,后一个数据覆盖了前一个数据而产生的错误。
 状态标志SPIF表示的是数据传输正在进行中,它对数据的传输有较大的影响。主器件的SPIF有效由数据寄存器的空标志SPTE=0产生,而从器件的 SPIF有效则只能由收到的第一个SCK的跳变产生,且又由于从器件的SPIF和主器件发出的SCK是异步的,因此从器件的传输标志SPIF从相对于主器件的传输标志SPIF主有一定的滞后。如图4所示,在主器件连续发送两个数据的时候将有可能导致从器件的传输标志和主器件下一个数据的传输标志相重叠(图 4中虚线和阴影部分),第一个收到的数据必然被覆盖,第二个数据的收/发也必然出错,产生溢出错误。
图4溢出错误
  通过对从器件的波形分析发现,counter=8后的第一个时钟周期,数据最后一位的传输已经完成。在数据已经收/发完毕的情况下,counter=8 状态的长短对数据的正确性没有影响,因此可以缩短counter=8的状态,以避免前一个SPIF和后一个SPIF相重叠。这样,从硬件上避免了这一阶段的溢出错误。
  但是,如果从器件工作速度不够快或者软件正在处理其他事情,在SPI接口接收到的数据尚未被读取的情况下,又接收到一个新的数据,溢出错误还是会发生的。此时,SPI接口保护前一个数据不被覆盖,舍弃新收到的数据,置溢出标志OVR=1;另外发出中断信号(如果该中断允许),通知从器件及时读取数据。
4&偏移错误(OFST)
  SPI接口一般要求从器件先工作,然后主器件才开始发送数据。有时在主器件往外发送数据的过程中,从器件才开始工作,或者SCK受到外界干扰,从器件未能准确地接收到8个SCK。如图5所示,从器件接收到的8个SCK其实是属于主器件发送相邻的两个数据的SCK主。这时,主器件的SPIF和从器件的SPIF会发生重叠,数据发生了错位,从器件如果不对此进行纠正的话,数据的接收/发送便一直地错下去。
图5偏移错误
 在一个数据的传输过程中,SPR是不允许改变的,即SCK是均匀的,而从图5可以看出,从器件接收到的8个SCK并不均匀,它们是分别属于两个数据的,因此可以计算SCK的占空时间来判断是否发生了偏移错误。经分析,正常时候SCK=1时的时钟周期数n的取值满足如下关系:
 但由于主从时钟之间是异步的,并且经过了取整,所以正常时候SCK=1时的时钟周期计数值COUNT应满足:
 比如在图5中,COUNT的最大值COUNT(max)=2或者1,都可认为是正常的。但当出现COUNT(max)=8时,可以判定出现了偏移错误。在实际设计中,先记录下第一个COUNT(max)的值,如果后面又出现与记录值相差1以上的COUNT(max)出现,可知有偏移错误OFST
发生。SPI接口在“不均匀”的地方令SPIF=1,然后准备等待下一个数据的第一个SCK。其中COUNT的位数固定为8位,为了避免溢出时重新从00H开始计数,当计数达到ffH时停止计数。
5&其他错误
 设定不当,或者受到外界干扰,数据传输难免会发生错误,或者有时软件对错误的种类判断不清,必须要有一种方法强制SPI接口从错误状态中恢复过来。在 SPI不工作,即SPEN=0的时候,清除SPI模块内部几乎所有的状态(专用寄存器除外)。如果软件在接收数据的时候,能够发现数据有错误,无论是什么错误,都可以强制停止SPI的工作,重新进行数据传输。例如,在偏移错误(OFST)中,如果SPR2、SPR1和SPR0的设置适当,也可以使SCK显得比较“均匀”。SPI接口硬件本身不可能检测到有错误,若用户软件能够发现错误,这时就可以强制停止SPI的传输工作,这样就可以避免错误一直持续下去。
在应用中,如果对数据的正确性要求较高,除了要在软件上满足SPI接口的时序要求外,还需要在软件上作适当的处理。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13335次
排名:千里之外
转载:34篇
(4)(1)(2)(3)(3)(5)(3)(3)(1)(3)(1)(2)(7)(1)(1)(2)(1)

我要回帖

更多关于 根据采样点计算相位 的文章

 

随机推荐