news 2026/2/3 8:10:14

STM32_SPI

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32_SPI
简介

SPI(Serial Peripheral Interface,串行外设接口)是一种高速的同步串行通信总线,由Motorola公司开发,广泛应用于单片机与外设之间的短距离高速通信。SPI总线需要4根线(SCK时钟线、MOSI主出从入线、MISO主入从出线、CS片选线),通信速率远高于I2C,可达几十Mbps。STM32F407 系列芯片提供了多达 6 个 SPI 接口,支持多种工作模式和通信速率,可连接各种 SPI 设备,如 Flash 存储器、SD 卡、LCD 显示屏、传感器等。本文从 SPI 的基本原理出发,详细讲解 STM32F407 SPI 的配置方法、代码实现、通信协议以及实际应用案例,帮助你快速掌握 SPI 通信技术。

一、SPI核心概念与分类
1.1 基本概念

SPI 是一种同步串行通信总线,主要用于主设备与从设备之间的高速数据传输,其主要特点包括:

  • 四根通信线:SCK(Serial Clock,串行时钟线)、MOSI(Master Out Slave In,主出从入线)、MISO(Master In Slave Out,主入从出线)、CS/SS(Chip Select/Slave Select,片选线)
  • 主从架构:一个主设备可以连接多个从设备,通过片选线选择从设备
  • 全双工通信:可以同时进行发送和接收
  • 同步通信:主设备提供时钟信号,所有设备在时钟的同步下进行通信
  • 高速通信:通信速率可达几十Mbps,远高于I2C

关键参数

  • 通信速率:由主设备的时钟频率决定,一般可达几Mbps到几十Mbps
  • 时钟极性(CPOL):时钟空闲时的电平,0为低电平,1为高电平
  • 时钟相位(CPHA):数据采样的时钟边沿,0为第一个边沿,1为第二个边沿
  • 数据位宽:通常为8位或16位
  • 数据顺序:MSB先传输或LSB先传输
1.2 STM32F407 的 SPI 资源

STM32F407 系列芯片提供了 6 个 SPI 接口(SPI1-SPI6):

SPI引脚最大通信速率适用场景
SPI1PA5(SCK), PA6(MISO), PA7(MOSI), PA4(NSS)42MHz主要SPI接口,支持高速模式
SPI2PB13(SCK), PB14(MISO), PB15(MOSI), PB12(NSS)42MHz辅助SPI接口
SPI3PB3(SCK), PB4(MISO), PB5(MOSI), PA15(NSS)42MHz辅助SPI接口
SPI4PE2(SCK), PE5(MISO), PE6(MOSI), PE4(NSS)42MHz辅助SPI接口
SPI5PF7(SCK), PF8(MISO), PF9(MOSI), PF6(NSS)42MHz辅助SPI接口
SPI6PG13(SCK), PG12(MISO), PG14(MOSI), PG8(NSS)42MHz辅助SPI接口

关键特性

  • 支持 8 位和 16 位数据宽度
  • 支持全双工、半双工和单线双向通信模式
  • 支持 DMA 传输
  • 支持硬件 CRC 校验
  • 支持 NSS 硬件管理和软件管理
  • 支持多种时钟极性和相位组合
二、SPI通信协议
2.1 基本通信流程

SPI 通信的基本流程包括:

  1. 片选:主设备将对应从设备的CS线拉低,选中该从设备
  2. 时钟生成:主设备生成SCK时钟信号
  3. 数据传输:主设备和从设备在时钟的同步下交换数据
  4. 片选释放:主设备将CS线拉高,释放从设备
2.2 时钟极性和相位

SPI 支持四种时钟模式,由 CPOL(Clock Polarity,时钟极性)和 CPHA(Clock Phase,时钟相位)决定:

模式0(CPOL=0, CPHA=0)

  • 时钟空闲时为低电平
  • 在第一个时钟边沿(上升沿)采样数据
  • 在第二个时钟边沿(下降沿)输出数据

模式1(CPOL=0, CPHA=1)

  • 时钟空闲时为低电平
  • 在第二个时钟边沿(下降沿)采样数据
  • 在第一个时钟边沿(上升沿)输出数据

模式2(CPOL=1, CPHA=0)

  • 时钟空闲时为高电平
  • 在第一个时钟边沿(下降沿)采样数据
  • 在第二个时钟边沿(上升沿)输出数据

模式3(CPOL=1, CPHA=1)

  • 时钟空闲时为高电平
  • 在第二个时钟边沿(上升沿)采样数据
  • 在第一个时钟边沿(下降沿)输出数据
2.3 数据传输格式

SPI 支持两种数据传输格式:

全双工模式

  • 主设备和从设备同时发送和接收数据
  • MOSI 线用于主设备发送数据,MISO 线用于主设备接收数据
  • 每个时钟周期传输一个数据位

半双工模式

  • 主设备和从设备交替发送和接收数据
  • 使用单根数据线(MOSI或MISO)进行数据传输
  • 需要通过软件或硬件切换数据方向
三、SPI配置与代码实现
3.1 标准库配置步骤

以 SPI1 为例,使用标准库配置 SPI 的基本步骤:

  1. 使能 SPI 时钟和 GPIO 时钟
  2. 配置 GPIO 为复用功能
  3. 配置 SPI 基本参数(时钟速率、数据位宽、时钟极性、时钟相位等)
  4. 使能 SPI
  5. 配置中断(可选)
  6. 配置 DMA(可选)
3.2 代码实现(SPI1,模式0,10MHz)
#include"stm32f4xx.h"#defineSPI_SPEED10000000// SPI通信速率:10MHz/** * @brief 初始化SPI1 * @param 无 * @retval 无 */voidSPI1_Init(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;// 1. 使能时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);// 2. 配置GPIO// SCK, MISO, MOSIGPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);// NSS(片选,使用软件控制)GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);// 设置NSS为高电平(不选中)GPIO_SetBits(GPIOA,GPIO_Pin_4);// 3. 将GPIO引脚连接到SPI1GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);// SCKGPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1);// MISOGPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);// MOSI// 4. 配置SPI1SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;// 全双工模式SPI_InitStructure.SPI_Mode=SPI_Mode_Master;// 主模式SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;// 8位数据SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;// 时钟极性:低电平SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;// 时钟相位:第一个边沿SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;// 软件片选SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_4;// 分频系数:4SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;// MSB先传输SPI_InitStructure.SPI_CRCPolynomial=7;// CRC多项式SPI_Init(SPI1,&SPI_InitStructure);// 5. 使能SPI1SPI_Cmd(SPI1,ENABLE);}/** * @brief SPI发送和接收一个字节 * @param SPIx: SPI接口,如SPI1、SPI2等 * @param data: 要发送的数据 * @retval 接收到的数据 */uint8_tSPI_TransferByte(SPI_TypeDef*SPIx,uint8_tdata){// 等待发送缓冲区为空while(SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_TXE)==RESET);// 发送数据SPI_I2S_SendData(SPIx,data);// 等待接收缓冲区非空while(SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_RXNE)==RESET);// 返回接收到的数据returnSPI_I2S_ReceiveData(SPIx);}/** * @brief SPI发送数据 * @param SPIx: SPI接口,如SPI1、SPI2等 * @param data: 要发送的数据数组 * @param length: 数据长度 * @retval 无 */voidSPI_SendData(SPI_TypeDef*SPIx,uint8_t*data,uint16_tlength){uint16_ti;for(i=0;i<length;i++){SPI_TransferByte(SPIx,data[i]);}}/** * @brief SPI接收数据 * @param SPIx: SPI接口,如SPI1、SPI2等 * @param data: 存储接收数据的数组 * @param length: 数据长度 * @retval 无 */voidSPI_ReceiveData
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/31 18:57:13

告别手动抢茅台:智能预约的自动化高效管理方案

告别手动抢茅台&#xff1a;智能预约的自动化高效管理方案 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署 项目地址: https://gitcode.com/GitHub_Trending/ca/campus-imaotai 你是否曾遇到这样的困扰&#…

作者头像 李华
网站建设 2026/1/31 20:32:05

3分钟解锁钉钉自动打卡:告别早起的智能秘诀

3分钟解锁钉钉自动打卡&#xff1a;告别早起的智能秘诀 【免费下载链接】AutoDingding 钉钉自动打卡 项目地址: https://gitcode.com/gh_mirrors/au/AutoDingding 每天早上被闹钟惊醒&#xff0c;匆匆忙忙洗漱出门&#xff0c;一路狂奔只为赶上9点的打卡&#xff1f;这种…

作者头像 李华
网站建设 2026/2/2 3:59:33

STM32_PWR

简介 PWR(Power Control,电源控制)是 STM32 单片机中用于管理电源模式和电压的外设,支持多种低功耗模式,可显著降低系统功耗。STM32F407 系列芯片配备了功能强大的 PWR 外设,支持睡眠模式、停止模式、待机模式等多种低功耗模式,广泛应用于电池供电、低功耗应用等场景。…

作者头像 李华
网站建设 2026/2/3 5:55:27

阴阳师智能挂机助手:让游戏更轻松的自动化工具

阴阳师智能挂机助手&#xff1a;让游戏更轻松的自动化工具 【免费下载链接】yysScript 阴阳师脚本 支持御魂副本 双开 项目地址: https://gitcode.com/gh_mirrors/yy/yysScript 你是否也曾因为每天重复刷御魂而感到枯燥乏味&#xff1f;是否希望有一款工具能够帮助你自动…

作者头像 李华
网站建设 2026/1/30 1:43:19

如何用代码绘制科研级图形?揭秘LaTeX绘图的隐藏优势

如何用代码绘制科研级图形&#xff1f;揭秘LaTeX绘图的隐藏优势 【免费下载链接】tikz Random collection of standalone TikZ images 项目地址: https://gitcode.com/gh_mirrors/tikz/tikz 在科研论文的创作过程中&#xff0c;可视化元素往往决定了研究成果的传达效率。…

作者头像 李华