SPI概述:
SPI协议最初由Motorola公司(现为NXP Semiconductors的一部分)在20世纪80年代中期开发。最初是为了在其68000系列微控制器中实现高速、高效的串行通信。该协议旨在简化微控制器与外围设备之间的数据传输。
-
1980年代:SPI协议迅速被其他半导体制造商采纳,并逐渐成为嵌入式系统中的事实标准。尽管SPI从未被任何正式的标准组织或行业标准小组正式标准化,但它在实际应用中被广泛接受。
-
1990年代初:SPI协议被JEDEC(电子设备工程联合委员会)标准化,这进一步推动了其在电子行业中的广泛应用。
SPI(Serial Peripheral Interface,串行外围设备接口)是一种高速的、全双工、同步的通信总线,用于短距离通信,主要应用在嵌入式系统中。
-
高速:SPI的通信速率可以达到数兆比特每秒(Mbps),具体速率取决于硬件设计和应用场景。
-
全双工:SPI支持同时发送和接收数据,这意味着主设备和从设备可以在同一时间进行数据交换。
-
同步串行通信:SPI使用时钟信号来同步数据的传输。数据在时钟信号的控制下逐位传输,确保数据的准确性和同步性。
SPI信号线
SPI协议通常使用四根线(SCLK、MOSI、MISO、SS)。
-
SCLK(时钟线):由主设备提供时钟信号,用于同步数据传输。
-
MOSI(主设备数据输出,从设备数据输入):主设备向从设备发送数据。
-
MISO(主设备数据输入,从设备数据输出):从设备向主设备发送数据。
-
CS/SS(片选线):用于选择特定的从设备。一个主设备可以通过多条CS线连接多个从设备。
SCLK(Serial Clock)
MOSI(Master Out Slave In)
MISO(Master In Slave Out)
CS/SS(Chip Select / Slave Select)
SPI协议也可以根据需要简化为三根线。
-
半双工模式:合并MOSI/MISO为单一数据线(SDIO),通过方向控制切换传输方向。
SPI时序
SPI协议定义了四种工作模式(Mode 0、Mode 1、Mode 2、Mode 3),这些模式主要区别在于时钟信号的极性(CPOL/POL)和相位(CPHA/PHA)。
-
(POL=1, PHA=1):时钟空闲状态为高电平,数据在第一个时钟下降沿之后采样。
-
(POL=1, PHA=0):时钟空闲状态为高电平,数据在第一个时钟上升沿之后采样。
-
(POL=0, PHA=1):时钟空闲状态为低电平,数据在第一个时钟上升沿之后采样。
-
(POL=0, PHA=0):时钟空闲状态为低电平,数据在第一个时钟下降沿之后采样。
i.MX6ull SPI介绍
The Enhanced Configurable Serial Peripheral Interface (ECSPI) is a full-duplex,synchronous, four-wire serial communication block.The ECSPI contains a 64 x 32 receive buffer (RXFIFO) and a 64 x 32 transmit buffer(TXFIFO). With data FIFOs, the ECSPI allows rapid data communication with fewersoftware interrupts. The figure below shows a block diagram of the ECSPI.增强型可配置串行外设接口(Enhanced Configurable Serial Peripheral Interface,简称ECSPI)是一个全双工、同步、四线串行通信模块。ECSPI包含一个64x32的接收缓冲器(RXFIFO)和一个64x32的发送缓冲器(TXFIFO)。通过数据FIFO,ECSPI允许快速数据通信,减少软件中断。
ECSPI结构框图
ECSPI 关键特性
• Full-duplex synchronous serial interface全双工同步串行接口• Master/Slave configurable主/从可配置• Four Chip Select (SS) signals to support multiple peripherals四个片选(SS)信号以支持多个外设• Transfer continuation function allows unlimited length data transfers传输继续功能允许不限长度的数据传输• 32-bit wide by 64-entry FIFO for both transmit and receive data32位宽、64项的发送和接收数据FIFO(先进先出缓冲区)• Polarity and phase of the Chip Select (SS) and SPI Clock (SCLK) are configurable片选(SS)和SPI时钟(SCLK)的极性和相位可配置• Direct Memory Access (DMA) support直接内存访问(DMA)支持• Max operation frequency up to the reference clock frequency.最高操作频率可达参考时钟频率
ECSPI 时钟
ECSPI 模式
ECSPI支持三种模式:(Master Mode 主机模式),(Slave Mode 从机模式),(Low Power Modes 低功耗模式)
本文只介绍i.MX6ull开发板ECSPI的Master Mode 主机模式,Slave Mode 从机模式和Low Power Modes 低功耗模式可参考i.MX6ull开发板的数据手册
Master Mode 主机模式
When the ECSPI is configured as a master, it uses a serial link to transfer data between the ECSPI and an external slave device.当ECSPI(增强型可配置串行外设接口)被配置为主设备时,它使用串行链路在ECSPI和外部从设备之间传输数据。One of the Chip Select (SS) signals and the clock signal (SCLK) are used to transfer data between two devices. If the external device is a transmit-only device, the ECSPI master's output port can be ignored and used for other purposes. In order to use the internal TXFIFO and RXFIFO, two auxiliary output signals, Chip Select (SS) and SPI_RDY, are used for data transfer rate control. Software can also configure the sample period control register to a fixed data transfer rate.片选(SS)信号之一和时钟信号(SCLK)被用来在两个设备之间传输数据。如果外部设备仅为发送设备,可以忽略ECSPI主设备的输出端口,并将其用于其他目的。为了使用内部的发送FIFO(TXFIFO)和接收FIFO(RXFIFO),两个辅助输出信号,片选(SS)和SPI_RDY,被用于数据传输速率控制。软件也可以配置采样周期控制寄存器以设定一个固定的数据传输速率。When the ECSPI is in Master mode the SS, SCLK, and MOSI are output signals, and the MISO signal is an input当ECSPI处于主模式时,SS、SCLK和MOSI是输出信号,而MISO是输入信号。The Chip Select (SS) signal enables the selected external SPI device, and the SCLK synchronizes the data transfer.片选(SS)信号用于启用选定的外部SPI设备,而SCLK(时钟)信号则同步数据传输。
Master Mode with SPI_RDY
SPI_RDY信号是一个辅助控制信号,它在SPI通信中用于流量控制和数据传输同步。在某些情况下,SPI_RDY信号可以指示从机是否准备好接收数据,或者帮助主设备控制数据的发送节奏,避免从设备因过载而无法处理过多的数据。在数据传输速率较高的应用中,RDY允许主设备控制数据的发送节奏。如果多个设备连接到同一个SPI总线上,RDY信号可以帮助主设备分批次向各设备发送数据,提高了系统效率。
在ECSPI(增强型可配置串行外设接口)中,DRCTL位用于设置SPI_RDY信号,为0的话不关心SPI_RDY信号;为1的话SPI_RDY信号为边沿触发;为2的话SPI_DRY是电平触发。如果SPI Data Ready Control (ECSPI_CONREG[DRCTL])位包含01或10,SPI_RDY信号控制SPI突发的开始。如果ECSPI_CONREG[DRCTL]被设置为01,则只有在检测到SPI_RDY信号的下降沿时,SPI突发才能被触发。如果SPI Data Ready Control (ECSPI_CONREG[DRCTL])被设置为10,则只有在SPI_RDY信号为低时,SPI突发才能被触发。
SPI突发传输
一种在SPI通信协议下进行数据传输的方式,它允许在单个传输事务中连续传输多个数据字,从而提高数据传输效率。在这种模式下,主设备首先发送一个选择信号,然后可以连续发送多个数据字节,而从设备则可以在不发送响应信号的情况下接收这些数据字节。在传输完成后,主设备发送一个停止信号,以结束通信。
Master Mode with SS_CTL[3:0] Control
SS_CTL[3:0]决定了当前操作是单次突发还是多次突发。当SPI片选波形选择SS_CTL[3:0]被设置时,当前操作是多次突发传输。当SPI片选波形选择SS_CTL[3:0]位被清除时,当前操作是单次突发传输。一个SPI突发可以包含多个字,如ECSPI_CONREG寄存器中BURST LENGTH字段所定义。
Master Mode with Phase Control
The Phase Control (ECSPI_CONREG[PHA]) bit controls how the transmit data shifts out and the receive data shifts in.相位控制(ECSPI_CONREG[PHA])位决定了传输数据的移出方式和接收数据的移入方式。When the Phase control (ECSPI_CONREG[PHA]) bit is set, the transmit data will shift out on the rising edge of SCLK, and the receive data is latched on the falling edge of SCLK. The most-significant bit is output on the first rising SCLK edge. When ECSPI_CONREG[PHA] is cleared, the transmit data is shifted out on the falling edge of SCLK and the receive data is latched on the rising edge of SCLK. The MSB is output when the host processor loads the transmitted data.当相位控制(ECSPI_CONREG[PHA])位被设置时,传输数据将在SCLK(时钟)的上升沿移出,接收数据在SCLK的下降沿被锁存。最高有效位(MSB)在第一个SCLK上升沿被输出。
当ECSPI_CONREG[PHA]被清除时,传输数据在SCLK的下降沿移出,接收数据在SCLK的上升沿被锁存。MSB在主处理器加载要传输的数据时输出。
Inverting the SCLK polarity does not impact the edge-triggered operations because they are internal to the serial peripheral interface master.反转SCLK极性不会影响边沿触发操作,因为这些操作是串行外设接口主设备内部的。
ECSPI Reset
Whenever a device reset occurs, a reset is performed on the ECSPI, resetting all registers to their default values.Software can reset the block using the CONREG[EN] bit;每当发生设备复位时,ECSPI(增强型可配置串行外设接口)也会执行复位操作,将其所有寄存器重置为默认值。
软件可以通过设置CONREG寄存器中的[EN]位来复位ECSPI模块。
ECSPI Initialization
This section provides initialization information for ECSPI.To initialize the block:1. Clear the EN bit in ECSPI_CONREG to reset the block.复位模块:清除ECSPI_CONREG(ECSPI控制寄存器)中的EN位以复位该模块2. Enable the clocks for ECSPI within the CCM.使能时钟:在CCM(时钟控制模块)内为ECSPI使能时钟。
3. Configure the Control Register and then set the EN bit in the ECSPI_CONREG toput ECSPI out of reset.配置控制寄存器并退出复位:配置控制寄存器,然后在ECSPI_CONREG中设置EN位,使ECSPI退出复位状态。
4. Configure corresponding IOMUX for ECSPI external signals.配置IOMUX:为ECSPI的外部信号配置相应的IOMUX(输入/输出多路复用器)。
5. Configure registers of ECSPI properly according to the specifications of the external SPI device.正确配置ECSPI寄存器:根据外部SPI设备的技术规格,正确配置ECSPI的寄存器。
ECSPI重点寄存器
Receive Data Register (ECSPIx_RXDATA)
The Receive Data register (ECSPI_RXDATA) is a read-only register that forms the topword of the 64 x 32 receive FIFO. This register holds the data received from an external SPI device during a data transaction. Only word-sized read operations are allowed.接收数据寄存器(ECSPI_RXDATA)是一个只读寄存器,它构成了64x32接收FIFO(先进先出缓冲区)的顶部字。该寄存器保存了在数据事务期间从外部SPI设备接收到的数据。只允许进行字大小的读取操作。
Transmit Data Register (ECSPIx_TXDATA)
The Transmit Data (ECSPI_TXDATA) register is a write-only data register that formsthe bottom word of the 64 x 32 TXFIFO. The TXFIFO can be written to as long as it isnot full, even when the SPI Exchange bit (XCH) in ECSPI_CONREG is set. This allowssoftware to write to the TXFIFO during a SPI data exchange process. Writes to thisregister are ignored when the ECSPI is disabled (ECSPI_CONREG[EN] bit is cleared).发送数据(ECSPI_TXDATA)寄存器是一个只写的数据寄存器,它构成了64x32发送FIFO(先进先出缓冲区)的底部字。只要发送FIFO未满,就可以对其进行写入操作,即使在ECSPI_CONREG中的SPI数据交换位(XCH)被设置的情况下也是如此。这允许软件在SPI数据交换过程中向发送FIFO写入数据。当ECSPI被禁用(ECSPI_CONREG[EN]位被清除)时,对该寄存器的写入操作将被忽略。
Config Register (ECSPIx_CONFIGREG)
The Config Register (ECSPI_CONFIGREG) allows software to configure each SPIchannel, configure its operating modes, specify the phase and polarity of the clock,configure the Chip Select (SS), and define the HT transfer length. Note, HT mode is not supported by this product.配置寄存器(ECSPI_CONFIGREG)允许软件配置每个SPI通道,设置其工作模式,指定时钟的相位和极性,配置芯片选择(SS),以及定义HT(高吞吐量)传输长度。请注意,本产品不支持HT模式。
SCLK_CTL(23-20位):控制每个SPI通道的SCLK(时钟)非活动状态
- 0表示保持低电平。
- 1表示保持高电平。
DATA_CTL(19-16位):控制每个SPI通道数据线的非活动状态
- 0表示保持高电平。
- 1表示保持低电平。
SS_POL(15-12位):SPI SS(片选)极性选择
在主模式和从模式下,此字段选择Chip Select (SS)信号的极性。
- 0表示保持低电平。
- 1表示保持高电平。
SS_CTL(11-8位):SPI SS波形选择
在主模式下,当SMC(开始模式控制)位被清除时,此字段控制Chip Select (SS)信号的输出波形。如果设置了SMC位,则忽略SS_CTL。
在从模式下,此位控制SPI突发完成的时机。
- 0表示主模式下只传输一个SPI突发。
- 1表示主模式下在SPI突发之间否定Chip Select (SS)信号,传输多个SPI突发。
SCLK_POL(7-4位):SPI时钟极性控制
- 0表示活动高极性(0=空闲)。
- 1表示活动低极性(1=空闲)。
SCLK_PHA(7-4位):SPI时钟/数据相位控制
- 0表示相位0操作。
- 1表示相位1操作。
Control Register (ECSPIx_CONREG)
The Control Register (ECSPI_CONREG) allows software to enable the ECSPI ,
configure its operating modes, specify the divider value, and SPI_RDY control signal,
and define the transfer length.控制寄存器(ECSPI_CONREG)允许软件启用ECSPI(增强型串行外设接口),配置其工作模式,指定分频值和SPI_RDY控制信号,并定义传输长度。
BURST_LENGTH(31-20位):定义了要传输的SPI突发的长度
在主模式下,它控制每个SPI突发的位数。由于移位寄存器总是从传输FIFO加载32位数据,因此只有n个最低有效位(n = BURST_LENGTH + 1)将被移出,其余位将被忽略。最大可以传输2^12位。
CHANNEL_SELECT(19-18位):SPI通道选择位
在主模式下,通过断言Chip Select (SSn) 输出来选择外部从设备。一次只能激活选定的Chip Select (SSn) 信号;其余三个信号将被否定。
DRCTL(17-16位):SPI数据就绪控制
此字段选择在主模式下使用SPI_RDY信号。ECSPI在开始SPI突发之前会检查此字段。
- 10:突发将由SPI_RDY信号的低电平触发(电平触发)。
- 01:突发将由SPI_RDY信号的下降沿触发(边沿触发)。
- 00:SPI_RDY信号不关心。
PRE_DIVIDER(15-12位):SPI预分频器
ECSPI使用两级分频器生成SPI时钟。
POST_DIVIDER(11-8位):SPI后分频器
ECSPI使用两级分频器生成SPI时钟。
CHANNEL_MODE(7-4位):用于为每个SPI通道选择模式
- CHANNEL_MODE[3]:对应SPI通道3。
- CHANNEL_MODE[2]:对应SPI通道2。
- CHANNEL_MODE[1]:对应SPI通道1。
- CHANNEL_MODE[0]:对应SPI通道0。
- 0:从模式(Slave mode)。
- 1:主模式(Master mode)。
SMC:开始模式控制位
仅适用于配置为主模式的通道(CHANNEL_MODE=1)。控制ECSPI如何启动SPI突发,可以通过SPI交换位或立即在TXFIFO写入时启动。
- 0:SPI交换位(XCH)控制何时可以启动SPI突发。设置XCH位将启动一个或多个SPI突发,由SPI SS波形选择(SS_CTL)控制。
- 1:当数据写入TXFIFO时立即启动SPI突发。
XCH:SPI交换位
仅适用于配置为主模式的通道(CHANNEL_MODE=1)。如果开始模式控制(SMC)位被清除,向此位写入1将根据SPI SS波形选择(SS_CTL)启动一个或多个SPI突发。XCH位在数据交换进行中或ECSPI等待活动输入(如果通过DRCTL启用了SPIRDY)时保持设置。当TXFIFO和移位寄存器中的所有数据都被移出后,此位会自动清除。
0:空闲。
1:启动交换(写入)或忙(读取)。
EN(0位):SPI使能控制位
此位启用ECSPI。在写入其他寄存器或启动交换之前,必须设置此位。向此位写入零将禁用块并重置内部逻辑,ECSPI_CONREG除外。模块被禁用时,其内部时钟将被关闭。
- 0:禁用。
- 1:启用。
Status Register (ECSPIx_STATREG)
The ECSPI Status Register (ECSPI_STATREG) reflects the status of the ECSPI'soperating condition. If the ECSPI is disabled, this register reads 0x0000_0003.ECSPI状态寄存器(ECSPI_STATREG)反映了ECSPI(增强型可配置串行外设接口)的运行状态。 如果ECSPI被禁用,该寄存器的读数为0x0000_0003。
TC:传输完成状态位
写入1可以清除。
- 0:传输正在进行中。
- 1:传输已完成。
RO:RXFIFO溢出位
当该位被设置时,表示RXFIFO已溢出。写入1可以清除。
- 0:RXFIFO没有溢出。
- 1:RXFIFO已溢出。
RF:RXFIFO满位
当RXFIFO满时,该位被设置。
- 0:未满。
- 1:已满。
RDR:RXFIFO数据请求位
1.当RXTDE被清除时:
- 0:RXFIFO中的数据条目数不大于RX_THRESHOLD。
- 1:RXFIFO中的数据条目数大于RX_THRESHOLD。
2.当RXTDE被设置时:
- 0:RXFIFO中的数据条目数不大于RX_THRESHOLD。
- 1:RXFIFO中的数据条目数大于RX_THRESHOLD或存在DMA TAIL DMA条件。
RR:RXFIFO就绪位
当RXFIFO中存储了一个或多个字时,该位被设置。
- 0:RXFIFO中没有有效数据。
- 1:RXFIFO中有多个字。
TF:TXFIFO满位
当TXFIFO满时,该位被设置。
TDR:TXFIFO数据请求位。
- 1:TXFIFO中的有效数据槽数不大于TX_THRESHOLD。
- 0:TXFIFO中的有效数据槽数大于TX_THRESHOLD。
TE:TXFIFO空位
如果TXFIFO为空,该位被设置。
- 1:TXFIFO为空。
- 0:TXFIFO包含一个或多个字。
Test Control Register (ECSPIx_TESTREG)
The Test Control Register (ECSPI_TESTREG) provides software a mechanism tointernally connect the receive and transmit devices of the ECSPI, and monitor thecontents of the receive and transmit FIFOs.测试控制寄存器(ECSPI_TESTREG)为软件提供了一种机制,可以内部连接ECSPI的接收和发送设备,并监控接收和发送FIFO的内容。这使得开发者能够在调试过程中检查数据流,确保数据正确地在发送和接收设备之间传输,同时也可以用来测试ECSPI接口的功能是否正常工作。
LBC(31位):回环控制位。
此位仅在主模式下使用。当设置此位时,ECSPI内部连接发送器和接收器部分,移位寄存器中最高位的数据被回环到移位寄存器的最低位。这样,可以对完整的发送/接收路径进行自检。输出引脚不受影响,输入引脚被忽略。
- 0:未连接。
- 1:发送器和接收器部分内部连接以进行回环。
RXCNT(14-8位):RXFIFO计数器。指示RXFIFO中的字数。
TXCNT(6-0位):TXFIFO计数器。指示TXFIFO中的字数。
示例代码:
下面代码只是对i.MX6ull开发板中ECSPI模块的基础应用
#include "spi.h"
//管脚初始化
void spi_gpio_init()
{
/*IOMUXC_SW_MUX_CTL_PAD_UART2_TX_DATA
GPIO1_IO20 ECSPI3_SS0
1000 ALT8 — Select mux mode: ALT8 mux port: ECSPI3_SS0 of instance: ecspi3
*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO20 &= ~(0xf<<0);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO20 |= (0x8<<0);
/*IOMUXC_SW_MUX_CTL_PAD_UART2_RX_DATA
GPIO1_IO21 ECSPI3_SCLK
1000 ALT8 — Select mux mode: ALT8 mux port: ECSPI3_SCLK of instance: ecspi3
*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO21 &= ~(0xf<<0);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO21 |= (0x8<<0);
/*IOMUXC_SW_MUX_CTL_PAD_UART2_CTS_B
GPIO1_IO22 ECSPI3_MOSI
1000 ALT8 — Select mux mode: ALT8 mux port: ECSPI3_MOSI of instance: ecspi3
*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO22 &= ~(0xf<<0);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO22 |= (0x8<<0);
/*IOMUXC_SW_MUX_CTL_PAD_UART2_RTS_B
GPIO1_IO23 ECSPI3_MISO
1000 ALT8 — Select mux mode: ALT8 mux port: ECSPI3_MISO of instance: ecspi3
*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO23 &= ~(0xf<<0);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO23 |= (0x8<<0);
}
//SPI控制器初始化
/*
控制寄存器(ECSPI_CONREG)
允许软件启用ECSPI(增强型串行外设接口)
配置其工作模式 operating modes
指定分频值divider value和SPI_RDY控制信号
定义传输长度。
*/
void spi_control_init()
{
//将控制寄存器位清零
ECSPI3->CONREG = 0;
/* 定义SPI突发的长度
[31–20] BURST_LENGTH
0x07 A SPI burst contains the 8 LSB in a word.
*/
ECSPI3->CONREG |= (0X07<<20);
/*SPI数据准备控制,ECSPI在开始SPI突发前会检查此字段。
[17–16] DRCTL
00 The SPI_RDY signal is a don't care.
*/
/*SPI预分频器
[15–12] PRE_DIVIDER
*/
ECSPI3->CONREG |= (0x9<<12);
/*SPI后分频器
[11–8] POST_DIVIDER
*/
ECSPI3->CONREG |= (0x1<<8);
/*启动模式控制,控制ECSPI如何开始SPI突发
[3] SMC
1 Immediately starts a SPI burst when data is written in TXFIFO.
*/
ECSPI3->CONREG |= (0x1<<3);
/*SPI块使能控制
[0] EN
0 Disable the block.
1 Enable the block
*/
ECSPI3->CONREG |= (0x1<<0);
}
//配置SPI通道
/*
配置寄存器(ECSPI_CONFIGREG)
允许软件配置每个SPI通道
设置其工作模式
指定时钟的相位和极性
配置芯片选择(SS)---*使用外部片选
定义HT(高吞吐量)传输长度。
请注意,本产品不支持HT模式。
*/
void spi_channel_config(uint_fast8_t channel,uint_fast8_t polarity,uint_fast8_t phase)
{
/*用于选择四个外部SPI主/从设备中的一个进行通信
通过断言相应的Chip Select (SSn) 输出来选择外部从设备
SPI通信中,Chip Select信号用于通知从设备何时开始和结束数据传输。
控制寄存器(ECSPI_CONREG)[19-18] CHANNEL_SELECT
eg:00:选择通道0,此时Chip Select 0 (SS0) 将被断言。与SS0关联的从设备会被激活
*/
ECSPI3->CONREG |= (channel<<18);
/*控制每个SPI通道的SCLK(时钟)信号在非活动状态下的电平。
SCLK_CTL [23-20]
SCLK CTL[3] is for SPI channel 3.
SCLK CTL[2] is for SPI channel 2.
SCLK CTL[1] is for SPI channel 1.
SCLK CTL[0] is for SPI channel 0.
0 Stay low.
1 Stay high.
*/
ECSPI3->CONFIGREG &= ~(0xf<<20);
ECSPI3->CONFIGREG |= (polarity<<(channel+20));
/*控制每个SPI通道的数据线在非活动状态下的电平。
DATA_CTL [19-16]
0 Stay high.
1 Stay low.
*/
ECSPI3->CONFIGREG &= ~(0xf<<16);
ECSPI3->CONFIGREG |= (1<<(channel+16));
/*选择每个SPI通道的Chip Select(CS)信号的极性。
SS_POL [15-12]
0 Active low.
1 Active high.
*/
ECSPI3->CONFIGREG &= ~(0xf<<12);
ECSPI3->CONFIGREG &= ~(1<<(channel+12));
/*SPI通道选择模式
控制寄存器(ECSPI_CONREG)[7–4] CHANNEL_MODE
0 Slave mode.
1 Master mode.
*/
ECSPI3->CONREG |= (1<<(channel+4));
/*
SCLK_POL (7-4) SPI时钟极性控制
0 Active high polarity (0 = Idle).
1 Active low polarity (1 = Idle).
*/
ECSPI3->CONFIGREG |= (polarity<<(channel+4));
/*
SCLK_PHA (3-0) SPI时钟/数据相位控制
0 Phase 0 operation.
1 Phase 1 operation.
*/
ECSPI3->CONFIGREG |= (phase<<(channel));
}
/*
ECSPI状态寄存器(ECSPI_STATREG)
用于反映ECSPI(增强型串行外设接口)的运行状态
*/
//发送数据
uint_fast32_t spi_Transfer_data(uint_fast8_t data)
{
uint_fast32_t resultdata;
/*保存输入的数据
Transmit Data Register (ECSPIx_TXDATA)
数据由软件写入,以供SPI硬件在数据传输过程中发送。
*/
ECSPI3->TXDATA = data;
/*判断数据是否传入TXFIFO
TE [0]
0 TXFIFO contains one or more words.
1 TXFIFO is empty
*/
while(ECSPI3->STATREG & (0x1<<0))
{
}
/*判断传输是否完成
TC [7]
Transfer Completed Status bit. Writing 1 to this bit clears it.
0 Transfer in progress.
1 Transfer completed.
*/
while(!(ECSPI3->STATREG & (0x1<<7)))
{
}
/*判断数据是否接收到数据
[3] RR 指示接收FIFO(RXFIFO)中的数据状态
0 No valid data in RXFIFO.
1 More than 1 word in RXFIFO.
*/
while(!(ECSPI3->STATREG & (0x1<<3)))
{
}
/*保存接收到的的数据
Receive Data Register (ECSPIx_RXDATA)
用于存储在数据传输期间从外部SPI设备接收到的数据
ECSPI_RXDATA寄存器的读取操作必须是字大小的
*/
resultdata = ECSPI3->RXDATA;
return resultdata;
}
//片选信号
void spi_cs_start()
{
GPIO1->GDIR |= (0x1<<20);
GPIO1->DR &= ~(0x1<<20);
}
void spi_cs_stop()
{
GPIO1->DR |= (0x1<<20);
}
void test_spi()
{
spi_gpio_init();
spi_control_init();
spi_channel_config(1,0,1);
uint_fast32_t tmpchar;
for(tmpchar='A';tmpchar<='Z';tmpchar++)
{
spi_cs_start();
uint_fast8_t result = spi_Transfer_data(tmpchar);
spi_cs_stop();
uart_printf("char:%c\r\n",result);
gpt_delay_seconds(1);
}
}
结语:
无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力