基于MSP430G2553的SPI串行协议.docx
《基于MSP430G2553的SPI串行协议.docx》由会员分享,可在线阅读,更多相关《基于MSP430G2553的SPI串行协议.docx(14页珍藏版)》请在冰豆网上搜索。
![基于MSP430G2553的SPI串行协议.docx](https://file1.bdocx.com/fileroot1/2022-11/30/3b8f7f6b-ec84-40c5-b736-9616d5ed9744/3b8f7f6b-ec84-40c5-b736-9616d5ed97441.gif)
基于MSP430G2553的SPI串行协议
基于MSP430G2553的SPI串行协议
一、概述.
SPI,SerialPerripheralInterface,串行外围设备接口,是Motorola公司推出的一种同步串行接口技术.SPI总线在物理上是通过接在外围设备微控制器(PICmicro)上面的微处理控制单元(MCU)上叫作同步串行端口(SynchronousSerialPort)的模块(Module)来实现的,它允许MCU以全双工的同步串行方式,与各种外围设备进行高速数据通信.
SPI主要应用在EEPROM,Flash,实时时钟(RTC),数模转换器(ADC),数字信号处理器(DSP)以及数字信号解码器之间.它在芯片中只占用四根管脚(Pin)用来控制以及数据传输,节约了芯片的pin数目,同时为PCB在布局上节省了空间.正是出于这种简单易用的特性,现在越来越多的芯片上都集成了SPI技术.
二、特点
1.采用主-从模式(Master-Slave)的控制方式
SPI规定了两个SPI设备之间通信必须由主设备(Master)来控制次设备(Slave).一个Master设备可以通过提供Clock以及对Slave设备进行片选(SlaveSelect)来控制多个Slave设备,SPI协议还规定Slave设备的Clock由Master设备通过SCK管脚提供给Slave设备,Slave设备本身不能产生或控制Clock,没有Clock则Slave设备不能正常工作.
2.采用同步方式(Synchronous)传输数据
Master设备会根据将要交换的数据来产生相应的时钟脉冲(ClockPulse),时钟脉冲组成了时钟信号(ClockSignal),时钟信号通过时钟极性(CPOL)和时钟相位(CPHA)控制着两个SPI设备间何时数据交换以及何时对接收到的数据进行采样,来保证数据在两个设备之间是同步传输的.
3.数据交换(DataExchanges)
SPI设备间的数据传输之所以又被称为数据交换,是因为SPI协议规定一个SPI设备不能在数据通信过程中仅仅只充当一个"发送者(Transmitter)"或者"接收者(Receiver)".在每个Clock周期内,SPI设备都会发送并接收一个bit大小的数据,相当于该设备有一个bit大小的数据被交换了.
一个Slave设备要想能够接收到Master发过来的控制信号,必须在此之前能够被Master设备进行访问(Access).所以,Master设备必须首先通过SS/CSpin对Slave设备进行片选,把想要访问的Slave设备选上.
在数据传输的过程中, 每次接收到的数据必须在下一次数据传输之前被采样.如果之前接收到的数据没有被读取,那么这些已经接收完成的数据将有可能会被丢弃, 导致SPI物理模块最终失效.因此,在程序中一般都会在SPI传输完数据后,去读取SPI设备里的数据,即使这些数据(DummyData)在我们的程序里是无用的.
三、工作机制
1.概述
2011-03-1216:
22上传
下载附件(28.52KB)
上图只是对SPI设备间通信的一个简单的描述,下面就来解释一下图中所示的几个组件(Module):
SSPBUF,SynchronousSerialPortBuffer,泛指SPI设备里面的内部缓冲区,一般在物理上是以FIFO的形式,保存传输过程中的临时数据;
SSPSR,SynchronousSerialPortRegister,泛指SPI设备里面的移位寄存器(ShiftRegitser),它的作用是根据设置好的数据位宽(bit-width)把数据移入或者移出SSPBUF;
Controller,泛指SPI设备里面的控制寄存器,可以通过配置它们来设置SPI总线的传输模式.
通常情况下,我们只需要对上图所描述的四个管脚(pin)进行编程即可控制整个SPI设备之间的数据通信:
SCK,SerialClock,主要的作用是Master设备往Slave设备传输时钟信号,控制数据交换的时机以及速率;
SS/CS,SlaveSelect/ChipSelect,用于Master设备片选Slave设备,使被选中的Slave设备能够被Master设备所访问;
SDO/MOSI,SerialDataOutput/MasterOutSlaveIn,在Master上面也被称为Tx-Channel,作为数据的出口,主要用于SPI设备发送数据;
SDI/MISO,SerialDataInput/MasterInSlaveOut,在Master上面也被称为Rx-Channel,作为数据的入口,主要用于SPI设备接收数据;
SPI设备在进行通信的过程中,Master设备和Slave设备之间会产生一个数据链路回环(DataLoop),就像上图所画的那样,通过SDO和SDI管脚,SSPSR控制数据移入移出SSPBUF,Controller确定SPI总线的通信模式,SCK传输时钟信号.
2.Timing.
2011-03-1513:
42上传
下载附件(21.66KB)
上图通过Master设备与Slave设备之间交换1Byte数据来说明SPI协议的工作机制.
首先, 在这里解释一下两个概念:
CPOL:
时钟极性,表示SPI在空闲时,时钟信号是高电平还是低电平.若CPOL被设为1,那么该设备在空闲时SCK管脚下的时钟信号为高电平.当CPOL被设为0时则正好相反.
CPHA:
时钟相位,表示SPI设备是在SCK管脚上的时钟信号变为上升沿时触发数据采样,还是在时钟信号变为下降沿时触发数据采样.若CPHA被设置为1,则SPI设备在时钟信号变为下降沿时触发数据采样,在上升沿时发送数据.当CPHA被设为0时也正好相反.
上图里的"Mode1,1"说明了本例所使用的SPI数据传输模式被设置成CPOL=1,CPHA=1.这样,在一个Clock周期内,每个单独的SPI设备都能以全双工(Full-Duplex)的方式,同时发送和接收1bit数据,即相当于交换了1bit大小的数据.如果SPI总线的Channel-Width被设置成Byte,表示SPI总线上每次数据传输的最小单位为Byte,那么挂载在该SPI总线的设备每次数据传输的过程至少需要8个Clock周期(忽略设备的物理延迟).因此,SPI总线的频率越快,Clock周期越短,则SPI设备间数据交换的速率就越快.
3.SSPSR.
2011-03-1216:
51上传
下载附件(34.63KB)
SSPSR是SPI设备内部的移位寄存器(ShiftRegister).它的主要作用是根据SPI时钟信号状态,往SSPBUF里移入或者移出数据,每次移动的数据大小由Bus-Width以及Channel-Width所决定.
Bus-Width的作用是指定地址总线到Master设备之间数据传输的单位.
例如,我们想要往Master设备里面的SSPBUF写入16Byte大小的数据:
首先,给Master设备的配置寄存器设置Bus-Width为Byte;然后往Master设备的Tx-Data移位寄存器在地址总线的入口写入数据,每次写入1Byte大小的数据(使用writeb函数);写完1Byte数据之后,Master设备里面的Tx-Data移位寄存器会自动把从地址总线传来的1Byte数据移入SSPBUF里;上述动作一共需要重复执行16次.
Channel-Width的作用是指定Master设备与Slave设备之间数据传输的单位.与Bus-Width相似, Master设备内部的移位寄存器会依据Channel-Width自动地把数据从Master-SSPBUF里通过Master-SDO管脚搬运到Slave设备里的Slave-SDI引脚,Slave-SSPSR再把每次接收的数据移入Slave-SSPBUF里.
通常情况下,Bus-Width总是会大于或等于Channel-Width,这样能保证不会出现因Master与Slave之间数据交换的频率比地址总线与Master之间的数据交换频率要快,导致SSPBUF里面存放的数据为无效数据这样的情况.
4.SSPBUF.
2011-03-1217:
14上传
下载附件(39.78KB)
我们知道,在每个时钟周期内,Master与Slave之间交换的数据其实都是SPI内部移位寄存器从SSPBUF里面拷贝的.我们可以通过往SSPBUF对应的寄存器(Tx-Data/Rx-Dataregister)里读写数据,间接地操控SPI设备内部的SSPBUF.
例如,在发送数据之前,我们应该先往Master的Tx-Data寄存器写入将要发送出去的数据,这些数据会被Master-SSPSR移位寄存器根据Bus-Width自动移入Master-SSPBUF里,然后这些数据又会被Master-SSPSR根据Channel-Width从Master-SSPBUF中移出,通过Master-SDO 管脚传给Slave-SDI管脚, Slave-SSPSR则把从 Slave-SDI接收到的数据移入Slave-SSPBUF里. 与此同时,Slave-SSPBUF里面的数据根据每次接收数据的大小(Channel-Width),通过Slave-SDO发往Master-SDI,Master-SSPSR再把从Master-SDI接收的数据移入Master-SSPBUF.在单次数据传输完成之后,用户程序可以通过从Master设备的Rx-Data寄存器读取Master设备数据交换得到的数据.
VoidUART_init()
{
WDTCTL=WDTPW+WDTHOLD;
P1SEL|=0x06;//I/O口的功能寄存器配置。
为1时作为模块输出或者输出,0为端口输入或者输出。
配置P1.1,P1.2为串行口。
P2DIR=0x04;//串口发送端为输出,串口接收端为输入。
0为输入,1为输出
U0CTL|=CHAR; //配置控制寄存器,数据类型为8位。
U0TCTL|=SSEL0; //选择时钟UCLK=ACLK。
U0BR0=0x45; //分频系数的高8位,8MHz时钟下波特率为115200
U0BR1=0x00; //分频系数的低8位。
U0MCTL=0x00; //波特率的调整。
U0CTL&=~SWRST; //系统复位。
只有对SWRST复位,USART才能重新被允许。
而接收和发送允许标志URXE和UTXE不会因SWRST而更改。
ME1|=UTXE0+URXE0; //使能USART0TXD/RXD模块USART中特有的使能配置。
IE1|=URXIE0; //使能USART0接收中断
_EINT();//开启全部中断。
_BIS_SR(LPM0_bits+GIE); //初始化完毕,进入睡眠状态。
等待工作。
该程序直接调用。
}
发送数据函数:
__interruptvoidusart0_rx(void)
{
while(!
(IFG1&UTXIFG0)); //判断发送缓冲区是否为空。
TXBUF0=RXBUF0; //将数据发送到串口。
}
二、SPI模式
USTAR下的SPI模式有如下特点:
1、SPI模式支持3线和4线模式;
2、支持主机与从机模式;
3、接受和发送有各自独立的发送移位寄存器和缓冲器;
4、接受和发送都有独立的中断能力;
5、移位时钟的极性和相位可编程;
6、字符长度可以是7位或者8位。
SPI工作在全双工下,即主机发送的同时也接收数据,传输的速率由编程决定。
4线SPI模式用附加数据线,允许从机数据的发送和接收。
其信号如下:
SIMO:
从进主出,主机模式下,数据输出;从机模式下,数据输入。
SOMI:
从出主进,主机模式下,数据输入,从机模式下,数据输出。
UCLK:
USARTSPI模式时钟,信号有主机输出,从机输入。
CLK时钟只能由主机提供。
STE:
从机模式发送接收允许控制脚,用于4线模式。
(一)SPI初始化
SPI当中不需要波特率调整,所以UxMCTL=0x0000,SPI的初始化及其复位和UART公用一套寄存器。
在初始化或者重新配置USART的SPI时,必须按照以下顺序进行:
1、UxCTL寄存器的第0位SWRST置位;
2、在SWRST置位的条件下,初始化所有的SPI寄存器,包括UxCTL寄存器;
3、通过置位模块使能寄存器MEx的URXEx和UTXEx位使能SPI的接受和发送使能模块;
4、通过软件复位UxCTL寄存器的第0位SWRST;
5、通过中断使能寄存器IEx的URXIEx和UTXIEx来使能发送和接受中断。
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD; //关闭看门狗。
P1SEL|=0x07; //配置P1.0、P1.1、P1.2模块输出。
UCTL=CHAR+SYNC+MM; //工作模式以及数据格式的设置,CHAR为1时为8-bit,0时为7位,SYNC控制通讯模式,1为SPI模式,0为UART模式。
UTCTL=CKPL+STC+SSEL0+SSEL1; //置位SSEL0与SSEL1时钟的类型,11则为SMCLK;CKPL为时钟极性控制位,0时UCLKI信号
与UCLK信号极性相同,1时UCLKI信号与UCLK信号极性相反。
UBR0=0x02; //SPICLK=SMCLK/2,2分频。
波特率的设置。
UBR1=0x00;
UMCTL=0x00;//SPI通讯中,不需要使用波特率调整器。
UCTL&=~SWRST; //复位。
ME1|=USPIE0; //SIP模块接收与发送允许使能
IE1|=URXIE0+UTXIE0; //接收与发送中断使能
_BIS_SR(LPM4_bits+GIE); //初始化完毕,进入睡眠模式
}
__interruptvoidSPI0_rx(void)
{
P1OUT=RXBUF0; //向P1OUT送入数据
}
__interruptvoidSPI0_tx(void)
{
unsignedinti;
i=P1IN;
i=i>>4;
TXBUF0=i; //数据发送。
}
三、寄存器及其功能
通信模块寄存器如下:
表3.1USART0的寄存器
寄存器
缩写
读写类型
地址
初始状态
控制寄存器
U0CTL
读/写
070H
PUC后001H
发送控制寄存器
U0TCTL
读/写
71H
PUC后001H
接收控制寄存器
U0RCTL
读/写
72H
PUC后000H
波特率调整控制寄存器
U0MCTL
读/写
73H
不变
波特率控制寄存器0
U0BR0
读/写
74H
不变
波特率控制寄存器1
U0BR1
读/写
75H
不变
接收缓冲器
U0RXBUF
读
76H
不变
发送缓冲器
U0TXBUF
读/写
77H
不变
SFR模块使能寄存器1
ME1
读/写
004H
PUC后000H
SFR模块使能寄存器1
IE1
读/写
000H
PUC后000H
SFR模块使能寄存器1
IFG1
读/写
002H
PUC后082H
(1)控制寄存器UxCTL
控制寄存器内的信息决定了USART的基本操作。
如:
选择通信协议、通信模式和校验位。
在SWRST复位使USART复位操作禁止前,各位应根据选择的模式进行编程。
表3.2发送控制寄存器UxCTL
位
含义
使用
7(PENA)
校验允许位
0:
校验禁止
1:
校验允许
6(PEV)
奇偶校验位
0:
奇校验
1:
偶校验
5(SP)
停止位选择
0:
1位停止位
1:
2位停止位
4(CHAR)
字符长度
0:
7位
1:
8位
3(LISTEN)
反馈选择
(选择是否发送数据由内部反馈给接收器)
0:
无反馈
1:
有反馈
2(SYNC)
USART模块的模式选择
0:
UART模式(异步)
1:
SPI模式(同步)
1(MM)
多机模式选择位
0:
线路空闲多机协议
1:
地址位多机协议
0(SWRST)
控制位(上电置位)
0:
USART禁止
1:
USART允许
(2)发送控制寄存器UxTCTL(未作说明的位未用)
寄存器UxTCTL控制与发送操作相关的USART硬件。
表3.3发送控制寄存器UxTCTL
位
含义
使用
7(CKPH)
时钟相位控制位
0:
正常UCLK时钟
1:
UCLK时钟延迟半个周期
6(CKPL)
时钟极性控制位
0:
UCLKI信号与UCLK信号极性相同
1:
UCLKI信号与UCLK信号极性相反
5(SSEL1)
时钟源选择
(确定波特率发生器的时钟源)
00:
外部时钟UCLKI
01:
辅助时钟ACLK
10:
子系统时钟SMCLK
11:
子系统时钟SMCLK
4(SSEL0)
1(STC)
发送控制位
0:
SPI为4线模式
1:
SPI为3线模式
0(TXEPT)
发送器空标志,在异步模式与同步模式时是不一样的
0:
正在传输数据或者发送缓冲器(UTXBUF)有数据
1:
表示发送移位寄存器和UTXBUF空或者SWRST=1
(3)接收控制寄存器URCTL
URCTL控制与接收操作相关的USART硬件并保存由最新写入URXBUF的字符引起的出错状况和唤醒条件。
若FE、PE、OE、BRK、RXERR或RXWake中的任何一位置位,通过接收下一个字符不能使其复位。
它们的复位要通过访问接收缓存URXBUF、USART的软件复位SWRST、系统复位PUC或用指令修改。
表3.4接收控制寄存器URCTL
位
含义
使用
7(FE)
帧错误标志位
0:
无帧错误
1:
有帧错误
6(PE)
校验错误标志位
0:
校验正确
1:
校验错误
5(OE)
溢出标志位
0:
无溢出
1:
有溢出
4(BRK)
打断检测位
0:
未打断
1:
打断
3(URXEIE)
接收出错中断允许位
0:
禁止中断,不接收出错字符,不改变URXIFG标志
1:
允许中断,接收出错字符,置位URXIFG标志
2(URXWIE)
接收唤醒中断允许位
0:
接收的所有字符都能够置位URXIFG
1:
只有接收到地址字符才置位URXIFG
1(RXWake)
接收唤醒检测位
0:
未被唤醒,接收到的字符是数据
1:
唤醒,接收的字符是地址
0(RXERR)
接收错误标志位
0:
未接收到错误
1:
接收到错误
在各种条件下URXEIE和URXWIE对URXIFG的影响:
URXEIE
URXWIE
字符出错
地址字符
接收字符后的标志位URXIFG
0
X
1
X
不变
0
0
0
X
置位
0
1
0
0
不变
0
1
0
1
置位
1
0
X
X
置位(接收所有字符)
1
1
X
0
不变
1
1
X
1
置位
(4)波特率选择寄存器和调制控制寄存器
波特率产生器利用波特率选择寄存器UxBR1和UxBR0,以及调整控制寄存器UxMCTL,来产生串行数据流的位定时。
UxBR0、UxBR1这两个寄存器是用于存放波特率分频因子的整数部分,若波特率发生器的输入频率BRCLK不是所需波特率的整数倍,带有小数,则整数部分写入UxBR寄存器,小数部分则由调整寄存器UxMCT的内容反映。
波特率由以下公式计算:
波特率=BRCLK/(UBR+(M7+M6+…M0)/8)
寄存器各位如下:
位
寄存器
7
6
5
4
3
2
1
0
UxBR0
UxBR1
UxMCT
M7
M6
M5
M4
M3
M2
M1
M0