SPI(Serial Peripheral Interface)串行外围设备接口

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介绍 

i.MX6ull开发板提供了一种增强型可配置的SPI--Enhanced Configurable SPI (ECSPI)
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 fewer
software 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 data
32位宽、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 to
put 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 top
word 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 forms
the bottom word of the 64 x 32 TXFIFO. The TXFIFO can be written to as long as it is
not full, even when the SPI Exchange bit (XCH) in ECSPI_CONREG is set. This allows
software to write to the TXFIFO during a SPI data exchange process. Writes to this
register 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 SPI
channel, 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's
operating 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 to
internally connect the receive and transmit devices of the ECSPI, and monitor the
contents 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);
    }
}

结语:

无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964300.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习 Pytorch 基础网络手动搭建与快速实现

为了方便后续练习的展开&#xff0c;我们尝试自己创建一个数据生成器&#xff0c;用于自主生成一些符合某些条件、具备某些特性的数据集。 导入相关的包 # 随机模块 import random# 绘图模块 import matplotlib as mpl import matplotlib.pyplot as plt# 导入numpy import nu…

10分钟快速上手DeepSeek!

DeepSeek 是一款基于命令行和配置文件的数据处理工具&#xff0c;支持多种数据格式&#xff08;如 CSV、JSON、SQL 等&#xff09;和多种数据源&#xff08;如本地文件、数据库、API 等&#xff09;。 它的核心功能包括&#xff1a; 数据导入与导出&#xff1a;支持从多种数据…

【现代深度学习技术】深度学习计算 | 延后初始化自定义层

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

Redis --- 秒杀优化方案(阻塞队列+基于Stream流的消息队列)

下面是我们的秒杀流程&#xff1a; 对于正常的秒杀处理&#xff0c;我们需要多次查询数据库&#xff0c;会给数据库造成相当大的压力&#xff0c;这个时候我们需要加入缓存&#xff0c;进而缓解数据库压力。 在上面的图示中&#xff0c;我们可以将一条流水线的任务拆成两条流水…

Rust HashMap :当储物袋遇上物品清单

开场白&#xff1a;哈希映射的魔法本质 在Rust的奇幻世界里&#xff0c;HashMap就像魔法师的储物袋&#xff1a; 键值对存储 → 每个物品都有专属咒语&#xff08;键&#xff09;和实体&#xff08;值&#xff09;快速查找 → 念咒瞬间召唤物品动态扩容 → 自动伸展的魔法空间…

LabVIEW的智能电源远程监控系统开发

在工业自动化与测试领域&#xff0c;电源设备的精准控制与远程管理是保障系统稳定运行的核心需求。传统电源管理依赖本地手动操作&#xff0c;存在响应滞后、参数调节效率低、无法实时监控等问题。通过集成工业物联网&#xff08;IIoT&#xff09;技术&#xff0c;实现电源设备…

C# Winform制作一个登录系统

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登录 {p…

尝试把clang-tidy集成到AWTK项目

前言 项目经过一段时间的耕耘终于进入了团队开发阶段&#xff0c;期间出现了很多问题&#xff0c;其中一个就是开会讨论团队的代码风格规范&#xff0c;目前项目代码风格比较混乱&#xff0c;有的模块是驼峰&#xff0c;有的模块是匈牙利&#xff0c;后面经过讨论&#xff0c;…

Docker技术相关学习三

一、Docker镜像仓库管理 1.docker仓库&#xff1a;用于存储和分发docker镜像的集中式存储库&#xff0c;开发者可以将自己创建的镜像推送到仓库中也可以从仓库中拉取所需要的镜像。 2.docker仓库&#xff1a; 公有仓库&#xff08;docker hub&#xff09;&#xff1a;任何人都可…

挑战项目 --- 微服务编程测评系统(在线OJ系统)

一、前言 1.为什么要做项目 面试官要问项目&#xff0c;考察你到底是理论派还是实战派&#xff1f; 1.希望从你的项目中看到你的真实能力和对知识的灵活运用。 2.展示你在面对问题和需求时的思考方式及解决问题的能力。 3.面试官会就你项目提出一些问题&#xff0c;或扩展需求…

Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践

title: Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践 date: 2025/2/4 updated: 2025/2/4 author: cmdragon excerpt: PostgreSQL 作为开源关系型数据库的佼佼者,因其强大的功能与性能被广泛应用于各种项目中。而 Python 则因其简洁易用的语法、丰富的库和强大的…

计算机从何而来?计算技术将向何处发展?

计算机的前生&#xff1a;机械计算工具的演进 算盘是计算机的起点&#xff0c;它其实是一台“机械式半自动化运算器”。打算盘的“口诀”其实就是它的编程语言&#xff0c;算盘珠就是它的存储器。 第二阶段是可以做四则运算的加法器、乘法器。1642年&#xff0c;法国数学家帕斯…

【Blazor学习笔记】.NET Blazor学习笔记

我是大标题 我学习Blazor的顺序是基于Blazor University&#xff0c;然后实际内容不完全基于它&#xff0c;因为它的例子还是基于.NET Core 3.1做的&#xff0c;距离现在很遥远了。 截至本文撰写的时间&#xff0c;2025年&#xff0c;最新的.NET是.NET9了都&#xff0c;可能1…

MapReduce分区

目录 1. MapReduce分区1.1 哈希分区1.2 自定义分区 2. 成绩分组2.1 Map2.2 Partition2.3 Reduce 3. 代码和结果3.1 pom.xml中依赖配置3.2 工具类util3.3 GroupScores3.4 结果 参考 本文引用的Apache Hadoop源代码基于Apache许可证 2.0&#xff0c;详情请参阅 Apache许可证2.0。…

重生之我在异世界学编程之C语言:深入指针篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文&#xff08;1&#xff09;内置数…

deep generative model stanford lecture note3 --- latent variable

1 Introduction 自回归模型随着gpt的出现取得很大的成功&#xff0c;还是有很多工程上的问题并不是很适合使用自回归模型&#xff1a; 1&#xff09;自回归需要的算力太大&#xff0c;满足不了实时性要求&#xff1a;例如在自动驾驶的轨迹预测任务中&#xff0c;如果要用纯自回…

STM32_SD卡的SDIO通信_DMA读写

本篇&#xff0c;将使用CubeMXKeil&#xff0c;创建一个SD卡的DMA读写工程。 目录 一、简述 二、CubeMX 配置 SDIO DMA 三、Keil 编辑代码 四、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、简述 上篇已简单介绍了SD、SDIO&#xff0c;本篇不再啰嗦&#xff0c;…

互联网行业常用12个数据分析指标和八大模型

本文目录 前言 一、互联网线上业务数据分析的12个指标 1. 用户数据&#xff08;4个&#xff09; (1) 存量&#xff08;DAU/MAU&#xff09; (2) 新增用户 (3) 健康程度&#xff08;留存率&#xff09; (4) 渠道来源 2. 用户行为数据&#xff08;4个&#xff09; (1) 次数/频率…

【学术投稿-2025年计算机视觉研究进展与应用国际学术会议 (ACVRA 2025)】从计算机基础到HTML开发:Web开发的第一步

会议官网&#xff1a;www.acvra.org 简介 2025年计算机视觉研究进展与应用&#xff08;ACVRA 2025&#xff09;将于2025年2月28-3月2日在中国广州召开&#xff0c;将汇聚世界各地的顶尖学者、研究人员和行业专家&#xff0c;聚焦计算机视觉领域的最新研究动态与应用成就。本次…

【Unity踩坑】Unity项目管理员权限问题(Unity is running as administrator )

问题描述&#xff1a; 使用Unity Hub打开或新建项目时会有下面的提示。 解决方法&#xff1a; 打开“本地安全策略”&#xff1a; 在Windows搜索栏中输入secpol.msc并回车&#xff0c;或者从“运行”对话框&#xff08;Win R&#xff0c;然后输入secpol.msc&#xff09;启…