STM32--SPI通信与W25Q64(2)

STM32–SPI通信与W25Q64(1)

文章目录

  • SPI外设
    • 特征
  • SPI框图
  • 传输模式
    • 主模式全双工连续传输
  • 非连续传输
  • 硬件SPI读写W25Q64

SPI外设

STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担

特征

3线全双工同步传输
8或16位传输帧格式选择
主或从操作
支持多主模式
8个主模式波特率预分频系数(最大为fPCLK/2)
主模式和从模式下均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变
可编程的数据顺序, MSB在前或LSB在前
可编程的时钟极性和相位
SPI总线忙状态标志
兼容I2S协议

STM32F103C8T6 硬件SPI资源:SPI1、SPI2

SPI框图

在这里插入图片描述
通过主控制电路来控制数据的传输;

先看左上角部分,对于接收的数据,会从MISO引脚进入;数据一位一位的进入移位寄存器,当有一个字节(或者两个字节大小)的数据在移位寄存器时,传送移位寄存器里的数据到接收缓冲器,并且RXNE标志被置位

这里的RXNE是是接收缓冲区的标志位,
在这里插入图片描述

读SPI_DR接收寄存器可以清除RNXE标志位
在连续传输数据中,一个要接收的数据只有被读出,下一个数据才有机会进入接收缓冲器。而利用RNXE标志位即可知道当前数据是否被读出。否则,下一个数据会对当前数据进行覆盖,那么读取数据就会造成错误。
对于要发送的数据,会将写入数据先放在发送缓冲器中,在发送第一个数据位时,数据字被并行地(通过内部总线)传入移位寄存器,而后串行地移出到MOSI脚上;(可自行设定低位先行还是高位先行); 数据从发送缓冲器传输到移位寄存器时TXE标志将被置位

发送到移位寄存器的标志位在这里插入图片描述

只要写入SPI_DR寄存器那么TXE标志位就会被清除。这里将移位寄存器和接收缓冲区和发送缓冲区合在一起,就是数据寄存器;
这里要注意,数据寄存器内部会分为两部分,接收和发送,移位寄存器是共用的,但传输单位最小是8bit或者是16bit,都是以字节为单位的,不会造成同时进行发送和接收的冲突

右边则是将寄存器的位都标出来了,CR是控制寄存器,只要是产生使能的寄存器;SR是状态寄存器,比较重要的就是刚才介绍的两个RXNE和TXE;

波特率发生器用来控制SCK分频;

传输模式

主模式全双工连续传输

同时进行传输的
在这里插入图片描述
一开始,会先写入一个数据1,接着会使标志位TXE置非空,等到TXE位空时,再写入一个数据2,此时会等待RXNE非空时,读取数据A1,接着就是等到TXE为空,再写入一个数据3,然后又是等待RXNE非空时,读取数据A2…以此传输下去,到最后,RXNE非空,读取数据AN,TXE也为空时,BSY位置0,关闭SPI模块;
在这里插入图片描述

这里的连续传输就是在一开始一个数据写入之后,还会继续写入一个数据,由于是同时进行传输,所以等到读取数据后又写入一个数据;
在最后会连续读取两个数据表示结束。

非连续传输

在这里插入图片描述
一开始写入一个数据1,接着会等待TXE为空时,此时读取一个数据A1,接着会等待RXNE非空时,再写入数据2,以此类推。
在这里插入图片描述

对于写入的数据,等待TXE为空后,本来可以再写入一个数据,但是在这种模式是读取一个数据,等到RXNE非空时,再写入数据;
你会发现,在标志位后本来是做出对应的事件,但是这种方式却是选择等待,也就是传输的数据是不连续的。

硬件SPI读写W25Q64

这里的接线方式和试验方法和软件读写是一致的,只是将MySPI.进行改装。

#include "stm32f10x.h"                  // Device header

//片选电平
void MySPI_W_SS(uint8_t Byte)
{
    GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)Byte);
}


//初始化
void MySPI_Init()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    SPI_InitTypeDef SPI_InitStructure;
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128; //设置SCK时钟波特率分频值
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//指定哪个边沿开始捕获
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low; //低边沿为常态
    SPI_InitStructure.SPI_CRCPolynomial=7; //CRC设置值,默认值为7
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//传输数据大小(bit)
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//设置双工和收发
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;//指定传输从低位还是高位开始
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//主从模式
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//软件设置
    SPI_Init(SPI1,&SPI_InitStructure);
    
    SPI_Cmd(SPI1,ENABLE);
    MySPI_W_SS(1);
    
}
//开始
void MySPI_Start()
{
    MySPI_W_SS(0);
}
//结束
void MySPI_Stop()
{
    MySPI_W_SS(1);
}
//交换字节
uint8_t MySPI_SwapByte(uint8_t SendByte)
{
    while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE));
    SPI_I2S_SendData(SPI1,SendByte);
    while(!SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE));
    return SPI_I2S_ReceiveData(SPI1);
}

对于片选信号,我们用GPIO引脚表示高低电平会更加容易;
对于A5和A7引脚,由于SPI外设是GPIO口的片上外设,所以要采用复用功能;
这里SPI外设的传输是有多种模式,我们选择全双工收发模式;
高位开始低位开始传输也是可以选择的;
最后要记得要启用SPI,否则将无效;

这里的交换字节采用非连续传输的方式,我们的顺序与上面的逻辑图是相反的,是因为对于标志位,在读取和写入时会自动清除标志位,先写标志位,再写发送数据和读出数据会更加方便;

在这里说一下试验的注意事项,

对于扇区擦除,只要输入的数据在指定扇区,那么就会对那一片扇区进行擦除;
在这里插入图片描述
这是一片扇区,那么输入000000h到000FFFh的地址位,都是对该扇区的擦除;

对于测试连续写入多字节时,最多写入一页的数据,超过页尾位置的数据,会回到页首覆盖写入。
我们可以以000000h为头,那么0000FFh就是尾,(页的大小)进行测试;通过改变地址来进行验证。

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

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

相关文章

2023.8各大浏览器11家对比:Edge/Chrome/Opera/Firefox/Tor/Vivaldi/Brave,安全性,速度,体积,内存占用

测试环境:全默认设置的情况下,均在全新的系统上进行测试,系统并未进行任何改动,没有杀毒软件,浏览器进程全部在后台,且为小窗模式,小窗分辨率均为浏览器厂商默认缩放大小(变量不唯一)&#xff0…

Window基础命令

文章目录 查看哪些端口被禁用TCP协议删除开机启动项方案1方案2 查看哪些端口被禁用TCP协议 netsh interface ipv4 show excludedportrange protocoltcp删除开机启动项 方案1 列出所有启动项 bcdedit /enum仔细看你要删除的是哪一项(看description)&a…

【LeetCode: 56. 合并区间+贪心+双指针+标识+模拟】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

postgresql类型转换函数

postgresql类型转换函数 简介CAST 函数to_date 函数to_timestamp 函数to_char 函数to_number 函数隐式类型转换 简介 类型转换函数用于将数据从一种类型转换为另一种类型。 CAST 函数 CAST ( expr AS data_type )函数用于将 expr 转换为 data_type 数据类型;Post…

稳恒电路直观理解

图v0 图v1 图v2 图v3 图v4 自由正电荷s,定向移动过程中,在任何一位置处受力都是平衡的,即s所受总合力为0, 即s处于匀速运动:直导体中匀速直线运动、拐弯处匀速圆周运动 起初t0时刻, s的势能是最高的E0,之…

MyBatisPlus实现多租户功能

前言:多租户是一种软件架构技术,在多用户的环境下,共有同一套系统,并且要注意数据之间的隔离性。 一、SaaS多租户简介 1.1、SaaS多租户 SaaS,是Software-as-a-Service的缩写名称,意思为软件即服务&#x…

ThinkPHP 文件上传 fileSystem 扩展的使用

ThinkPHP 文件上传 ThinkPHP 文件上传 扩展 filesystem一、安装 FileSystem 扩展二、认识 filesystem 配置文件 config/filesystem.php三、上传验证(涉及到验证器的知识点)四、文件上传demo ThinkPHP 文件上传 扩展 filesystem ThinkPHP 为我们 提供了 …

WebRTC之FEC前向纠错协议

FEC前向纠错用于丢包恢复,对媒体包进行异或或其他算法生成冗余包进行发送。如果接收端出现丢包,可以通过冗余包恢复出原始的媒体包。FEC的代价是增加码率带宽,所以一般会根据网络状况、丢包率来动态调整FEC冗余系数,也会结合NACK/…

软件测试之Web压力测试怎么做?

Web压力测试是评估一个网站、应用程序或服务在高负载情况下的性能表现的过程。这种测试可以帮助确定系统的极限容量,发现性能瓶颈,并确保系统在实际使用情况下能够稳定运行。以下是进行Web压力测试的一般步骤: 1.制定测试计划:定…

基于亚马逊云科技服务,构建大语言模型问答知识库

随着大语言模型效果明显提升,其相关的应用不断涌现呈现出越来越火爆的趋势。其中一种比较被广泛关注的技术路线是大语言模型(LLM)知识召回(Knowledge Retrieval)的方式,在私域知识问答方面可以很好的弥补通…

【24考研】:四川大学计算机学院23届874考研考情分析

四川大学计算机学院23届CS考研考情分析 作者:老李 往年都是大佬们做的, 今年正好自己在做公众号这一块, 因此不自量力的承担这个工作,顺便锻炼一点pandas包和plt包的应用能力。 所以形式上我也会仿照一下往年的大佬。 21考情&a…

助力网络管理的利器:企业办公网络中的VLAN划分策略

企业办公网络的性能和安全性对员工的高效工作和信息安全具有重要意义。在实现这一目标时,VLAN(Virtual Local Area Network)划分在网络设计中发挥着至关重要的作用。通过将办公网络划分为多个虚拟局域网,VLAN划分可以实现网络资源…

FFI绕过disable_functions

文章目录 FFI绕过disable_functions[RCTF 2019]NextphpPHP7.4 FFI参考 FFI绕过disable_functions [RCTF 2019]Nextphp 首先来看这道题目 index.php <?php if (isset($_GET[a])) {eval($_GET[a]); } else {show_source(__FILE__); }查看一下phpinfo 发现过滤了很多函数&…

使用openpyxl来创建一个月的日程表

首先你心里要有一张表的样子&#xff0c;openpyxl才能帮你创建出其余的29张。 import openpyxl from openpyxl.styles import Alignment, Font import calendar from datetime import datework_path rXX\YY\ZZ\日报-九月.xlsxtry:workbook openpyxl.load_workbook(work_path…

系统架构设计高级技能 · 面向服务架构设计理论与实践

点击进入系列文章目录 系统架构设计高级技能 面向服务架构设计理论与实践 一、SOA的相关概念1.1SOA的定义1.2 业务流程与业务流程执行语言 二、SOA的发展史三、SOA与微服务的区别三、SOA的参考架构四、SOA的主要协议规范五、SOA的设计标准要求六、SOA的作用与设计原则七、SOA的…

Linux土遁术之监测监测进程打开文件

分析问题过程中&#xff0c;追踪进程打开的文件可以在许多不同情况下有用&#xff0c;体现在以下几个方面&#xff1a; 故障排除和调试&#xff1a; 当程序出现问题、崩溃或异常行为时&#xff0c;追踪进程打开的文件可以帮助您找出问题的根本原因。这有助于快速定位错误&…

运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0)&#xff1b; pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 一&#xff1a; if...elif...elif..else fi多层…

【UniApp开发小程序】小程序私聊页面完善(仿微信带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】

文章目录 说明仿微信带尾巴聊天气泡组件效果展示组件整体代码气泡主体气泡尾巴 使用 私聊页面滑动到顶部获取历史数据页面整体代码 说明 之前已经在【UniApp开发小程序】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】这篇文章中介绍了私聊页…

跨屏无界 | ZlongGames 携手 Google Play Games 打造无缝游戏体验

一款经典游戏&#xff0c;会在时间的沉淀中被每一代玩家所怀念&#xff0c;经久不衰。对于紫龙游戏来讲&#xff0c;他们就是这样一群怀揣着创作出经典游戏的初心而聚集在一起的团队&#xff0c;致力于研发出被广大玩家喜爱的作品。 从 2015 年团队成立&#xff0c;到 2019 年走…

Shell - 加固系统配置

文章目录 #! /bin/bash # Function:对账户的密码的一些加固 read -p "设置密码最多可多少天不修改&#xff1a;" A read -p "设置密码修改之间最小的天数&#xff1a;" B read -p "设置密码最短的长度&#xff1a;" C read -p "设置密码失效…