当前位置: 首页 > news >正文

STM32的SPI接口详解

目录

1.SPI简介

2.SPI工作原理

3.SPI时序

3.1 CPOL(Clock Polarity,时钟极性):

3.2 CPHA(Clock Phase,时钟相位):

3.3  四种工作模式

4.相关代码

4.1使能片选信号

4.2使能通讯线

4.3初始化SPI

4.4设置SPI速度

4.5读写数据


1.SPI简介

STM32 的SPI(Serial Peripheral Interface)是一个串行外设接口,它允许STM32微控制器与其他设备(如传感器、存储器等)进行高速、全双工、同步的串行通信。通常包含SCK(串行时钟)、MOSI(主设备输出/从设备输入)、MISO(主设备输入/从设备输出)和NSS(片选信号)这4条线,支持多个从设备连接到一个主设备上。

2.SPI工作原理

MISO   主设备数据输入,从设备数据输出。
MOSI   主设备数据输出,从设备数据输入。
SCLK   时钟信号,由主设备产生。
CS       从设备片选信号,由主设备控制。

主机和从机都存在一个移位寄存器,主机将要传输的数据保存到移位寄存器上,然后通过MOSI发送到从机的移位寄存器上,从机同时也将自己移位寄存器保存的数据通过MISO发送到主机的移位寄存器中,这样就完成了一次主机和从机的数据交换,如果是进行写操作,主机只要无视从机返回的数据就可以了,如果是进行读操作,那么主机就要发送对应字节的空字节来推动从机的数据传输

3.SPI时序

SPI通过CS片选设备以后开启数据传输,数据传输根据主机CPHA(Clock Phase,时钟相位)和CPOL(Clock Polarity,时钟极性)配置的不同衍生出了不同的工作模式。

3.1 CPOL(Clock Polarity,时钟极性):

CPOL决定了SPI通信中空闲状态的时钟电平。

当CPOL=0时,空闲状态下SCK(Serial Clock,串行时钟)为低电平。
当CPOL=1时,空闲状态下SCK为高电平。

3.2 CPHA(Clock Phase,时钟相位):

CPHA决定了数据是在SCK的第一个边沿还是第二个边沿被采样。

当CPHA=0时,数据在SCK的第一个边沿被采样(对于MOSI是上升沿,对于MISO可能是下降沿,取决于具体实现)。
当CPHA=1时,数据在SCK的第二个边沿被采样(对于MOSI是下降沿,对于MISO可能是上升沿)。

CPHA的选择影响数据传输的时序和稳定性。

3.3  四种工作模式

通过CPOL和CPHA的不同值组合,可以实现SPI的四种模式:

模式1 (CPOL=0, CPHA=0):空闲时SCK为低电平,数据在SCK的第一个上升沿被主设备发送,并在第一个下降沿被从设备接收。
模式2 (CPOL=0, CPHA=1):空闲时SCK为低电平,数据在SCK的第二个上升沿被采样。
模式3 (CPOL=1, CPHA=0):空闲时SCK为高电平,数据在SCK的第一个下降沿被主设备发送,并在第一个上升沿被从设备接收。
模式4 (CPOL=1, CPHA=1):空闲时SCK为高电平,数据在SCK的第二个下降沿被采样。

4.相关代码

本文基于STM32F429的HAL库为例讲解一下相关代码。

4.1使能片选信号

#define	W25QXX_CS 		PFout(6)  		//W25QXX的片选信号GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOF_CLK_ENABLE();           //使能GPIOF时钟//PF6
GPIO_Initure.Pin=GPIO_PIN_6;            //PF6
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST;     //快速         
HAL_GPIO_Init(GPIOF,&GPIO_Initure);     //初始化W25QXX_CS=1;			                //SPI 不选中

使能GPIO_PF6为SPI的片选信号,默认拉高不选中。

4.2使能通讯线

 GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOF_CLK_ENABLE();       //使能GPIOF时钟__HAL_RCC_SPI5_CLK_ENABLE();        //使能SPI5时钟//PF7,8,9GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;GPIO_Initure.Mode=GPIO_MODE_AF_PP;              //复用推挽输出GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉GPIO_Initure.Speed=GPIO_SPEED_FAST;             //快速            GPIO_Initure.Alternate=GPIO_AF5_SPI5;           //复用为SPI5HAL_GPIO_Init(GPIOF,&GPIO_Initure);

使能SPI5,GPIO_F7/F8/F9推挽输出,默认上拉,快速,复用为SPI5。

4.3初始化SPI

void SPI5_Init(void)
{SPI5_Handler.Instance=SPI5;                         //SP5SPI5_Handler.Init.Mode=SPI_MODE_MASTER;             //设置SPI工作模式,设置为主模式SPI5_Handler.Init.Direction=SPI_DIRECTION_2LINES;   //设置SPI单向或者双向的数据模式:SPI设置为双线模式SPI5_Handler.Init.DataSize=SPI_DATASIZE_8BIT;       //设置SPI的数据大小:SPI发送接收8位帧结构SPI5_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH;    //串行同步时钟的空闲状态为高电平SPI5_Handler.Init.CLKPhase=SPI_PHASE_2EDGE;         //串行同步时钟的第二个跳变沿(上升或下降)数据被采样SPI5_Handler.Init.NSS=SPI_NSS_SOFT;                 //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI5_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为256SPI5_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI5_Handler.Init.TIMode=SPI_TIMODE_DISABLE;        //关闭TI模式SPI5_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验SPI5_Handler.Init.CRCPolynomial=7;                  //CRC值计算的多项式HAL_SPI_Init(&SPI5_Handler);//初始化__HAL_SPI_ENABLE(&SPI5_Handler);                    //使能SPI5SPI5_ReadWriteByte(0Xff);                           //启动传输
}

设置SPI为主机工作模式,双线模式,空闲状态为高电平,数据为8位帧结构,二个跳变沿(上升或下降)数据被采样,片选信号由软件控制,数据传输从MSB位开始,关闭硬件CRC校验,最后启动传输。

我们把 SPI5 的频率设置成了最低的256 分频,后面我们可以随时通过函数 SPI5_SetSpeed 来设置 SPI5 的速度。

4.4设置SPI速度

void SPI5_SetSpeed(u8 SPI_BaudRatePrescaler)
{assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性__HAL_SPI_DISABLE(&SPI5_Handler);            //关闭SPISPI5_Handler.Instance->CR1&=0XFFC7;          //位3-5清零,用来设置波特率SPI5_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//设置SPI速度__HAL_SPI_ENABLE(&SPI5_Handler);             //使能SPI}

SPI_BaudRatePrescaler 可以设置 2/4/8/16/32/64/128/256分频,例如STM32F429的APB1为90MHz,设置2分频就是45MHz。

4.5读写数据

void read(){W25QXX_CS=0;//拉低片选信号      SPI5_ReadWriteByte(0XFF);W25QXX_CS=1; //拉高片选信号      
}u8 SPI5_ReadWriteByte(u8 TxData)
{u8 Rxdata;HAL_SPI_TransmitReceive(&SPI5_Handler,&TxData,&Rxdata,1, 1000);       return Rxdata;          		    //返回收到的数据		
}

读写数据都是用SPI5_ReadWriteByte这个函数,不同的是,如果是写入数据,不用管接收到的从机数据是什么,如果是读取数据,则可以发送0XFF,读取从机返回的对应数据

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【算法】代码随想录之数组(更新中)
  • Python学习笔记33:进阶篇(二十二)pygame的使用之image模块
  • 【笔记】在window上连接虚拟机中的redis
  • PTA - 编写函数计算圆面积
  • 垃圾回收器详解
  • mybatis-plus中的方法的作用
  • 【网络安全的神秘世界】XSS基本概念和原理介绍
  • FFmpeg引用计数数据缓冲区相关的结构体:AVBuffer、AVBufferRef简介
  • 3款ui设计师必备的高效软件,一定要收藏!
  • 谷粒商城 - 编写一个自定义校验注解
  • k8s-第一节-minikube
  • [从0开始轨迹预测][NMS]:NMS的应用(目标检测、轨迹预测)
  • 数据库图形化管理界面应用 Navicat Premium 使用教程
  • 基于SpringBoot构造超简易QQ邮件服务发送 第二版
  • 【持续集成_03课_Linux部署Sonar+Gogs+Jenkins】
  • SegmentFault for Android 3.0 发布
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Brief introduction of how to 'Call, Apply and Bind'
  • Elasticsearch 参考指南(升级前重新索引)
  • git 常用命令
  • jdbc就是这么简单
  • JSONP原理
  • laravel5.5 视图共享数据
  • nfs客户端进程变D,延伸linux的lock
  • python大佬养成计划----difflib模块
  • React+TypeScript入门
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 类orAPI - 收藏集 - 掘金
  • 前端相关框架总和
  • 前端之React实战:创建跨平台的项目架构
  • 人脸识别最新开发经验demo
  • 如何设计一个微型分布式架构?
  • 手机端车牌号码键盘的vue组件
  • 温故知新之javascript面向对象
  • 异步
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​你们这样子,耽误我的工作进度怎么办?
  • #includecmath
  • (13)Hive调优——动态分区导致的小文件问题
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (十一)图像的罗伯特梯度锐化
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (一)SvelteKit教程:hello world
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)大道至简,职场上做人做事做管理
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .net core使用ef 6
  • .net mvc 获取url中controller和action
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .Net的DataSet直接与SQL2005交互