嵌入式学习笔记——SPI协议

news2025/4/5 22:23:18

SPI协议详解

    • SPI协议概述
    • SPI接口信号介绍
    • SPI通信模式
    • SPI的通信流程
    • SPI的优缺点
      • 优点
      • 缺点
    • SPI在STM32上的实现
      • SPI引脚配置
      • SPI初始化代码(STM32F10x)
      • SPI主设备发送和接收数据
      • SPI从设备数据处理
    • 总结

SPI协议概述

SPI(Serial Peripheral Interface)是摩托罗拉公司提出的一种同步串行通信协议,用于MCU(微控制器)与外围设备之间的高速数据交换。它是一种全双工通信协议,数据可以在主设备和从设备之间同时传输,广泛应用于FLASH存储器、传感器、液晶显示屏、SD卡等设备。

SPI接口信号介绍

SPI协议使用以下四条主要信号线:

信号名称说明
MOSI(Master Out, Slave In)主设备输出,从设备输入,数据从主机发送到从机
MISO(Master In, Slave Out)主设备输入,从设备输出,数据从从机发送到主机
SCLK(Serial Clock)串行时钟,由主设备生成,控制数据传输速率
SS(Slave Select)片选信号,低电平时选中从设备

SPI通信模式

SPI有四种不同的工作模式,它们由时钟极性(CPOL)和时钟相位(CPHA)决定:

SPI模式CPOLCPHA说明
模式000时钟空闲时为低电平,数据在上升沿采样
模式101时钟空闲时为低电平,数据在下降沿采样
模式210时钟空闲时为高电平,数据在下降沿采样
模式311时钟空闲时为高电平,数据在上升沿采样

SPI的通信流程

  1. 主设备拉低片选信号SS,选中从设备
  2. 主设备发送时钟信号SCLK,驱动数据传输。
  3. 数据通过MOSI和MISO传输,同时进行发送和接收。
  4. 数据传输完成后,主设备拉高SS信号,结束通信

SPI的优缺点

优点

  • 高速通信:SPI的通信速率可达几十MHz,比I2C快。
  • 全双工传输:同时进行数据发送和接收。
  • 简单易用:只需4条信号线,硬件开销较小。

缺点

  • 多设备连接复杂:每个从设备都需要一个独立的片选信号。
  • 缺少标准化设备地址:不像I2C,SPI必须通过额外的SS信号管理多个设备。

SPI在STM32上的实现

SPI引脚配置

在STM32中,常见的SPI引脚如下:

引脚说明
PB13SCLK(时钟信号)
PB14MISO(从机数据输出)
PB15MOSI(主机数据输出)
PB12NSS(片选信号)

SPI初始化代码(STM32F10x)

#include "stm32f10x.h"

void SPI_Init_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;

    // 使能GPIOB和SPI2的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    // 配置SPI引脚(PB13 SCLK, PB14 MISO, PB15 MOSI)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置SPI参数
    SPI_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_High;                       // 空闲时钟高电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                      // 第二个时钟沿采样数据
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                         // NSS软件管理
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 波特率预分频
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                 // 高位优先
    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);
    SPI_Cmd(SPI2, ENABLE);
}

SPI主设备发送和接收数据

void SPI_Master_Config(void)
{
    SPI_Init_Config();
    while (1)
    {
        // 等待发送缓冲区为空
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
        
        // 发送数据
        SPI_I2S_SendData(SPI2, 0xAA);
        
        // 等待接收缓冲区非空
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
        
        // 读取接收到的数据
        uint8_t received_data = SPI_I2S_ReceiveData(SPI2);
    }
}

SPI从设备数据处理

void SPI_Slave_Config(void)
{
    SPI_Init_Config();
    while (1)
    {
        // 等待接收缓冲区非空
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
        
        // 读取接收到的数据
        uint8_t received_data = SPI_I2S_ReceiveData(SPI2);

        // 等待发送缓冲区为空
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
        
        // 发送数据
        SPI_I2S_SendData(SPI2, 0x55);
    }
}

总结

SPI是一种高速、全双工的同步通信协议,适用于各种外围设备的通信。通过STM32的SPI模块,我们可以轻松实现主从机通信。对于初学者,理解SPI的时序、引脚配置以及初始化代码,是使用SPI进行实际工程开发的重要前提。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络编程—Socket套接字(UDP)

上篇文章: 网络编程—网络概念https://blog.csdn.net/sniper_fandc/article/details/146923380?fromshareblogdetail&sharetypeblogdetail&sharerId146923380&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 概念 2 Soc…

视频设备轨迹回放平台EasyCVR综合智能化,搭建运动场体育赛事直播方案

一、背景 随着5G技术的发展,体育赛事直播迎来了新的高峰。无论是NBA、西甲、英超、德甲、意甲、中超还是CBA等热门赛事,都是值得记录和回放的精彩瞬间。对于体育迷来说,选择观看的平台众多,但是作为运营者,搭建一套体…

AIGC实战——CycleGAN详解与实现

AIGC实战——CycleGAN详解与实现 0. 前言1. CycleGAN 基本原理2. CycleGAN 模型分析3. 实现 CycleGAN小结系列链接 0. 前言 CycleGAN 是一种用于图像转换的生成对抗网络(Generative Adversarial Network, GAN),可以在不需要配对数据的情况下将一种风格的图像转换成…

VS2022远程调试Linux程序

一、 1、VS2022安装参考 VS Studio2022安装教程(保姆级教程)_visual studio 2022-CSDN博客 注意:勾选的时候,要勾选下方的选项,才能调试Linux环境下运行的程序! 2、VS2022远程调试Linux程序测试 原文参…

345-java人事档案管理系统的设计与实现

345-java人事档案管理系统的设计与实现 项目概述 本项目为基于Java语言的人事档案管理系统,旨在帮助企事业单位高效管理员工档案信息,实现档案的电子化、自动化管理。系统涵盖了员工信息的录入、查询、修改、删除等功能,同时具备权限控制和…

【Linux系统编程】进程概念,进程状态

目录 一,操作系统(Operator System) 1-1概念 1-2设计操作系统的目的 1-3核心功能 1-4系统调用和库函数概念 二,进程(Process) 2-1进程概念与基本操作 2-2task_struct结构体内容 2-3查看进程 2-4通…

优选算法的妙思之流:分治——快排专题

专栏:算法的魔法世界 个人主页:手握风云 目录 一、快速排序 二、例题讲解 2.1. 颜色分类 2.2. 排序数组 2.3. 数组中的第K个最大元素 2.4. 库存管理 III 一、快速排序 分治,简单理解为“分而治之”,将一个大问题划分为若干个…

wx206基于ssm+vue+uniapp的优购电商小程序

开发语言:Java框架:ssmuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:M…

React编程高级主题:错误处理(Error Handling)

文章目录 **5.2 错误处理(Error Handling)概述****5.2.1 onErrorReturn / onErrorResume(错误回退)****1. onErrorReturn:提供默认值****2. onErrorResume:切换备用数据流** **5.2.2 retry / retryWhen&…

ubuntu20.04升级成ubuntu22.04

命令行 sudo do-release-upgrade 我是按提示输入y确认操作,也可以遇到配置文件冲突时建议选择N保留当前配置

SpringCloud(25)——Stream介绍

1.场景描述 当我们的分布式系统建设到一定程度了,或者服务间是通过异步请求来通讯的,那么我们避免不了使用MQ来解决问题。 假如公司内部进行了业务合并或者整合,需要服务A和服务B通过MQ的方式进行消息传递,而服务A用的是RabbitMQ&…

centos8上实现lvs集群负载均衡dr模式

1.前言 个人备忘笔记,欢迎探讨。 centos8上实现lvs集群负载均衡nat模式 centos8上实现lvs集群负载均衡dr模式 之前写过一篇lvs-nat模式。实验起来相对顺利。dr模式最大特点是响应报文不经调度器,而是直接返回客户机。 dr模式分同网段和不同网段。同…

uniapp如何接入星火大模型

写在前面:最近的ai是真的火啊,琢磨了一下,弄个uniappx的版本开发个东西玩一下,想了想不知道放啥内容,突然觉得deepseek可以接入,好家伙,一对接以后发现这是个付费的玩意,我穷&#x…

MySQL vs MSSQL 对比

在企业数据库管理系统中,MySQL 和 Microsoft SQL Server(MSSQL)是最受欢迎的两大选择。MySQL 是一款开源的关系型数据库管理系统(RDBMS),由 MySQL AB 开发,现归属于 Oracle 公司。而 MSSQL 是微…

python基础-10-组织文件

文章目录 【README】【10】组织文件(复制移动删除重命名)【10.1】shutil模块(shell工具)【10.1.1】复制文件和文件夹【10.1.1.1】复制文件夹及其下文件-shutil.copytree 【10.1.2】文件和文件夹的移动与重命名【10.1.3】永久删除文件和文件夹【10.1.4】用…

ORA-09925 No space left on device 问题处理全过程记录

本篇文章关键字:linux、oracle、审计、ORA-09925 一、故障现像 朋友找到我说是他们备份软件上报错。 问题比较明显,ORA-09925,看起来就是空间不足导致的 二、问题分析过程 这里说一下逐步的分析思路,有个意外提前说一下就是我…

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测&#…

27信号和槽_自定义信号(2)

自定义信号和槽 绑定信号和槽 如何才能触发出自定义的信号呢?(上诉代码只是将信号和槽绑定在一起,但并没有触发信号) Qt 内置的信号,都不需要咱们手动通过代码来触发 用户在 GUI, 进行某些操作,就会自动触发对应信号.(发射信号的代码已经内置…

人工智能在生物医药领域的应用地图:AIBC2025将于6月在上海召开!

人工智能在生物医药领域的应用地图:AIBC2025将于6月在上海召开! 近年来,人工智能在生物医药行业中的应用受到广泛关注。 2024年10月,2024诺贝尔化学奖被授予“计算蛋白质设计和蛋白质结构预测”,这为行业从业人员带来…

2025.3.19

1、用vim编辑/etc/hosts文件,将本机和第二个虚拟机的ip地址和主机名写入该文件,然后ping 两个主机的主机名能否ping通; (1)在第一个虚拟机编辑/etc/hosts: 首先使用hostname、hostnamectl、hostname -f指令查看主机名…