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,9
 GPIO_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;           //复用为SPI5
 HAL_GPIO_Init(GPIOF,&GPIO_Initure);

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

4.3初始化SPI

void SPI5_Init(void)
{
    SPI5_Handler.Instance=SPI5;                         //SP5
    SPI5_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;//定义波特率预分频的值:波特率预分频值为256
    SPI5_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);                    //使能SPI5
	
    SPI5_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);            //关闭SPI
    SPI5_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,读取从机返回的对应数据

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue学习day01-vue的概念、创建Vue实例、插值表达式、响应式、安装Vue开发者工具

1、vue的概念 Vue是一个用于构建用户界面的渐进式 框架 (1)构建用户界面:基于数据动态渲染页面 (2)渐进式:循序渐进的学习 (3)框架:一条完整的项目解决方案&#xff…

回溯算法-以医院信息管理系统为例

1.回溯算法介绍 1.来源 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。 用回溯算法解决问题的一般步骤: 1、 针对所给问题,定义问题的解空间,它至少包含问题的一个(最优)解。 2 、确定易于搜…

Redis代替Session实现共享

集群的session共享问题 session共享问题:多台tomcat并不共享session存储空间,当请求切换到不同的tomcat服务时导致数据丢失的问题。 session的替代方案: 数据共享内存存储key、value结构 将redis替换session可以解决session共享问题

一文学会 BootStrap

文章目录 认识BootStrap历史优缺点使用注意安装CDN源码引入包管理器 媒体查询屏幕尺寸的分割点(Breakpoints)响应式容器网格系统基本使用底层实现.container.row.col、.col-份数 网格嵌套自动布局列 Auto-layout响应式类 Responsive Class 响应式工具类-…

在 PostgreSQL 里如何处理数据的版本跟踪和回滚?

文章目录 一、事务二、保存点三、使用版本控制扩展四、审计表和触发器五、使用时间戳列六、比较和还原数据七、考虑数据备份和恢复八、结论 在数据库管理中,数据的版本跟踪和回滚是非常重要的功能,有助于在数据操作出现错误或需要回滚到特定状态时进行有…

dbeaver连接postgresql报错��������: �û� “root“ Password ��֤ʧ��

文章目录 问题描述解决办法 问题描述 新安装完成的postgresql通过dbeaver连接访问报错��������: �� “root” Password ��֤ʧ&#…

纷享销客荣获CDIE“2024优秀数字化技术服务商”

近日,在第十届数字化创新博览会(CDIE 2024)上,CRM品牌领导者纷享销客凭借其卓越的技术实力和创新的解决方案,荣获“2024 优秀数字化技术服务商”奖项。 作为国内领先的CRM数字化解决方案服务商,纷享销客一直…

如何构建数据驱动的企业?爬虫管理平台是关键桥梁吗?

一、数据驱动时代:为何选择爬虫管理平台? 在信息爆炸的今天,数据驱动已成为企业发展的核心战略之一。爬虫管理平台,作为数据采集的第一站,它的重要性不言而喻。这类平台通过自动化手段,从互联网的各个角落…

static的理论学习

在说到static之前,需要先明确变量类型: 而在聊到变量类型之前我们可以将变量的两个属性好好学一学 变量的两个属性 作用域(scope): 从内存的角度来看,就是变量存放在栈(stack)中&…

Open3D SVD算法实现对应点集配准

目录 一、概述 1.1基本思想 1.2实现步骤 二、代码实现 三、实现效果 3.1原始点云 3.2配准后点云 3.3变换矩阵 一、概述 在点云配准中,SVD(Singular Value Decomposition,奇异值分解)方法是一种常用的精确计算旋转和平移变换的算法。其目标是找到一个刚体变…

解答|企业网站为什么首选OV SSL证书

在数字化转型日益加速的今天,企业网站不仅承载着品牌形象展示、产品服务介绍、客户互动沟通等多重功能,更是企业与客户建立信任桥梁的关键所在。然而,在网络空间中,数据安全与隐私保护成为不容忽视的核心议题。SSL证书作为加密通信…

在 PostgreSQL 里如何实现数据的自动清理和过期处理?

文章目录 一、使用 TIMESTAMP 列和定期任务二、使用事件触发器(Event Triggers)三、使用分区表(Partitioned Tables)四、结合存储过程和定时任务示例场景实现步骤测试与验证 在 PostgreSQL 中,可以通过多种方式实现数据…

Spring系统学习 - AOP之基于注解的AOP和XML的AOP

上一篇我们围绕了AOP中代理模式的使用,这篇我们将主要围绕AOP的相关术语介绍,以及重点围绕基于注解的AOP进行相关知识的概述和使用说明。 AOP的相关术语 切面(Aspect):切面是一个模块化的横切关注点,它包含…

mybatis-plus参数绑定异常

前言 最近要搞个发票保存的需求,当发票数据有id时说明是发票已经保存只需更新发票数据即可,没有id时说明没有发票数据需要新增发票;于是将原有的发票提交接口改造了下,将调用mybatis-plus的save方法改为saveOrUpdate方法&#xff…

C++:多态(继承)

hello,各位小伙伴,本篇文章跟大家一起学习《C:多态》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 ! 文章目录 :maple_leaf:多态的概念:maple_leaf:继承中的多态1.:leaves:虚函数表 :…

更亮更好听的户外耳机,下班之后畅快运动,哈氪聆光体验

在当今市场上,蓝牙耳机种类繁多,现在正值酷热的夏季,有必要准备一副适合户外活动的蓝牙耳机,对此,我觉得气传导耳机更适合在户外锻炼或散步时使用。这种耳机设计通常为后挂式,不仅佩戴舒适,而且…

宝塔面板运行Admin.net框架

准备 宝塔安装 .netcore安装 Admin.net框架发布 宝塔面板设置 完结撒花 1.准备 服务器/虚拟机一台 系统Windows server / Ubuntu20.04(本贴使用的是Ubuntu20.04版本系统) Admin.net开发框架 先安装好服务器系统,这里就不做安装过程描述了&…

安装nodejs | npm报错

nodejs安装步骤: 官网:https://nodejs.org/en/ 在官网下载nodejs: 双击下载下来的msi安装包,一直点next,我选的安装目录是默认的: 测试是否安装成功: 输入cmd打开命令提示符,输入node -v可以看到版本,说…

“郑商企航”暑期社会实践赴美丽美艳直播基地开展调研

马常旭文化传媒网讯(记者张明辉报道)导读:2024 年 7 月 3 日,商学院暑期社会实践团“郑商企航”在河南省郑州市新密市岳村镇美丽美艳直播基地,展开了一场意义非凡的考察活动,团队成员深度调研了直播基地的产…

DMA方式的知识点笔记

苏泽 “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家 目录 1. DMA基本概念 2. DMA传送过程 易错点 DMA控制器操作流程 3. DMA传送方式 这是单总线的结果 (CPU说了算 所以不会产生于CPU的冲突) 这…