一起游 手游攻略 手游评测 中科芯CKS32F107XX系列MCU的串行外设接口介绍

中科芯CKS32F107XX系列MCU的串行外设接口介绍

时间: 来源:互联网 浏览:0

MCU微课堂CKS32F107XX系列串行外设接口介绍第69期2026.01.19

SPI简介

SPI协议是Motorola提出的通信协议(Serial Peripheral Interface),即串行外设接口。它是一种高速全双工通信总线。仅占用芯片引脚上的四根线,节省了芯片引脚,节省了PCB布局空间。正是因为这种简单易用的特点,现在越来越多的芯片集成了这种通信协议,广泛应用于ADC、LCD、FLASH等设备与MCU之间。

中科芯的CKS32F107xx系列产品具有3路SPI接口,允许芯片以半/全双工、同步和串行方式与外部设备通信。该接口可配置为主模式,并向外部从设备提供通信时钟(SCK)。支持在多主配置下工作。下面介绍SPI相关功能。

SPI的主要特点

SPI特征 3线全双工同步传输

两线单工同步传输,带或不带第三条双向数据线

8位或16位传输帧格式选择

主从操作

支持多主模式

8 个主模式波特率预分频器系数(最大fPCLK/2)

从模式频率(最大fPCLK/2)

主从模式快速通讯

主从模式下均可通过软件或硬件进行NSS管理:主/从工作模式动态变化

可编程时钟极性和相位

可编程数据顺序,MSB 在前或LSB 在前

触发中断的专用发送和接收标志

SPI 总线忙状态标志

硬件CRC支持可靠通信

在发送模式下,CRC 值可以作为最后一个字节发送

在全双工模式下对最后接收的字节进行自动CRC 检查

可触发中断的主模式故障、过载和CRC 错误标志

1 字节发送和接收缓冲区支持DMA 功能:生成发送和接收请求

SPI功能说明

SPI概述SPI 的框图如下所示。

e24a8fcc-f50c-11f0-92de-92fbcf53809c.png

图1 SPI框图

图中为SPI引脚MOSI、MISO、SCK、NSS。 CKS32F107xx系列芯片通过上述四个引脚将SPI通信信号引至不同的GPIO引脚。这些指定的引脚在使用时必须进行配置。关于GPIO引脚的复用功能,请参考芯片数据手册。各引脚功能介绍如下:

NSS:从设备选择信号线,常称为片选信号线。当多个SPI从设备连接到SPI主机时,设备的其他信号线SCK、MOSI和MISO同时并联到同一条SPI总线上,即无论有多少个从设备,都只使用这3条总线;每个从设备都有独立的NSS信号线。当主机要选择一个从设备时,将从设备的NSS信号线设置为低电平,该从设备被选中,即片选有效,然后主机开始与选定的从设备进行SPI通信。

SCK:时钟信号线,用于通讯数据同步。它由通信主机生成并决定通信速率。不同的设备支持不同的最大时钟频率。当两个设备之间通信时,通信速率受到低速设备的限制。

MOSI:主设备输出/从设备输入引脚。主机的数据从该信号线输出,从机从该信号线读取主机发送的数据,即该线上数据的方向是从主机到从机。

MISO:主设备输入/从设备输出引脚。主机从该信号线读取数据,从机的数据通过该信号线输出到主机,即该线上数据的方向是从机到主机。

图中为SCK线的时钟信号,由波特率发生器根据“控制寄存器CR1”中的BR[0:2]位控制。该位是fpclk时钟的分频因子。 fpclk的分频结果就是SCK引脚的输出时钟频率。

图中是SPI的数据控制逻辑。 SPI的MOSI和MISO连接到数据移位寄存器。数据移位寄存器的内容来自接收缓冲器和发送缓冲器以及MISO和MOSI线。对外发送数据时,数据移位寄存器以“发送缓冲区”为数据源,通过数据线逐位发送数据;当从外部接收数据时,数据移位寄存器将数据线采样的数据逐位存储到“接收缓冲器”中。通过写入SPI的“数据寄存器DR”将数据填充到发送缓冲区中。通过“数据寄存器DR”,可以获得接收缓冲区的内容。数据帧的长度可以通过“控制寄存器CR1”的“DFF位”配置为8位和16位模式;配置“LSBFIRST位”可以选择MSB优先或LSB优先。

图中是SPI的整体控制逻辑。总体控制逻辑负责协调整个SPI外设。控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而变化。基本控制参数包括SPI模式、波特率、LSB优先、主从模式、单双向模式等。当外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR)”。我们只需读取状态寄存器的相关寄存器位即可了解SPI的工作状态。另外,控制逻辑还负责根据要求控制SPI中断信号、DMA请求的产生以及控制NSS信号线。在实际应用中,我们一般不使用SPI外设的标准NSS信号线,而是简单地使用普通GPIO,由软件控制其电平输出。

CKS32F107xx系列产品SPI配置:

接下来我们讲解如何使用CKS32F107xx系列固件库来完成SPI的配置和使用。与其他外设一样,CKS32 标准库提供了SPI 初始化结构体和初始化函数来配置SPI 外设。了解了初始化结构之后,我们就可以自由地使用SPI外设了。结构如下图所示:

e2a61798-f50c-11f0-92de-92fbcf53809c.png

图2 SPI配置结构

结构体中各个函数变量的介绍以及初始化时可以赋值的值如下:

1)SPI_Direction:该函数设置SPI的通信方向,可设置为两线全双工(SPI_Direction_2Lines_FullDuplex)、两线仅接收(SPI_Direction_2Lines_RxOnly)、仅单线接收(SPI_Direction_1Line_Rx)、仅单线发送模式(SPI_Direction_1Line_Tx)。

2)SPI_Mode:该函数设置SPI工作在主机模式(SPI_Mode_Master)或从机模式(SPI_Mode_Slave)。这两种模式最大的区别在于SPI SCK信号线的时序。 SCK 时序由通信中的主机产生。如果配置为从机模式,CKS32 的SPI 外设将接受外部SCK 信号:

3) SPI_DataSize: 该函数可以选择SPI通信的数据帧大小是8位(SPI_DataSize_8b)还是16位(SPI_DataSize_16b)。

4)SPI_CPOL和SPI_CPHA:这两个函数配置SPI的时钟极性CPOL和时钟相位CPHA。前面提到,这两种配置会影响SPI的通信模式。时钟极性CPOL 成员可设置为高(SPI_CPOL_High) 或低(SPI_CPOL_Low)。时钟相位CPHA 可设置为SPI_CPHA_1Edge(在SCK 的奇数边沿收集数据)或SPI_CPHA_2Edge(在SCK 的偶数边沿收集数据)。具体组合设置方法可参考图2。

e301872c-f50c-11f0-92de-92fbcf53809c.png

图3 数据时钟时序图

5) SPI_NSS: 该函数配置NSS引脚的使用模式。您可以选择硬件模式(SPI_NSS_Hard) 和软件模式(SPI_NSS_Soft)。在硬件模式下,SPI片选信号由SPI硬件自动产生,而在软件模式下,我们需要将相应的GPIO端口拉高或拉低来产生非片选和片选信号。在实践中,软件模型的应用有很多。

6) SPI_BaudRatePrescaler: 该函数设置波特率分频系数。分频时钟是SPI SCK 信号线的时钟频率。该成员参数可设置为fpclk的2、4、8、16、32、64、128、256分频。可选值如下所示:

e35f2b84-f50c-11f0-92de-92fbcf53809c.png

图4 SPI波特率划分

7) SPI_FirstBit: 所有串行通信协议都会存在MSB First(高位数据优先)或LSB First(低位数据优先)的问题,CKS32F107VET6 的SPI 模块可以通过该结构体以编程方式控制此功能。

e3c521d2-f50c-11f0-92de-92fbcf53809c.png

图5 SPI数据优先模式

8) SPI_CRCPolynomial: 这是SPI CRC 校验中的多项式。如果我们使用CRC校验,我们将使用这个参数(多项式)来计算CRC值。

配置完这些结构体成员的值后,调用库函数SPI_Init将结构体配置写入寄存器。

SPI外设主要有两种实现方式:主模式和从模式。现在我们分别对这两种模式进行说明。

配置SPI为主模式在主配置中,串行时钟在SCK 引脚上生成。

配置步骤:

(1)通过SPI_CR1寄存器的BR[2:0]位定义串行时钟波特率;

(2) 选择CPOL和CPHA位来定义数据传输和串行时钟之间的相位关系(见图4);

(3) 设置DFF位,定义8位或16位数据帧格式;

(4) 配置SPI_CR1寄存器的LSBFIRST位来定义帧格式;

(5) 如果要求NSS引脚工作在输入模式,在硬件模式下,NSS引脚在整个数据帧传输过程中应保持高电平;在软件模式下,需要设置SPI_CR1寄存器的SSM位和SSI位。如果NSS引脚工作在输出模式,则只需设置SSOE位即可;

(6) MSTR 位和SPE 位必须置位(这些位只有在NSS 引脚连接为高电平时才能保持置位状态)。在此配置中,MOSI 引脚为数据输出,MISO 引脚为数据输入;

数据发送过程当数据写入发送缓冲区时,发送过程开始。当发送第一个数据位时,数据字被并行传送到移位寄存器(通过内部总线),然后串行移出到MOSI引脚; MSB 在前或LSB 在前,具体取决于SPI_CR1 寄存器中LSBFIRST 位的设置。当数据从发送缓冲器传输到移位寄存器时,TXE 标志将被置位。如果SPI_CR1 寄存器中的TXEIE 位置1,则会产生中断。

数据接受过程对于接收方,数据传输完成后:

将移位寄存器中的数据传送到接收缓冲器,并且RXNE 标志位被置位。

如果SPI_CR2 寄存器中的RXNEIE 位置1,则产生中断。在最后一个采样时钟沿,RXNE 位被置位,移位寄存器中接收到的数据字被传输到接收缓冲区。当读取SPI_DR 寄存器时,SPI 设备返回接收缓冲区中的数据。读取SPI_DR 寄存器将清除RXNE 位。一旦传输开始,如果将下一个要发送的数据放入传输缓冲区,则可以保持连续的传输流。在尝试写入发送缓冲区之前,请确保TXE 标志应为“1”。

注意:在NSS 硬件模式下,从设备的NSS 输入由NSS 引脚或另一个软件驱动的GPIO 引脚控制。

具体初始化代码如下:

无效SPI_Init(无效)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,启用);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,启用);

/* 配置SPI1引脚PA.4 NSS(软件); PA.5 SCK; PA.6 味噌; PA.7 MOSI--------------*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA, GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, GPIO_InitStructure);

GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);

/* 配置SPI1 --------------------------------------------------------------------------*/

SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;

SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;

SPI_InitStruct.SPI_Mode=SPI_Mode_Master;

SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;

SPI_InitStruct.SPI_CPOL=SPI_CPOL_Low;

SPI_InitStruct.SPI_CPHA=SPI_CPHA_2Edge;

SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;

SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;

SPI_InitStruct.SPI_CRCPolynomial=7;

SPI_Init(SPI1, SPI_InitStruct);

SPI_Cmd(SPI1,启用);

}

单字节收发功能代码如下:

uint8_t CKS_SPI_Tx_Rx_Byte(uint8_t 数据)

{

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET);

SPI_I2S_SendData(SPI1,数据);

while( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==重置);

返回SPI_I2S_ReceiveData(SPI1);

}

配置SPI为从机模式

在从模式下,SCK 引脚用于接收来自主设备的串行时钟。 SPI_CR1寄存器中BR[2:0]的设置不影响数据传输速率。

注意:建议在主设备发送时钟之前使能SPI 从设备,否则可能会发生意外的数据传输。从机的数据寄存器必须在通信时钟的第一个边沿到达之前或正在进行的通信结束之前准备好。在启用从设备和主设备之前,通信时钟的极性必须处于稳定值。请按照以下步骤将SPI 配置为从机模式:

配置步骤(1) 设置DFF位来定义数据帧格式为8位或16位。

(2) 选择CPOL 和CPHA 位来定义数据传输和串行时钟之间的相位关系。为了保证数据正确传输,从设备和主设备的CPOL和CPHA位必须以相同的方式配置。

(3) 帧格式(由SPI_CR1寄存器中的LSBFIRST位定义的“MSB优先”或“LSB优先”)必须与主设备相同。

(4) 在硬件模式下(参见从机选择(NSS)引脚管理部分),在传输一个完整的数据帧(8 位或16 位)期间,NSS 引脚必须为低电平。在NSS软件模式下,设置SPI_CR1寄存器中的SSM位并清除SSI位。

(5) 清零MSTR 位并设置SPE 位(SPI_CR1 寄存器),使相应引脚工作在SPI 模式。在此配置中,MOSI 引脚是数据输入,MISO 引脚是数据输出。

数据发送过程在写操作中,数据字并行写入发送缓冲区。当从设备接收到时钟信号并且第一个数据位出现在MOSI引脚上时,传输过程开始(注:此时第一个数据位被发送出去)。其余位(8 位数据帧格式为7 位,16 位数据帧格式为15 位)装入移位寄存器。当发送缓冲区中的数据传输到移位寄存器时,SPI_SP 寄存器的TXE 标志被置位。如果SPI_CR2 寄存器的TXEIE 位置1,则会产生中断。

数据接受过程对于接收端,数据接收完成后:

移位寄存器中的数据被传送到接收缓冲区,并且SPI_SR 寄存器中的RXNE 标志被置1。

如果SPI_CR2 寄存器中的RXNEIE 位置1,则产生中断。在最后一个采样时钟沿之后,RXNE 位设置为“1”,移位寄存器中接收到的数据字节将传输到接收缓冲区。当读取SPI_DR 寄存器时,SPI 设备返回该接收缓冲区的值。当读取SPI_DR 寄存器时,RXNE 位被清零。

以上部分是SPI的主/从模式的理论配置过程。我们开始分解实际程序中的代码配置。程序比较简单。它使用单个CKS32F107VET6的SPI1外设作为主机,SPI2外设作为从机。两个外设相互通信(先SPI1发送,SPI2接收;然后SPI2发送,SPI1接收)。

本讲以简单的数据接收和发送为例进行配置。具体初始化代码如下:

uint8_t CKS_SPI_Tx_Rx_Byte(uint8_t 数据)

{

而(SPI_I2S_GetFlagStatus(SPI1,

无效SPI_Slaver_Init(无效)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStruct;

NVIC_InitTypeDef NVIC_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO,启用);

/* 配置SPI1引脚PA.4 NSS(软件); PA.5 SCK; PA.6 味噌; PA.7 MOSI--------------*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA, GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA, GPIO_InitStructure);

/* 配置SPI1 --------------------------------------------------------------------------*/

SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_64;

SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;

SPI_InitStruct.SPI_Mode=SPI_Mode_Slave;

SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;

SPI_InitStruct.SPI_CPOL=SPI_CPOL_High;

SPI_InitStruct.SPI_CPHA=SPI_CPHA_2Edge;

SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;

SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;

SPI_InitStruct.SPI_CRCPolynomial=7;

SPI_Init(SPI1, SPI_InitStruct);

SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, 启用);

SPI_Cmd(SPI1,启用);

/* 配置SPI1 INT----------------------------------------------------------*/

NVIC_InitStructure.NVIC_IRQChannel=SPI1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

NVIC_InitStructure.NVIC_IRQChannelCmd=启用;

NVIC_Init(NVIC_InitStructure);

}

)==重置);

SPI_I2S_SendData(SPI1,数据);

while( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==重置);

返回SPI_I2S_ReceiveData(SPI1);

}

SPI中断函数:

无效SPI1_IRQHandler(无效)

{

if(SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_RXNE) !=重置)

{

SPI_Rx=SPI_I2S_ReceiveData(SPI1);

如果(SPI_Rx=0x04)

{

SPI_I2S_SendData(SPI1, SPI_Tx[SPI_Rx]);

}

否则

{

SPI_I2S_SendData(SPI1, SPI_Tx[0x05]);

}

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==重置){}

SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);

}

}

标题:中科芯CKS32F107XX系列MCU的串行外设接口介绍
链接:https://yqqlyw.com/news/sypc/71278.html
版权:文章转载自网络,如有侵权,请联系删除!
资讯推荐
更多
  • RA MCU众测宝典 | ADC/DAC之DAC电
  • 瑞萨RL78/F22 MCU基于IAR开发环境
  • 绯红之境兑换码最新2021 礼包兑换码大全

    绯红之境兑换码最新2021 礼包兑换码大全[多图],绯红之境兑换码怎么领取?绯红之境兑换码有哪些?绯红之境在今日

    2026-01-22
    三国群英传7霸王再临攻略 霸王再临攻略技巧开启方法

    三国群英传7霸王再临攻略 霸王再临攻略技巧开启方法[多图],三国群英传7霸王再临怎么玩?三国群英传7霸王再临

    2026-01-22
    妄想山海怎么加好友 加好友方法大全

    妄想山海怎么加好友 加好友方法大全[多图],妄想山海添加好友功能在哪里?妄想山海添加好友的方法是什么?好友添

    2026-01-22
    江南百景图又见桃花村钓鱼位置在哪?又见桃花村钓鱼攻略

    江南百景图又见桃花村钓鱼位置在哪?又见桃花村钓鱼攻略[多图],江南百景图又见桃花村钓鱼怎么钓?又见桃花村钓

    2026-01-22