<!-- 本文件由脚本自动转换生成，请勿手动编辑 -->

> **《LKS32MC09x User Manual》SPI** . 完整目录见 [README.md](README.md)
>
> **声明**：本文档由芯片用户手册自动转换生成，仅供检索与查阅参考。Markdown 格式可被自由编译、修改，本文档不构成正式技术文件，相关内容以凌鸥创芯官方网站正式发布的手册为准。
>
> 南京凌鸥创芯电子有限公司 . (C) 2023, 版权归凌鸥创芯所有 . 机密文件，未经许可不得扩散

# SPI

## 概述

SPI接口主要使用在，外部设计采用SPI协议的应用场景下。SPI的工作模式软件可选，默认为SPI
Motorola模式。SPI接口支持全双工传输和半双工传输。当接口配置为Master模式时，可发送时钟信号供外部Slave设备使用。

## 主要特性

- 支持Master和Slave操作
- 全双工传输，可根据应用情况，使用3根或者4根信号线
- 支持半双工传输，可根据应用情况，使用2根信号线
- 可编程的时钟极性和相位
- 可编程的数据顺序:MSB或LSB
- 最快传输速度为系统最高时钟频率的1/8
- 片选信号均可选。Master模式下，片选信号可以软件控制也可以硬件产生；Slave模式下，片选信号可以恒定有效，也可以来自外界设备
- 无本地FIFO，支持DMA操作。包含溢出检测和片选信号异常检测
- 数据长度8-Bit～16-Bit可调

## 功能描述

### 功能框图

本接口采用同步串行设计，实现MCU同外部设备之间的SPI传输。支持轮询和中断方式获得传输状态信息。本接口的主要功能模块如下图所示。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-1 SPI模块结构框图

接口信号包括，spi_din，spi_dout，sclk_in，sclk_out，ss_in和ss_out。

spi_din:接口接收的数据信号。同SPI协议比较，当接口配置为Master模式时，其等效为MISO；当接口配置为Slave模式时，其等效为MOSI。

spi_dout:接口发送的数据信号。同SPI协议比较，当接口配置为Master模式时，其等效为MOSI；当接口配置为Slave模式时，其等效为MISO。

sclk_in:接口接收的时钟信号。此时，接口的工作模式为Slave。非Slave模式下，此信号输入无效。

sclk_out:接口发送的时钟信号。此时，接口的工作模式为Master，非Master模式下，此信号输出恒定为0。

ss_in:接口接收的片选信号。此时，接口的工作模式为Slave。非Slave模式下，此信号输入无效。

ss_out:接口发送的片选信号。此时，接口的工作模式为Master。非Master模式下，此信号输出恒定为1。

### 功能说明

#### 全双工模式

默认情况下，SPI接口配置为全双工模式。此时，数据传输需要两根数据线。数据信号的变化，发生在时钟信号的边沿，即同步于时钟信号。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

接口为Master模式时:

- spi_din为数据输入，接外部Slave设备的MISO
- spi_dout为数据输出，接外部Slave设备的MOSI
- spi_ss_out为片选信号，根据应用情况选择是使用该信号还是软件控制其它GPIO实现

接口为Slave模式时:

- spi_din为数据输入，接外部Master设备的MOSI
- spi_dout为数据输出，接外部Master设备的MISO
- spi_ss_in为片选信号，根据应用情况是使用该信号还是片选恒有效

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-2a SPI接口全双工主模式互连框图

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-2b SPI接口全双工从模式互连框图

从上图可知，GPIO若配置为输出，则SPI接口可发送数据；GPIO若配置为输入，则SPI接口可接收数据。

#### 半双工模式

SPI接口可配置为半双工模式。此时，数据传输只需要一根数据线。数据信号的变化，发生在时钟信号的边沿，即同步于时钟信号。一次传输只能是一个方向的，要不就是发送，要不就是接收。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-3 SPI接口半双工模式互连框图

注意，上图中若本接口做Master，则clk为本接口的输出信号；若本接口做Slave，则clk为本接口的输入信号。

仅发送

SPI_CFG.
DUPLEX配置为2，半双工发送模式有效。此时，本接口只能发送数据。GPIO_0的oe使能，发送spi_dout数据到外界；GPIO_0的ie关闭，spi_din恒定输入为0。此模式下，支持Master/Slave模式下的发送。

仅接收

SPI_CFG.
DUPLEX配置为3，半双工接收模式有效。此时，本接口只能接收数据。GPIO_0的oe关闭，spi_dout无法发送数据到外界；GPIO_0的ie开启，spi_din接收来自外部的数据。此模式下，支持Master/Slave模式下的接收。

注意，全双工下是两个GPIOx用于数据传输，半双工下可从中任意选一个GPIOx用于数据传输，且半双工模式下，din与dout可通过配置GPIOx进行输入/输出互换。

#### 片选信号

本接口做Slave模式时，片选信号可选，SPI_CFG.CS决定片选来源。ss为Master设备发出的选通使能信号，低电平有效。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-4 SPI模块Slave模式片选信号选择

本接口做Master模式时，片选信号亦可选。模块硬件产生了标准的片选信号，实际应用可屏蔽此信号通过软件操作额外的GPIO实现。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-5 SPI模块Master模式片选信号选择

注意，图8-5虚线仅表示不确定。若使用spi_ss_out为ss的源头，那么将GPIO_0同外界设备互连；若使用软件操作GPIO的方式，那么可将GPIO_1同外界设备互连。

#### 通讯格式

在SPI通讯过程中，发送或者接收操作均是基于SPI时钟的。通讯格式受到SPI_CFG.
SAMPLE和SPI\_ CLK_POL控制。SPI_CFG. SAMPLE为Phase控制位，SPI\_
CLK_POL为Polarity控制位。

Polarity控制了SPI时钟信号在默认情况下的电平状态。Polarity为0时，默认时钟电平为低电平；Polarity为1时，默认电平为高电平。

Phase控制了SPI数据的发送/接收时刻。Phase为0时，时钟从默认电平到第一个跳变边沿为采样数据时刻，Phase为1时，时钟从默认电平到第一个跳变边沿为发送数据时刻。

（1）当polarity为0时，默认时钟为低电平，第一个跳变沿为上升沿，此时:

如左上图，当phase为0时:第一个上升沿为采样数据时刻，第一个下降沿为发送数据时刻；

如右上图，当phase为1时:第一个上升沿为发送数据时刻，第一个下降沿为采样数据时刻；

（2）当polarity为1时，默认时钟为高电平，第一个跳变沿为下降沿，此时:

如左下图，当phase为0时:第一个下降沿为发送数据时刻，第一个上升沿为采样数据时刻；

如右下图，当phase为1时:第一个下降沿为采样数据时刻，第一个上升沿为发送数据时刻；

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

#### 数据格式及长度

SPI数据传输格式分成两种:MSB和LSB。数据传输格式受到SPI_CFG.ENDIAN控制。注意，在数据传输过程中硬件自动实现传输格式的转换，无需软件介入。

SPI数据长度可配，范围是从8-Bit到16-Bit。SPI_SIZE.BITSIZE控制长度。

#### DMA传输

在大容量数据传输应用下，SPI接口支持DMA传输，减轻MCU的负担。一次传输，最大传输量为由DMA模块决定，最小传输量为1字节。在全双工模式下，接收和发送均可实现DMA传输；在半双工模式下，仅接收或发送实现DMA传输。

在接收到新的数据后，硬件自动产生DMA请求，通过DMA模块将数据搬移到RAM中。在发送新数据前，硬件自动产生DMA请求，通过DMA模块将数据从RAM中搬移到SPI接口。因SPI无FIFO，SPI发送一次DMA请求，DMA只能搬移一个字节数据。**若要实现多字节搬移，DMA需配置为多轮搬移，每一轮搬移一个字节的方式**。

DMA传输需要配置DMA模块相应寄存器。

因SPI接口支持DMA传输，也支持MCU传输。两者区别在于--DMA传输，发送的数据来自DMA的搬移；MCU传输，发送的数据来自MCU的搬移。

DMA传输，推荐软件配置流程如下:

- 初始化DMA模块，将本次发送的数据来源，接收的数据去向配置好，传输长度配置完毕。
- 初始化GPIO模块，将SPI复用的GPIO配置完毕。
- 初始化SPI接口，SPI_IE/SPI_CFG/SPI_BAUD/SPI_SIZE等寄存器配置完毕。
- 触发SPI接口，进入发送/接收状态。触发条件是MCU对SPI_TXDATA寄存器执行写操作，因最终发送的数据来自DMA，本次MCU写入的数据不会混入SPI发送流程。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图 8-6 SPI DMA 数据流与握手逻辑框图

#### MCU传输

一次只能发送/接收一个SPI_SIZE.BITSIZE长度的数据，每次完成后需要通过中断或者轮询的方式判断传输是否完成。无论是主模式还是从模式，写SPI_TXDATA寄存器，才能触发传输。主模式为主动发送，从模式为加载数据到发送队列等待主模式发出时钟信号，开始传输。推荐软件配置流程如下:

- 初始化GPIO模块，将SPI复用的GPIO配置完毕。
- 初始化SPI接口，SPI_IE/SPI_CFG/SPI_BAUD/SPI_SIZE等寄存器配置完毕。
- MCU对SPI_TXDATA寄存器执行写操作，触发SPI接口进入发送流程。从模式下，数据加载到内部状态机等待主设备发起读取操作；主模式下，触发发送。

**注意:若需要连续发送，则需要重新配置SPI_TXDATA寄存器。通过中断或者轮询方式获得传输完毕信息。**

**【图片已删除】**图
8-7 SPI 传输的软件配置与操作流程

#### 外部事件传输

在大容量数据传输应用下，SPI接口支持DMA传输。传输过程中，可被打断也可不被打断。所谓打断是指，当前字节传输完成，需等待外部事件才开始下一个字节的传输；不打断是指，当前字节传输完成，直接下一个字节的传输。打断模式需要同其它模块配合使用。例如定时器模块，定时器可触发下一字节的传输。打断模式仅在Master模式有效。SPI_IE.TRANS_TRIG控制了是否使用打断模式。

#### 中断处理

SPI接口包含三种类型的中断事件，分别是:数据传输完成事件，异常事件和溢出事件。

- 数据完成事件，当前数据传输完成。高电平有效，对SPI_IE.
  CMPLT_IF写1清除。
- 异常事件，SPI接口为Slave模式，若在传输过程中片选信号受到干扰，被拉高，将产生片选异常事件。高电平有效，对SPI_IE.
  AB_IF写1清除。
- 溢出事件，SPI_RX_DATA寄存器数据没有及时被读走，，将产生溢出事件。高电平有效，对SPI_IE.
  OV_IF写1清除。

上述事件，默认是不触发SPI中断，可以通过配置SPI_IE\[7:4\]使能事件产生中断。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图8-6 SPI模块中断选信号产生图

数据传输完毕后，可通过DMA中断或者SPI自身中断判断结束。

- 发送模式下，DMA先完成搬移操作，SPI后发送完毕。SPI发送完毕，可作为本次传输完成标识。
- 接收模式下，SPI接收完毕，触发DMA搬移。DMA搬移完成，可作为本次传输完成标识。

溢出事件。在全双工模式下，发送和接收的DMA均有效，一般情况下不会发送溢出事件；在半双工模式下，只有发送（或接收），此时硬件屏蔽了接收（或发送）的溢出判断

#### 波特率设置

SPI接口时钟通过对系统时钟分频获得，分频系数来自SPI_BAUD.
BAUD。SPI传输波特率配置计算公式为:

SPI传输波特率 = 系统时钟 / (2\*(BAUD + 1))

SPI协议为半拍协议，上升沿发送数据，下降沿采集数据；或者下降沿发送数据，上升沿采样数据。

SPI接口采用同步设计，需要对外部设备的信号进行同步采样，同步时钟为系统时钟。数据和时钟信号（此时为Slave模式）的同步，需要两拍系统时钟。考虑到时钟相位的偏移，此时需要一拍系统时钟的冗余，由此推导出最快的SPI传输波特率为系统时钟的1/8，高电平周期为四拍系统时钟，低电平周期为四拍系统时钟。因此，SPI_BAUD.BAUD的配置值不能小于3。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-1I2C模块顶层功能框图

I2C接口同外界通讯只有SCL和SDA两根信号线。SDA为双向复用信号线，受到sda_oe控制。模块级，I2C接口信号包括，scl_i，sda_i，scl_o，sda_o和sda_oe。

scl_i:时钟信号。当I2C接口配置为从模式时，此为I2C总线的时钟输入信号。

sda_i:数据信号。当I2C接口接收数据时（无论主模式还是从模式），此为I2C总线的数据输入信号。

scl_o:时钟信号。当I2C接口配置为主模式时，此为I2C总线的时钟输出信号。

sda_o:数据信号。当I2C接口发送数据时（无论主模式还是从模式），此为I2C总线的数据输出信号。

sda_oe:数据使能信号。当sda_o输出时，sda_oe有效；当sda_i输入时，sda_oe无效。

### 功能说明

I2C模块接收和发送数据，并将数据从串行转换成并行，或并行转换成串行。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。

#### 模式选择

接口可以下述4种模式中的一种运行:

- 从发送模式
- 从接收模式
- 主发送模式
- 主接收模式

I2C接口默认主从均不使能。接口根据配置情况，进入主模式或者从模式。当仲裁丢失或产生停止信号时，主模式自动释放总线并产生相应异常中断。允许多主机功能。

主模式时，I2C接口启动数据传输并产生时钟信号。串行数据传输总是以起始条件开始并以停止条件结束。起始条件和停止条件都是在主模式下由软件控制产生。

从模式时，I2C接口能识别它自己的地址(7位)。软件能够控制开启或禁止硬件地址比较功能，硬件地址比较功能可降低MCU的负担。只有地址匹配才通知MCU进行相关处理。

数据和地址按8位/字节进行传输，高位在前。跟在起始条件后的1个字节是地址。地址只在主模式发送。

在一个字节传输的8个时钟后的第9个时钟期间，接收器必须回送一个应答位(ACK)给发送器。

软件可以开启或禁止应答(ACK)，并可以设置I2C接口的地址。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-2基本I2C传输时序图

I2C接口没有FIFO，若一次性发送大量数据，为了降低MCU的负担，需DMA配合。I2C接口支持DMA传输（多字节传输）和非DMA传输（单字节传输）。上述四种传输模式进一步扩展为:

- 从模式单字节发送，从模式DMA发送
- 从模式单字节接收，从模式DMA接收
- 主模式单字节发送，主模式DMA发送
- 主模式单字节接收，主模式DMA接收

一般情况下，非DMA方式时，一次传输一个字节（可反复单次传输，需软件介入提供数据）。DMA方式，一次连续传输可以多字节（最大不超过32字节，极端情况一次传输一个字节，因无FIFO，每次DMA请求，仅传输一个字节，多轮完成本次数据传输）。

上述所有模式，遵循如下基本原则:

- 单字节发送，中断将在8-bit数据发送完毕且收到响应后（ACK/NACK均可）产生。
- 单字节接收，中断将在8-bit数据接收完毕后产生。
- DMA发送，正常情况下，中断将在数据发送完毕且收到响应后（ACK/NACK均可）产生。
- DMA接收，正常情况下，中断将在数据接收完毕后产生。
- 当I2C接口配置为主模式时，检测到错误后，I2C接口会主动释放总线，恢复到起始状态并产生中断信号。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-3 I2C传输模式决策与执行流程图

#### 从模式

默认情况下，I2C接口主模式和从模式均关闭。若工作在从模式，需使能从模式。为了产生正确的时序，必须通过系统寄存器SYS_CLK_DIV0设定I2C接口的工作时钟频率，I2C接口时钟基于系统高速主时钟进行分频，SYS_CLK_DIV0是I2C接口工作时钟的分频系数。

- 从模式下，I2C接口时刻在监控总线上的信号。一旦检测到起始条件，其将保存地址位数据和读写位数据。
- 从模式下，若硬件地址匹配功能开启，只有地址匹配的情况下，才会产生中断，通知MCU进行后续处理。若没有开启，每次收到地址及读写位数据，都将产生中断。
- 从模式下，单字节接收模式。每次收到一个字节的数据后，产生中断，此时I2C接口可拉低SCL，直至中断完成，继续后续操作。
- 从模式下，单字节发送模式。每次发送一个字节完毕后且收到响应（ACK/NACK），产生中断，此时I2C接口可拉低SCL，直至中断完成，继续后续操作。
- 从模式下，DMA接收模式。每次收到SIZE约定后的数据，产生中断，此时I2C接口可拉低SCL，直至中断完成。
- 从模式下，DMA发送模式。每次发送SIZE约定后的数据并收到响应（ACK/NACK），产生中断，此时I2C接口可拉低SCL，直至中断完成。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-5从模式传输示意图

##### 从模式发送

地址匹配后，从发送器将字节从I2C_DATA寄存器经由内部移位寄存器发送到SDA线上。在I2C_DATA数据没有准备好之前，从设备可拉底SCL，直到待发送数据已写入I2C_DATA寄存器。I2C接口在发送完毕每个字节后都执行下列操作:

- 如果接收到ACK位，装载下一个字节数据，继续传输。装载过程中，可拉底SCL。
- 如果接收到NACK位，停止下一个字节的装载。
- 等待STOP事件，停止本次传输。

##### 从模式单字节接收

地址匹配后，从接收器将通过内部移位寄存器从SDA线接收到的数据存入I2C_DATA寄存器。I2C接口在接收到每个字节后都执行下列操作:

- 如果设置了ACK位，在一个字节接收完毕后，产生一个ACK应答脉冲。
- 如果清除了ACK位，在一个字节接收完毕后，产生一个NACK应答脉冲。
- 等待STOP事件，结束本次传输。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-6 I2C从模式（发送/接收/DMA）的逻辑流程图

#### 从模式DMA传输

从模式下，一般仅配置I2C时钟、从地址以及硬件地址匹配使能，等待总线有访问请求后，根据芯片实际情况决定是否响应本次传输请求。DMA传输，其含义为每次传输多个字节的数据后，将产生中断判断是否还要继续传输。DMA传输的极端情况是仅传输一个字节的数据。DMA传输，一般建议开启硬件地址比较功能，NACK中断，传输完成中断。一般DMA传输的流程如下:

- 配置I2C从地址，使能I2C中断（可使能硬件地址比较中断）。地址匹配，产生I2C地址匹配中断，在中断处理函数中，配置DMA，准备好发送数据或者准备好接收地址。然后写I2C_SCR，准备开始传输或者停止本次传输。
- 若是接收模式，I2C_BSIZE.BURST_SIZE约定的字节接收完毕后，产生中断，软件判断是否继续接收，返回ACK/NACK响应。
- 若是发送模式，I2C_BSIZE.BURST_SIZE约定的字节发送完毕后，等待响应（ACK/NACK），产生中断，根据响应判断后续操作。
- 获得总线完成标志，本次传输完成。

##### 从模式DMA发送

地址匹配后，配置完毕DMA。通过发送DMA请求，将字节从RAM搬移到I2C_DATA寄存器，然后经由内部移位寄存器发送到SDA线上。在I2C_DATA数据没有准备好之前，从设备可拉底SCL，直到待发送数据已写入I2C_DATA寄存器。从模式下发送数据，需要软件协助触发第一次DMA搬移，配置I2C_BCR.BYTE_CMPLT为1即可。I2C接口在发送完毕I2C_BSIZE.BURST_SIZE约定的字节数据后都执行下列操作:

- 如果接收到ACK位，配置DMA，准备下一批数据，继续传输。准备过程中，可拉低SCL。
- 如果接收到NACK位，停止准备下一批数据，停止本次传输。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-7从模式下多字节发送示意图

##### 从模式DMA接收

地址匹配后，配置好DMA，从SDA线接收到的数据先存入I2C_DATA寄存器，然后通过DMA搬移到RAM。I2C接口在接收到一个字节后都将执行DMA请求。完成I2C_BCR.BURST_SIZE约定的数据传输后，执行下列操作:

- 如果设置了ACK位，在I2C_BCR.BURST_SIZE约定数据接收完毕后，产生一个ACK应答脉冲。
- 如果清除了ACK位，在I2C_BCR.BURST_SIZE约定数据接收完毕后，产生一个NACK应答脉冲。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-8从模式下多字节接收示意图

#### 主模式

默认情况下，I2C接口主模式和从模式均关闭。若工作在主模式，需使能主模式。为了产生正确的时序，必须在系统寄存器CLK_DIV0中设定I2C接口的工作时钟。

I2C接口执行主模式传输之前，需要判断总线是否空闲。可读取I2C_MSCR寄存器的BIT3，查询当前总线状态。若总线处于忙的状态，可以开启I2C中断，通过收到STOP中断事件判断总线是否空闲下来。只有空闲状态下，才能正常发送START状态，以及后续的数据。

##### 主模式单字节传输

单字节传输，并不意味着仅仅传输一个字节数据，其含义为每次传输完一个字节的数据后，将产生中断判断是否还要继续传输。单字节传输的极端情况是仅传输一个字节的数据。图6为单字节传输的总线示意图。从图可知，一般单字节传输的流程如下:

- 判断总线是否空闲，若空闲，准备开始传输。
- 若是接收模式，一个字节接收完毕后，产生中断，软件判断是否继续接收，返回ACK/NACK响应。
- 若是发送模式，一个字节发送完毕后，等待响应（ACK/NACK），产生中断，根据响应判断后续操作。
- 发送总线STOP事件，本次传输完成。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-9主模式下单字节传输示意图

##### 主模式单字节发送

开始传输后，I2C接口将字节从I2C_DATA寄存器经由内部移位寄存器发送到SDA线上。在I2C_DATA数据没有准备好之前，主设备可不产生SCL时钟信号，直到待发送数据已写入I2C_DATA寄存器。I2C接口在发送完毕每个字节后都执行下列操作:

- 如果接收到ACK位，装载下一个字节数据，继续传输。装载过程中，可拉底SCL。
- 如果接收到NACK位，停止下一个字节的装载。
- 产生STOP事件，结束本次传输。

##### 主模式单字节接收

开始传输后，I2C接口将通过内部移位寄存器从SDA线接收到的数据存入I2C_DATA寄存器。I2C接口在接收到每个字节后都执行下列操作:

- 如果设置了ACK位，在一个字节接收完毕后，产生一个ACK应答脉冲。
- 如果清除了ACK位，在一个字节接收完毕后，产生一个NACK应答脉冲。
- 产生STOP事件，结束本次传输。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-11主模式下多字节发送示意图

##### 主模式DMA接收

总线空闲，配置好DMA从SDA线接收到的数据先存入I2C_DATA寄存器，然后通过DMA搬移到RAM。I2C接口在接收到一个字节后都将执行DMA请求。完成I2C_BCR.BURST_SIZE约定的数据传输后，执行下列操作:

- 如果设置了ACK位，在I2C_BCR.BURST_SIZE约定数据接收完毕后，产生一个ACK应答脉冲。
- 如果清除了ACK位，在I2C_BCR.BURST_SIZE约定数据接收完毕后，产生一个NACK应答脉冲。
- 产生STOP事件，停止本次传输。

异常情况是:

- 若从设备地址不匹配或者从设备没有准备好，此时从设备将返回NACK。
- 主设备产生STOP事件，停止本次传输。

等待一段时间后，重新配置I2C寄存器，再次发送传输请求。因为上一次没有收到有效数据，DMA并没有任何动作，所以不用重置DMA。

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-12主模式下多字节接收示意图

#### DMA传输

在大容量数据传输应用下，I2C接口支持DMA传输，减轻MCU的负担。一次传输，最大传输量为32字节，最小传输量为1字节。因I2C无FIFO，I2C发送一次DMA请求，DMA只能搬移一个字节数据。若要实现多字节搬移，DMA需配置为多轮搬移，每一轮搬移一个字节的方式。

在接收到新的数据后，硬件自动产生DMA请求，通过DMA模块将数据搬移到RAM中。在发送新数据前，硬件自动产生DMA请求，通过DMA模块将数据从RAM中搬移到I2C接口。

DMA传输需要配置DMA模块相应寄存器。

因I2C接口支持DMA传输，也支持MCU传输。两者区别在于DMA传输，发送的数据来自DMA的搬移；MCU传输，发送的数据来自MCU的搬移。

DMA传输，推荐软件配置流程如下:

- 初始化DMA模块，将本次发送的数据来源，接收的数据去向配置好，传输长度配置完毕。
- 初始化GPIO模块，将I2C复用的GPIO配置完毕。
- 初始化I2C接口，I2C_CFG/I2C_BCR/I2C_BSIZE等寄存器配置完毕。
- 主模式下，触发I2C接口，进入发送状态；从模式下，等待主发送传输请求。

若I2C接口为从发送模式，需要考虑预取，I2C_BCR.
SLV_DMA_PREF为预取开关。一般从模式传输的时候，可以开启硬件地址比较(I2C_ADDR.
ADDR_CMP)，可选择是否开启硬件地址比较中断使能(I2C_BCR. BURST_ADDR_CMP)。

- 开启硬件地址比较中断，从设备收到的地址同自身匹配成功后，会产生中断。通知软件此时主设备请求获得从设备数据，软件判断是否接收，若接收就回ACK，软件需要I2C_BCR.
  SLV_DMA_PREF置1，协助硬件预取第一次传输的数据；否则就回NACK。

关闭硬件地址比较中断，一旦总线上出现START事件，从设备硬件预取第一次传输数据，无论从设备是否地址匹配成功。匹配成功，也不会产生地址匹配中断，直接开始数据传输。匹配不成功，从设备不会传输数据。此时，若匹配不成功，因为I2C有预取的操作，为后续匹配成功后传输正常，需要对DMA进行清除操作

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。
- I2C波特率 = I2C模块工作时钟频率 / 17

【图片已删除】为控制知识库体积，本文档不携带图片，相关图示请查阅凌鸥创芯官网发布的正式手册。

图9-14 I2C总线错误处理及中断管理流程图

## 寄存器

### 地址分配

I2C模块寄存器的基地址是0x4001_0100，寄存器列表如下:

表9-1 I2C寄存器地址分配表

||||
|---|---|---|
|名称|偏移|说明|
|I2C0_ADDR|0x00|I2C地址寄存器|
|I2C0_CFG|0x04|I2C配置寄存器|
|I2C0_SCR|0x08|I2C状态寄存器|
|I2C0_DATA|0x0C|I2C数据寄存器|
|I2C0_MSCR|0x10|I2C主模式寄存器|
|I2C0_BCR|0x14|I2C传输控制寄存器|
|I2C0_BSIZE|0x18|I2C传输长度寄存器|

### I2C0_ADDR 地址寄存器

地址:0x4001_0100

复位值:0x0

表9-2地址寄存器I2C0_ADDR

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|||||||||ADDR_CMP|ADDR|||||||
|||||||||RW|RW|||||||
|||||||||0|0|||||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[7\]|ADDR_CMP|I2C硬件地址比较使能开关，默认值为0。0:关闭1:开启|
|\[6:0\]|ADDR|主模式下，用于配置需要进行通信的从机地址；从模式下，用于配置该节点的从机地址；|

### I2C0_CFG 系统控制寄存器

地址:0x4001_0104

复位值:0x0

表9-3系统控制寄存器I2C_CFG

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|||||||||IE|TC_IE|BUS_ERR_IE|STOP_IE|||MST_MODE|SLV_MODE|
|||||||||RW|RW|RW|RW|||RW|RW|
|||||||||0|0|0|0|||0|0|

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[7\]|IE|I2C中断使能信号。默认值为0。1:使能I2C中断0:关闭I2C中断|
|\[6\]|TC_IE|I2C数据传输完成中断使能信号。默认值为0。1:使能此中断源0:屏蔽此中断源|
|\[5\]|BUS_ERR_IE|I2C总线错误事件中断使能信号。默认值为0。1:使能此中断源0:屏蔽此中断源|
|\[4\]|STOP_IE|I2CSTOP事件中断使能信号。默认值为0。1:使能此中断源0:屏蔽此中断源|
|\[3:2\]||NA|
|\[1\]|MST_MODE|I2C主模式使能信号。默认值为0。1:使能主模式0:关闭主模式|
|\[0\]|SLV_MODE|I2C从模式使能信号。默认值为0。1:使能从模式0:关闭从模式|

### I2C0_SCR 状态控制寄存器

地址:0x4001_0108

复位值:0x0

表9-4状态控制寄存器I2C_SCR

|||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7||6||5||4||3||2||1|0|
||||||||||STT_ERR||LOST_ARB||STOP_EVT||BYTE_CMPLT||ADDR_DATA||DATA_DIR|RX_ACK|Done|
||||||||||RW||RW||RW||RW||RW||RW|RW|RW|
||||||||||0||0||0||0||0||0|0|0|

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[7\]|STT_ERR|总线错误状态标志位，用于主模式发送/主模式接收，写0清除。0:无START/STOP总线错误1:有START/STOP总线错误|
|\[6\]|LOST_ARB|总线仲裁丢失状态标志位，用于主模式发送/主模式接收，发生总线仲裁丢失事件将此位置1，无中断事件产生，在字节完成中断中需查此位。总线上任何START事件将导致硬件清除此位。0:无总线仲裁丢失错误发生1:有总线仲裁丢失错误发生|
|\[5\]|STOP_EVT|STOP事件状态标志位，用于主模式发送/从模式发送/主模式接收/从模式接收。写0清除。0:无STOP事件1:有STOP事件|
|\[4\]|BYTE_CMPLT|下一字节ACK位。若作为发送方，无须配置此位。若作为接收方（主/从模式接收），0:字节接收完成，向发送方返回NACK，表示我方不能接收更多数据1:字节接收完成，向发送方返回ACK，表示我方可以继续接收数据|
|\[3\]|ADDR_DATA|地址字节标志位，用于从模式。START后，从机收到的第一个字节为地址字节，此位是状态位。写0清除。0:收到的不是地址字节。1:收到的是地址字节。|
|\[2\]|DATA_DIR|发送或接收控制位，主模式发送/从模式发送，此位置1，触发发送，硬件自动清零；主模式接收/从模式接收，此位置0，等待接收。0:接收1:触发发送|
|\[1\]|RX_ACK|接收响应标志位，用于主模式发送/从模式发送。此位是我方作为发送方，收到的接收方反馈。我方收到此反馈后，可对该位写0来执行清零操作。0:发送数据后，接收到ACK响应。1:发送数据后，接收到NACK响应。|
|\[0\]|Done|传输完成状态标志位，用于主模式发送/从模式发送/主模式接收/从模式接收。写0清除。0:传输未完成1:传输已完成|

一般，进入中断后，需读取I2C_SCR寄存器，获得当前I2C总线状态及当前传输处于什么阶段；然后，对I2C_SCR进行写操作，写入不同的值，软件通知硬件下一步如何处理。

### I2C0_DATA 数据寄存器

地址:0x4001_010C

复位值:0x0

表9-5数据寄存器I2C_DATA

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|||||||||DATA||||||||
|||||||||RW||||||||
|||||||||0||||||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[7:0\]|DATA|数据寄存器，用于主模式发送/从模式发送/主模式接收/从模式接收。发送方，写入发送数据；接收方，读取接收数据。注意，地址数据也是数据，主模式只能将要发送地址数据写入此寄存器。|

### I2C0_MSCR 主模式寄存器

地址:0x4001_0110

复位值:0x0

表9-6主模式寄存器I2C_MSCR

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|||||||||||||BUSY|MST_CHECK|RESTART|START|
|||||||||||||RW|RW|RW|RW|
|||||||||||||0|0|0|0|

||||
|---|---|---|
|位置|位名称|说明|
|\[31:4\]||未使用|
|\[3\]|BUSY|I2C总线，闲忙状态。0:空闲。1:忙碌。|
|\[2\]|MST_CHECK|主模式争抢总线标志位。争抢到总线，置1；STOP事件或者发生总线冲突本模块释放总线，置0。|
|\[1\]|RESTART|再次触发START事件，写1有效。发送START完毕，硬件清0。I2C_CFG\[1\]置1，才能实现写1操作。|
|\[0\]|START|触发START事件并发送地址数据至总线，写1有效。I2C_CFG\[1\]置1，才能实现写1操作。|

### I2C0_BCR I2C传输控制寄存器

地址:0x4001_0114

复位值:0x0

表9-7 DMA传输控制寄存器I2C_BCR

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
|||||||||BURST_NACK|BURST_ADDR_CMP|BUSRT_EN|SLV_DMA_PREF|||||
|||||||||RW|RW|RW|RW|||||
|||||||||0|0|0|0|||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[7\]|BURST_NACK|I2C传输，NACK事件中断使能信号。1:使能此中断源0:屏蔽此中断源|
|\[6\]|BURST_ADDR_CMP|I2C传输，硬件地址匹配中断使能信号。1:使能此中断源0:屏蔽此中断源|
|\[5\]|BUSRT_EN|I2C多数据传输使能，需要采用DMA方式。1:使能0:关闭|
|\[4\]|SLV_DMA_PREF|I2C多数据传输。从模式执行DMA方式发送，触发硬件预取第一个字节。硬件自动清零。1:使能0:关闭|

### I2C0_BSIZE I2C传输长度寄存器

地址:0x4001_0118

复位值:0x0

表9-8 DMA传输长度寄存器I2C_BSIZE

|||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
||||||||||||SIZE|||||
||||||||||||RW|||||
||||||||||||0|||||

||||
|---|---|---|
|位置|位名称|说明|
|\[31:8\]||未使用|
|\[4:0\]|SIZE|I I2C数据传输长度寄存器，用于多字节传输。实际传输字节数 = B\[3:0\] + 1|

