0%

MSP430单片机(六)——USCI-SPI模式

在墨水屏入门功能开发(一)中写到了SPI的应用,但对SPI并没有做深入的了解,正好借开发墨水屏的机会,从原理到墨水屏开发的实际应用来全面学习SPI。

SPI

SPI接口简介

SPI,是一种高速的,全双工(通信允许数据在两个方向上同时传输),同步的通信总线,在芯片的管脚上只占用四根线,节约了芯片的管脚,为PCB的布局节省空间。主要应用与实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

SPI内部结构

SPI接口一般使用4条线通信:

MISO主设备数据输入,从设备数据输出;
MOSI主设备数据输出,从设备数据输入;
SCLK时钟信号,由主设备产生;
CS从设备片选信号,由主设备控制。

MISO做主机时作为输入,作为从机时作为输出,MOSI则相反。

例:移位寄存器A数据为 10101010 ,移位寄存器B为 01010101 ,若进行信息传输,移位寄存器A作为主机,B作为从机,移位寄存器A的最高位“1”移至移位寄存器B的最高位,B的数据左移,将末位的 0 移至移位寄存器A。最终,移位寄存器A的数据变为 01010101,B的数据变为 10101010,实现了两个寄存器数据的互换。

移位寄存器在进行数据传输时,主机给从机传输N个字节,从机也会给主机传输回N个字节。所以SPI会有read()和write()函数,这是因为寄存器在进行字节传输时同时有接受和发送。

SPI工作原理总结

​ ① 硬件上为四根线;
​ ② 主机和从机都有一个串行移位寄存器,主机通过向它的SPI传销寄存器写入一个字节来发起一次传输;
​ ③ 串行移位寄存器通过MOSI信号线将字节传送给从机,从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机,这样,两个移位寄存器中的内容就被交换;
​ ④外设的写操作和读操作是同步完成的,如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

SPI特征

  • 3线全双工同步传输
  • 8位或者16位传输帧格式选择
  • 主或从操作
  • 支持多主模式
  • 可编程的时钟极性和相位
  • 可编程的数据顺序,MSB在前或者LSB在前
  • 可触发终端的专用发送和接受标志
  • SPI总线忙状态标志
  • 支持可靠通信的硬件CRC
    • 在发送模式下,CRC的值可以作为最后一个字节发送
    • 在全双工模式中对接收到的最后一个字节自动进行CRC校验
  • 支持DMA功能的1字节发送和接受缓冲器,产生发送和接受请求
时钟信号的相位和极性

在墨水屏的开发中,数据采样和时钟沿是绕不开的一个点,这两点与CPOL时钟极性和CPHA时钟相位的组合有关。

SPI时序图

SPI CR寄存器的CPOL和CPHA位,能够 0 1 组合成四种可能的时序关系。CPOL(时钟极性)位控制在没有数据传输时时钟的空闲状态电平,此位对主模式和从模式下的设备都有效。如果CPOL被清 0 ,SCK引脚在空状态保持低电平;如果CPOL被置 1 ,SCK引脚在空闲状态保持高电平。如果CPHA(时钟相位)位被置 1,SCK时钟的第二个边沿(CPOL位为0时就是下降沿,CPOL位为 1 时就是上升沿)进行数据位的采样,数据在第二个时钟边沿被锁存。如果CPHA位被清 0,SCK时钟的第一边沿(CPOL位位‘0’时就是下降沿,CPOL位为 1 时就是上升沿)进行数据位采样,数据在第一个时钟边沿被锁存。

以表格形式总结以上文字:

CPHA CPOL 采样时刻 SCK时钟
1 0 第二个时钟沿 上升沿
1 1 第二个时钟沿 下降沿
0 1 第一个时钟沿 下降沿
0 0 第一个时钟沿 上升
状态标志

应用程序通过3个状态标志可以完全监控SPI总线的状态。

发送缓冲器空闲标志(TXE)

此标志为“1”时表明发送缓冲器为空,下一个待发送的数据可进入缓冲器中。当写入SPI_DR时,TXE标志被清除。

接收缓冲器非空(RXNE)

此标志位为“1”时表明在接收缓冲器中包含有效的接收数据。读SPI数据寄存器可以清除此标志。

忙(BUSY)标志

BUSY标志由硬件设置与清除(写入此位无效果),此标志表明SPI通信层的状态。

SPI中断
中断事件 事件标志 使能控制位
发送缓冲器空标志 TXE TXEIE
接收缓冲器非空标志 RXNE RXNEIE
主模式失效事件 MODF ERRIE
溢出错误 OVR ERRIE
CRC错误标志 CRCERR ERRIE

USCI-SPI 模式

USCI-SPI模式简介

在同步模式下,USCI通过三个或四个引脚将设备连接到外部系统: UCxSIMOUCxSOMIUCxCLKUCxSTE 。 当 UCSYNC位置1时选择SPI模式,并通过 UCMODEx位选择SPI模式(3针或4针)。

在SPI模式下,串行数据通过主机提供的共享时钟由多个设备发送和接收。提供了一个额外的引脚UCxSTE,以使设备能够接收和发送数据,并由主机控制。

三个或四个信号用于SPI数据交换:

  • UCxSIMO 从机输入,主机输出主机模式: UCxSIMO 是数据输出线。从模式: UCxSIMO 是数据输入线。
  • UCxSOMI 从机输出,主机处于主机模式: UCxSOMI 是数据输入线。从模式: UCxSOMI 是数据输出线。
  • UCxCLK USCI SPI时钟主模式: UCxCLK 是输出。从模式: UCxCLK 是输入。
  • UCxSTE 从机发送使能。在4引脚模式下使用,以允许单个总线上有多个主机。在3针模式下不使用。见表17-1。
UCMODEx UCxSTE Active State UCxSTE Slave Master
01 High 0 Inactive Active
1 Active Inactive
10 Low 0 Active Inactive
1 Inactive Active

主从模式

主机模式:

要在主机模式下将数据接收到 USCI,必须将数据写入 UCxTXBUF ,因为接收和发送的操作是同时进行的。

image-20210126160915298

看图说话,工作流程如下:

数据移至 Transmit Buffer UCxTXBUF(TX数据缓冲区)USCI 启动数据传输 -> 数据被发送至 Transmit Shift Register(TX移位寄存器) -> 从 MSBLSB 开始在 UCxSIMO 上启动数据传输 -> 数据进入 Data Shift Register(DSR) 之后通过 UCxSOMI 将数据传至 Receive Shift Register(RX移位寄存器) -> 数据被传至 Receive Buffer UCxRXBUF ,同时接收中断标志 UCRXIFG 被置位(指示RX/TX操作已完成)

UCxSTE 的作用是防止与另一个主机冲突:

主机在SET为高电平时正常操作,SET为低电平时(另一台设备申请成为主机),当前主机驱动总线的MOSI和UCLK的引脚变为输入;

如果在主机被 UCxSTE 保持非活动状态时将数据写入 UCxTXBUF ,则一旦 UCxSTE 转换为主机活动状态,就会立即发送数据;

如果主机在活动状态被 UCxTXBUF 转换为非活动状态导致了传输终止,则必须将数据重写到 UCxTXBUF 中, UCxSTE 转换回主机活动状态时将重新进行传输

从机模式:

image-20210126161129878

工作流程如下:

UCxCLK 之前,数据被写入 UCxTXBUF -> 送至 TX Shift Register -> 在 UXcSOMI 上传输至 DSR -> 接收到设置的位数后,数据经 UCxSIMO 移至相对边缘的 RX Shift Register -> 最后送入 UCxRXBUF -> UCRXIFG 中断标志被置1,数据接收完成。

UCxSTE 的作用是当作发送和接受允许信号:

当SET为1时该从机禁止发送和接受数据;

注:1. UCxCLK 用作 SPI 时钟的输入,必须由外部主机提供,传输速率由该时钟决定而不由内部时钟发生器决定;2.若新数据移至 UCxRXBUF 之前没有将其中的旧数据读取的话,将会导致溢出错误位UCOE

寄存器

USCI_Ax Control Register 0 (UCAxCTL0)

USCI_Bx Control Register 0 (UCBxCTL0)

image-20210126163147114

USCI_Ax Control Register 1 (UCAxCTL1)

USCI_Bx Control Register 1 (UCBxCTL1)

image-20210126163537402

USCI_Ax Bit Rate Control Register 0 (UCAxBR0) / USCI_Ax Bit Rate Control Register 0 (UCAxBR0)

USCI_Ax Bit Rate Control Register 1 (UCAxBR1) / USCI_Bx Bit Rate Control Register 1 (UCBxBR1)

image-20210126163925932

程序

SPI初始化:

1
2
3
4
5
6
7
8
9
#define HAL_EPAPER_SPI_PRESCALER 	((uint8)(HAL_CPU_CLOCK_MHZ / 8.1) + 1)
void SPI_INIT(void)
{
UCB1CTL1 = UCSSEL1 | UCSWRST; //SMCLK、启用软复位
UCB1CTL0 = UCCKPL | UCMSB | UCMST | UCSYNC; //时钟极性高、MSB优先、UCMODE同步模式、同步模式打开
UCB1BR0 = HAL_EPAPER_SPI_PRESCALER; //设置频率
UCA0BR1 = 0; //
UCB1CTL1 &= ~UCSWRST; //关闭软复位
}

管脚初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
void IO_Init(void)
{
P2DIR &= ~BIT1; //LBUSY
P2REN |= BIT1;
P2OUT &= ~BIT1; //BUSY引脚上拉电阻
P2DIR |= BIT3; //RESET
P3DIR |= BIT6; //LCS
P5DIR |= BIT4; //LDC
P5SEL |= BIT5; //LSCK
P3SEL |= BIT7; //LSDA

HAL_EPAPER_SPI_INIT();
}
两种颜色的功德箱(逃