目录
- 硬知识
- USCI的同步模式
- SPI概述
- SPI特性及结构框图
- 同步操作原理与操作
- USCI寄存器——SPI模式
- USCI_x_SPI API (机翻)
- 处理状态和初始化的函数
- 参数
- 处理数据的函数
- 参数
- 管理中断的函数
- 参数
- DMA相关
- 参数
平台:Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)
硬知识
USCI的同步模式
SPI概述
SPI(Serial Peripheral Interface)为串行外设接口的简称,它是一种同步全双工通信协议。MSP430F5xx/6xx系列单片机的USCI_A和USCI_B模块都支持SPI通信模式。SPI通信模块通过3线(SOMI、SIMO、CLK)或者4线(SOMI、SIMO、CLK及STE)同外界进行通信。下面对这4根线进行简要说明。
① CLK:CLK为SPI通信时钟线。该时钟线由主机控制,即传送的速率由主机编程决定。
② SOMI:SOMI(Slave Output Master Input)即主入从出引脚。如果设备工作在主机模式,该引脚为输入;如果设备工作在从机模式,该引脚为输出。
③ SIMO:SIMO(Slave Input Master Output)即从入主出引脚。如果设备工作在主机模式,该引脚为输出;如果设备工作在从机模式,该引脚为输入。
④ STE:STE(Slave Transmit Enable)即从机模式发送/接收控制引脚,控制多主或多从系统中的多个从机。在其他应用场合中,也经常被写为片选CS(Chip Select)和从机选择SS(Slave Select)。
SPI通信模块硬件功能很强,致使SPI通信软件实现相当简单,使CPU有更多的时间处理其他事情。SPI通信原理也比较简单,如图所示。
SPI特性及结构框图
当MSP430单片机USCI模块控制寄存器UCAxCTL0或UCBxCTL0的UCSYNC控制位置位,USCI模块工作在同步SPI模式,通过配置该寄存器中的UCMODEx控制位,可使SPI模块工作在三线或四线SPI通信模式下。MSP430的同步通信模式具有如下特点:
7位或8位数据长度;
最高有效位在前或者最低有效位在前的数据发送和接收;
支持3线或4线SPI操作;
支持主机模式或从机模式;
具有独立的发送和接收移位寄存器;
具有独立的发送和接收缓冲寄存器;
具有连续发送和接收能力;
时钟的极性和相位可编程;
主模式下,时钟频率可编程;
具有独立的接收和发送中断能力;
LPM4下的从模式工作。
USCI模块配置为SPI模式下的结构框图如图所示。
同步操作原理与操作
(1)SPI的主机模式
MSP430单片机的USCI模块作为SPI通信功能使用时,作为主机与另一具有SPI接口的SPI从机设备的连接图如图所示。
当控制寄存器UCAxCTL0/UCBxCTL0中的UCMST=1时,MSP430单片机的SPI通信模块工作在主机模式。USCI模块通过在UCxCLK引脚上的时钟信号控制串行通信。串行通信发送工作由发送缓冲区UCxTXBUF、发送移位寄存器和UCxSIMO引脚完成。当移位寄存器为空,已写入发送缓冲区的数据将移入发送移位寄存器,并启动在UCxSIMO引脚的数据发送,该数据发送是最高有效位还是最低有效位在前,取决于UCMSB控制位的设置。串行通信接收工作由UCxSOMI引脚、接收移位寄存器和接收缓冲区UCxRXBUF完成。UCxSOMI引脚上的数据在与发送数据时相反的时钟沿处移入接收移位寄存器,当接收完所有选定位数时,接收移位寄存器中的数据移入接收缓冲寄存器UCxRXBUF中,并置位接收中断标志位UCRXIFG,这标志着数据的接收/发送已经完成。
(2)SPI的从机模式
MSP430单片机的USCI模块作为SPI通信功能使用时,作为从机与另一具有SPI接口的SPI主机设备的连接图如图所示。
当控制寄存器UCAxCTL0/UCBxCTL0中的UCMST=0时,MSP430单片机的SPI通信模块工作在从机模式。在从机模式下,SPI通信所用的串行时钟来源于外部主机,从机的UCxCLK引脚为输入状态。数据传输速率由主机发出的串行时钟决定,而不是内部的时钟发生器。在UCxCLK开始前,由UCxTXBUF移入移位寄存器中的数据在主机UCxCLK信号的作用下,通过从机的UCxSOMI引脚发送给主机。同时,在UCxCLK时钟的反向沿UCxSIMO引脚上的串行数据移入接收移位寄存器中。当数据从接收移位寄存器移入接收缓冲寄存器UCxRXBUF中时,UCRXIFG中断标志位置位,表明数据已经接收完成。当新数据被写入接收缓冲寄存器时,前一个数据还没有被取出,则溢出标志位UCOE将被置位。
(3)串行时钟控制
串行通信所需的时钟线UCxCLK由SPI总线上的主机提供。当UCMST=1时,串行通信所需的时钟由USCI时钟发生器提供,通过UCSSELx控制位选择用于产生串行通信时钟的参考时钟,最终串行通信时钟由UCxCLK引脚输出。当UCMST=0时,USCI时钟由主机的UCxCLK引脚提供,此时USCI不使用时钟发生器,不考虑UCSSELx控制位。SPI的接收器和发送器并行操作,且数据传输使用同一个时钟源。
串行通信时钟速率控制寄存器(UCxxBR1和UCxxBR0)组成的16位UCBRx的值,是USCI时钟源BRCLK的分频因子。在主模式下,USCI模块能够产生的最大串行通信时钟是BRCLK。SPI模式下不可使用调制器,即SPI串行通信时钟发生器不支持小数分频,所以USCI工作在SPI模式下的时钟发生器产生频率计算公式为
(4)SPI通信时序图
SPI通信时序图如图所示。其中,CKPH和CKPL为UCxCLK的极性和相位控制位,在此对这两个控制位进行简要介绍。CKPH为UCxCLK的相位控制位,CKPL为UCxCLK的极性控制位。两个控制位如何设置对通信协议没有什么影响,只是用来约定在UCxCLK的空闲状态和从什么位置开始采样信号。当CKPH=0时,意味着发送在以UCxCLK第一个边沿开始采样信号,反之则在第二个边沿开始。当CKPL=0时,意味着时钟总线低电平空闲,反之则是时钟总线高电平空闲。当信号线稳定时,进行接收采样,当接收采样时,信号线不允许发生电平跳变。
(5)SPI中断
USCI模块只有一个中断向量,发送和接收共用该向量。USCI_Ax和USCI_Bx不共用同一个中断向量。
① SPI发送中断操作
若UCTXIFG置位,表明发送缓冲寄存器UCxTXBUF为空,可以向其写入新的字符。如果UCTXIE和GIE也置位,将产生发送中断请求。如果将字符写入UCxTXBUF缓冲区,UCTXIFG将会自动复位,因此可利用发送中断服务程序不断向发送缓冲寄存器UCxTXBUF写入新的数据,完成数据的传输。注意当UCTXIFG=0时,写数据到UCxTXBUF缓冲区,将可能会导致错误的数据发送。
② SPI接收中断操作
每当接收到一个字符,并把字符装载到接收缓冲寄存器UCxRXBUF时,将置位接收中断标志位UCRXIFG。如果UCRXIE和GIE也置位时,将产生一个接收中断请求。当接收缓冲寄存器UCxRXBUF被读取时,UCRXIFG会自动复位。因此,可利用接收中断服务程序完成数据的接收工作。
③ USCI中断向量UCxIV
USCI中断标志具有不同的优先级,它们组合共用一个中断向量,即USCI为多源中断。中断向量寄存器UCxIV用来决定哪个中断标志请求产生中断。优先级最高的中断将会在UCxIV寄存器内产生一个数字偏移量,这个偏移量累加到程序计数器PC上,程序自动跳转到相应的软件程序处。禁止中断不会影响UCxIV的值。对UCxIV寄存器的任何读或写访问,都会复位挂起优先级最高的中断标志。如果另一个中断标志置位,在响应完之前的中断后,将会立即产生另一个中断。
USCI寄存器——SPI模式
在SPI模式下可用的USCI寄存器如表所示。由于USCI_Ax寄存器和USCI_Bx寄存器类型和功能类似,在此只列出USCI_Ax寄存器并对其每位的含义进行讲解。若用户使用的为USCI_Bx模块,可参考USCI_Ax寄存器进行理解和配置。
USCI_x_SPI API (机翻)
要将模块配置为主机模式,用户必须调用USCI_x_SPI_initMaster()来配置USCI_x_SPI 主机模式。接下来是使用USCI_x_SPI_enable()启用USCI_x_SPI模块。然后启用中断(如果需要)。建议在开启中断前先开启USCI_x_SPI模块。然后使用USCI_x_SPI_transmitData()初始化数据传输,然后当设置接收标志时,使用USCI_x_SPI_receiveData()读取接收到的数据,这表明RX/TX操作已经完成。
要将模块配置为从机模式,可以使用USCI_x_SPI_initSlave()进行初始化
然后使用USCI_x_SPI_enable()启用模块。在此之后,中断可能
在需要时启用。当设置接收标志时,首先使用USCI_x_SPI_transmitData()传输数据,然后使用USCI_x_SPI_receiveData()接收数据。
USCI_x_SPI API被分成3组函数:
处理状态和初始化的函数,
处理数据的函数,
以及管理中断的函数。
处理状态和初始化的函数
USCI_A_SPI_initMaster(uint16_t baseAddress, USCI_A_SPI_initMasterParam ∗param)
//初始化SPI主机模式
USCI_A_SPI_initSlave(uint16_t baseAddress, uint8_t msbFirst, uint8_t clockPhase, uint8_t clockPolarity)
//初始化SPI从机模式
USCI_A_SPI_disable(uint16_t baseAddress)
//禁用SPI模块
USCI_A_SPI_enable(uint16_t baseAddress)
//启用SPI模块
USCI_A_SPI_changeMasterClock(uint16_t baseAddress, USCI_A_SPI_changeMasterClockParam ∗param)
//初始化SPI主时钟。在这个函数调用的末尾,SPI模块被保留为启用状态
USCI_A_SPI_isBusy(uint16_t baseAddress)
//指示SPI总线是否繁忙
USCI_B_SPI_initMaster(uint16_t baseAddress, USCI_B_SPI_initMasterParam ∗param)
//初始化SPI主机模式
USCI_B_SPI_initSlave(uint16_t baseAddress, uint8_t msbFirst, uint8_t clockPhase, uint8_t clockPolarity)
//初始化SPI从机模式
USCI_B_SPI_disable(uint16_t baseAddress)
//禁用SPI模块
USCI_B_SPI_enable(uint16_t baseAddress)
//启用SPI模块
USCI_B_SPI_changeMasterClock(uint16_t baseAddress, USCI_B_SPI_changeMasterClockParam ∗param)
//初始化SPI主时钟。在这个函数调用的末尾,SPI模块被保留为启用状态
USCI_B_SPI_isBusy(uint16_t baseAddress)
//指示SPI总线是否繁忙
参数
baseAddress
USCI_A0_BASE
USCI_A1_BASE
USCI_B0_BASE
USCI_B1_BASE
USCI_A_SPI_initMasterParam
//*****************************************************************************
//
//! \brief Used in the USCI_A_SPI_initMaster() function as the param parameter.
//
//*****************************************************************************
typedef struct USCI_A_SPI_initMasterParam {//! Selects Clock source.//! \n Valid values are://! - \b USCI_A_SPI_CLOCKSOURCE_ACLK//! - \b USCI_A_SPI_CLOCKSOURCE_SMCLKuint8_t selectClockSource;//! Is the frequency of the selected clock sourceuint32_t clockSourceFrequency;//! Is the desired clock rate for SPI communicationuint32_t desiredSpiClock;//! Controls the direction of the receive and transmit shift register.//! \n Valid values are://! - \b USCI_A_SPI_MSB_FIRST//! - \b USCI_A_SPI_LSB_FIRST [Default]uint8_t msbFirst;//! Is clock phase select.//! \n Valid values are://! - \b USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT [Default]//! - \b USCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXTuint8_t clockPhase;//! \n Valid values are://! - \b USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH//! - \b USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default]uint8_t clockPolarity;
} USCI_A_SPI_initMasterParam;
USCI_B_SPI_initMasterParam
//*****************************************************************************
//
//! \brief Used in the USCI_B_SPI_initMaster() function as the param parameter.
//
//*****************************************************************************
typedef struct USCI_B_SPI_initMasterParam {//! Selects Clock source.//! \n Valid values are://! - \b USCI_B_SPI_CLOCKSOURCE_ACLK//! - \b USCI_B_SPI_CLOCKSOURCE_SMCLKuint8_t selectClockSource;//! Is the frequency of the selected clock sourceuint32_t clockSourceFrequency;//! Is the desired clock rate for SPI communicationuint32_t desiredSpiClock;//! Controls the direction of the receive and transmit shift register.//! \n Valid values are://! - \b USCI_B_SPI_MSB_FIRST//! - \b USCI_B_SPI_LSB_FIRST [Default]uint8_t msbFirst;//! Is clock phase select.//! \n Valid values are://! - \b USCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT [Default]//! - \b USCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXTuint8_t clockPhase;//! \n Valid values are://! - \b USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH//! - \b USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default]uint8_t clockPolarity;
} USCI_B_SPI_initMasterParam;
msbFirst
//controls the direction of the receive and transmit shift register. Valid values are:
USCI_A_SPI_MSB_FIRST
USCI_A_SPI_LSB_FIRST //[Default]
clockPhase
//is clock phase select. Valid values are:
USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT //[Default]
USCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT
clockPolarity
//Valid values are:
USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH
USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default]
USCI_A_SPI_changeMasterClockParam
//*****************************************************************************
//
//! \brief Used in the USCI_A_SPI_changeMasterClock() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct USCI_A_SPI_changeMasterClockParam {//! Is the frequency of the selected clock sourceuint32_t clockSourceFrequency;//! Is the desired clock rate for SPI communicationuint32_t desiredSpiClock;
} USCI_A_SPI_changeMasterClockParam;
USCI_B_SPI_changeMasterClockParam
//*****************************************************************************
//
//! \brief Used in the USCI_B_SPI_changeMasterClock() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct USCI_B_SPI_changeMasterClockParam {//! Is the frequency of the selected clock sourceuint32_t clockSourceFrequency;//! Is the desired clock rate for SPI communicationuint32_t desiredSpiClock;
} USCI_B_SPI_changeMasterClockParam;
处理数据的函数
USCI_A_SPI_transmitData(uint16_t baseAddress, uint8_t transmitData)
//从SPI模块传输一个字节
USCI_A_SPI_receiveData(uint16_t baseAddress)
//接收已发送到SPI模块的字节
USCI_B_SPI_transmitData(uint16_t baseAddress, uint8_t transmitData)
//从SPI模块传输一个字节
USCI_B_SPI_receiveData(uint16_t baseAddress)
//接收已发送到SPI模块的字节
参数
baseAddress
USCI_A0_BASE
USCI_A1_BASE
USCI_B0_BASE
USCI_B1_BASE
transmitData
从SPI模块传输的数据
管理中断的函数
USCI_A_SPI_disableInterrupt(uint16_t baseAddress, uint8_t mask)
//禁用单个SPI中断源
USCI_A_SPI_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//启用单个SPl中断源
USCI_A_SPI_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//获取当前SPI中断状态
USCI_A_SPI_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除选择的SPl中断状态标志
USCI_B_SPI_disableInterrupt(uint16_t baseAddress, uint8_t mask)
//禁用单个SPI中断源
USCI_B_SPI_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//启用单个SPl中断源
USCI_B_SPI_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//获取当前SPI中断状态
USCI_B_SPI_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除选择的SPl中断状态标志
参数
baseAddress
USCI_A0_BASE
USCI_A1_BASE
USCI_B0_BASE
USCI_B1_BASE
USCI_A_SPI 的 mask
/*is the bit mask of the interrupt sources to be disabled. Mask value is the logical
OR of any of the following:*/
USCI_A_SPI_TRANSMIT_INTERRUPT
USCI_A_SPI_RECEIVE_INTERRUPT
USCI_B_SPI 的 mask
/*is the bit mask of the interrupt sources to be disabled. Mask value is the logical
OR of any of the following:*/
USCI_B_SPI_TRANSMIT_INTERRUPT
USCI_B_SPI_RECEIVE_INTERRUPT
DMA相关
USCI_A_SPI_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的SPI的RX缓冲区的地址
USCI_A_SPI_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的SPI的TX缓冲区的地址
USCI_B_SPI_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的SPI的RX缓冲区的地址
USCI_B_SPI_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的SPI的TX缓冲区的地址
参数
baseAddress
USCI_A0_BASE
USCI_A1_BASE
USCI_B0_BASE
USCI_B1_BASE