SPI

news2025/4/15 18:07:41

Flash-W25Q64

-- 这一章的重点是重点是知道标准SPI通信,地址会算,FLASH时序要会看

目录

Flash-W25Q64

回顾

FLASH

SPI简介

单片机(32)上的SPI

W25Q64

模块之间应该怎么通信呢?-- 看时序图

代码编写

更改代码的错误

应用函数

应用:将图片生成的模写入flash中


回顾

-- LCD的核心主要是应用:带背景色的显示函数,动图等

-- LVGL:界面设计的工具

-- 低功耗模式:

尤其是电池供电的设备
设备进入低功耗模式:各个模块都进入低功耗模式
例如dht11,su03t,kqm6600,光敏电阻,mq2,lcd,芯片
芯片:睡眠》停机》待机(功耗从大到小)

  • 睡眠模式:任一个中断就可唤醒,唤醒之后,代码接着往下运行
    睡眠模式只把1.8v供电关闭

  • 停机模式:外部中断可以唤醒 ,唤醒之后,代码接着往下运行(唤醒之后系统默认使用内部高速时钟,所以要进行时钟重新初始化),类似于暂停
    停机模式是把VDDA,VDD,1.8v关闭了,电压调节器未关闭

  • 待机模式:需要特殊的唤醒方式(比如唤醒引脚,闹钟中断),唤醒之后,代码从头开始运行(重新),相当于复位
    待机模式是把VDDA,VDD,1.8v,电压调节器都关闭了

供电区域: 主要给什么供电
VDDA :ADC
VDD : IO,电压调节器
1.8V :内核
后备区域:RTC

spi与FALSH 

FLASH

-- 今天讲FLASH芯片:型号是w25Q64:8M的空间储存器(这个flash芯片与32芯片的一样)

-- 为什么引入这个呢?

-- 上一章学的LCD显示,汉字,图片,字符,都要先取模(取得模,都是数组,占的空间很大),咱们的芯片只有512kb,程序运行的时候,会报错,出现空间不够的情况。

-- 所以,我们引入一个外部的储存器,把取模的数据,放到外部的储存器中,这样,我们的芯片就可以正常工作了。

-- 今天我们讲FLASH芯片,主要的作用:保存字模,图片模

-- (FLASH芯片在银色旁边) 

alt text

SPI简介

-- USART,SPI,IIC三大串行通信方式

-- SPI:是通信总线

-- 什么叫总线类型的通信?(SPI和IIC都叫做总线通信)

  • 多设备通信,一对多,多对一(也支持一对一) (多个设备可以挂载到总线上,通过总线进行通信)

-- 如何判断设备是否支持串口通信?有RX和TX

-- 如何判断设备是否支持SPI通信? 有以下四根线

  • SCK:同步时钟
  • CS:片选线(类似于通信上的使能)
  • MISO:主机输入,从机输出
  • MOSI:主机输出,从机输如

-- 串口是异步通信,SPI是同步通信(有时钟线)

-- SPI是怎么实现一对多通信的?SPI物理层 

alt text

连接的个数跟芯片有关,也跟从机有关

为什么主机有两个cs,从机只有一个cs?每个从机都有一个cs,主机通过cs来控制从机,有几个从机,主机就有几个cs。

-- 为什么SPI只适合短距离通信? 

alt text


-- SPI的通信核心是数据交换原则 

alt text

-- 什么是数据交换原则? 

alt text

alt text

-- 那么为什么要在上升沿的时候发送数据,下降沿的时候接收数据呢?

-- SPI通信有四个工作模式:SPI0,SPI1,SPI2,SPI3
这四种工作模式规定了主机在哪个边沿(上升沿,下降沿)进行数据发送

-- 四种工作模式是如何形成的?
CPOL:时钟极性 (有两个取值0或者1),规定了空闲状态下,时钟的电平情况(0:低电平 1:高电平) CPHA:时钟相位(也有两个取值0/1),决定了主机在第几个边沿进行数据发送(当时钟相位=0时,是第一个边沿,=1时是第二个边沿) 

alt text

alt text

单片机(32)上的SPI

-- 查看参考手册上的SPI框图 

alt text

-- 接着看引脚 

alt text

-- 在32单片机上,比较特殊的一点,也是与标准SPI不同的一点就是他的其中一个引脚不是cs,而是NSS。还有就是32单片机上的SPI可以支持多主机(而在其他单片机的正常情况下,都是一主多从)。
每个STM32芯片都可以做主机,如果说某一个设备SSOE被使能,输出低电平,其他的设备都会变成从机


W25Q64

-- 下面来看该型号的官方文档 

alt text

-- 打开官方文档,看该型号的一些信息,其中最重要的一点:

  • 作为一个储存器,他是有自己的储存结构的(最小的是以字节为单位,然后从小到大一次是:字节-》页-》扇区-》块)

alt text

  • 单位的换算:一页是256字节,一扇区是16页,一块是16扇区。 而FLash的储存空间为8M,也就是810241024字节,也就是8102416*256字节 = 8M

    alt text


-- 有储存器,就会涉及到储存地址,对于FLASH芯片,储存的大小一共是6位16进制数,也就是24位,那么存储大小是2^24次方,也就是16M。

-- 那么为什么用24位的储存地址呢?

因为FLASH芯片是用来储存数据的,
最终要把数据读出来,
要想把数据读出来,要先知道地址。

-- 那么地址是怎么规定的呢? 

alt text

-- 例如:第一块第二扇区第三页第五字节怎么表示相应的地址? 

alt text

  • 注意:如何换算地址这里是重点!!!

模块之间应该怎么通信呢?-- 看时序图

-- 这里依旧是看该型号的官方文档

-- 先看指令表 

alt text

-- 首先来看写使能的时序图,主机向从机发送06h指令 

alt text

-- 然后看读数据(读数据和写数据的时序图类似) 

alt text

代码编写

更改代码的错误

-- 打开固件库 

alt text

-- 找到相应的函数后,将其加入工程之后,编译,会出现一个错误 

alt text

-- 将头文件改成 

alt text

-- 之后编译,发现出现了更多错误,23个,莫方 

alt text


  • 1、将117行和129行屏蔽,同时把127行赋初值之后编译,同样是23个错误 

    alt text

    alt text

  • 2、接下来改宏定义的问题(在.h中) 

    alt text

  • 3、打开原理图,找到对应的引脚 

    alt text

  • 4、这些问题是因为官方例程里没有IO初始化,我们需要在初始化函数里加上IO初始化,并配置好对应的模式(.c文件中)

alt text

注意这里是外设,所以是复用推挽

//IO初始化----
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure = {0};						//定义结构体变量,并且将结构体变量赋初值
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15; 						//引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽模式
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; 						//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	//浮空模式
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 						//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//推挽模式
	GPIO_Init(GPIOB, &GPIO_InitStructure);
  • 5、随后发现SPI的初始化没有开时钟,写上开启时钟的代码,并编译,发现依然是23个错误
//---------------------------------------------------------------------------------
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//开SPI2的时钟

alt text

  • 6、下面开始到.h文件中改宏定义,编译之后发现只有5个错误

alt text

加入两行代码

#define sFLASH_CS_GPIO_PORT GPIOB
#define sFLASH_CS_PIN GPIO_Pin_12

alt text

  • 7、发现错误是未定义外设的名字 

    alt text

在刚刚的宏定义前加上定义外设的代码

#define sFLASH_SPI SPI2

  • 8、同样,这里面对指令的宏定义有些也是不对的 

    alt text

将这些宏定义更改为:

#define sFLASH_CMD_WRITE          0x02  /*!< Write to Memory instruction */
#define sFLASH_CMD_WRSR           0x01  /*!< Write Status Register instruction */
#define sFLASH_CMD_WREN           0x06  /*!< Write enable instruction */
#define sFLASH_CMD_READ           0x03  /*!< Read from Memory instruction */
#define sFLASH_CMD_RDSR           0x05  /*!< Read Status Register instruction  */
#define sFLASH_CMD_RDID           0x9F  /*!< Read identification */
#define sFLASH_CMD_SE             0x20  /*!< Sector Erase instruction */
#define sFLASH_CMD_BE             0xD8  /*!< Bulk Erase instruction */

-- 将这些错误全部更改完毕后,再次编译,就没有错误了

应用函数

-- 其实这么多函数我们目前只会用到其中几个函数

-- 首先是读数据和写数据函数 

alt text

-- 然后是擦除函数,分别是扇区擦除和块擦除 

alt text

-- 那么为什么要用擦除函数呢?

首先,观察过我们之前下载程序的时候就可以看出每次都会有擦除的步骤 

alt text

 哪怕是使用J-Link下载,也要擦除,校验,编译

-- 那么什么是擦除呢?

会将flash中保存的数据先擦除,擦除之后,其存储单元的每一位都会变为1
因为向flash中下载数据的时候,只能把1变成0,不能把0变成1

-- 所以写数据之前,要先进行擦除


-- 我们这里简单看一个官方代码,写数据的代码,我们可以看出写数据函数中的核心就是这个函数 

alt text

-- 我们进入这个函数 

alt text

注:最小单位的虽然是字节,但是都是以页为单位进行写数据

-- 写使能函数,就是按照时序图来写的 

alt text


-- 在主函数中编写将数据写入FLASH的代码

//SPI***********************************************************************
	sFLASH_Init();
	
	char abuff[]="123456789qweaszc";
	
	sFLASH_EraseSector(0x009000);//写准备写进哪个扇区,就擦除该扇区(第10个扇区)
	sFLASH_WriteBuffer(abuff,0x009000,strlen(abuff));//第一个参数是abuff的地址,第二个参数是你要写入的扇区地址,第三个参数是要读的数量
	printf("写入完成\r\n");

-- 但是不知道写成功没,怎么验证呢?读出来

注意:只需要在写之前擦除,不需要在读之前擦除,还有就是今天写的函数,不能放在while循环里面一直擦除,因为flash芯片有寿命,规定了擦除的次数,如果擦除的次数超过规定的次数,将会擦除不了

-- 写入读数据

    char bbuff[100]={0};
	sFLASH_ReadBuffer(bbuff,0x009000,50);//第一个参数是要保存的地址,第三个参数是要要读的数量
	printf("bbuff:%s\r\n");

-- 从扇区中读50个数的效果图为: 

alt text

应用:将图片生成的模写入flash中

-- 由于生成的图片的模占的内存很大,所以我们使用flash来保存

-- 首先计算图片的模占的内存大小,算出要擦除的扇区个数 

alt text

alt text

--

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

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

相关文章

Vue Data UI——Vue 3 数据可视化组件库

文章目录 1、Vue Data UI2、核心特点2.1.Vue 3 的深度集成2.2 丰富的可视化组件2.3 灵活的定制性2.4 易于集成2.5 文件导出功能2.6 多主题支持3、如何在项目中使用 Vue Data UI?3.1 安装 Vue Data UI3.2 全局注册组件3.3 局部引入组件3.4 使用通用组件3.5 TypeScript 集成4、总…

城市交通系统优化策略:透视拥堵之困,探索流畅之道

在快速城市化的今天&#xff0c;交通拥堵已成为众多大中型城市的“城市病”&#xff0c;严重影响居民生活质量、经济运行效率及环境质量。本文旨在深度剖析城市交通拥堵的根源&#xff0c;并提出一系列行之有效的优化策略&#xff0c;旨在构建更加顺畅、高效、绿色的城市交通系…

R语言实现logistic回归曲线绘制

方式一&#xff1a;编制函数 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码快 f <- function(x){y 1/(1 exp(-x))plot(x,y)}#sigmoid函数 f(x)​ 方式二&#xff1a;Sigmoid函数代码 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码块 #y<-1/(1exp(-x)) y&…

【NOIP1997 普及组第一题】棋盘问题

题目背景 NOIP1997 普及组第一题 题目描述 设有一个NM 方格的棋盘 (1≤N≤100,1≤M≤100) 求出该棋盘中包含有多少个正方形、多少个长方形&#xff08;不包括正方形&#xff09;。 例如&#xff1a;当 N2,M3时&#xff1a; 正方形的个数有 8 个&#xff1a;即边长为 1 的正…

北斗短报文平板终端|军用三防平板|国产加固平板|防爆工业平板

在当今数字化浪潮的推动下&#xff0c;各行各业对智能终端设备的需求日益多样化与专业化&#xff0c;特别是在工业领域&#xff0c;一款集通信、定位、导航及耐用性于一身的设备显得尤为重要。北斗三代短报文工业平板电脑正是应此需求而生&#xff0c;它不仅是一款普通的平板电…

睿赛德科技正式推出RT-Thread开源 4+服务,助力企业用户发展

RT-Thread始于2006 年&#xff0c;是100%由中国开发者编写的开源嵌入式操作系统。经过10多年的发展&#xff0c;已经成为国内最流行的嵌入式操作系统&#xff0c;广泛应用于工业、 电力、轨道交通、智慧城市、智能家居、穿戴、车载、甚至航空航天等领域。 RT-Thread的成功基于对…

基金好书入门阅读笔记《基金作战笔记:从投基新手到配置高手的进阶之路》笔记3

公募基金的分类方式按投资范围分 80%以上资产投资于股票的&#xff0c;叫股票基金&#xff1b;80%以上资产投资于债券的&#xff0c;叫债券基金&#xff1b;80% 以上资产投资于其他基金的&#xff0c;叫FOF; 80%以上资产投资于货币市场的&#xff0c;叫货币基金&#xff1b;以上…

【AI绘画】Midjourney进阶:中心点构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;中心点构图中心点构图的特点使用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midj…

freertos的任务管理

任务函数 任务被实现为C函数。它们唯一特别的地方是它们的原型&#xff0c;它必须返回void并接受void指针参数。以下是函数原型。 void ATaskFunction( void *pvParameters );每个任务本身都是一个小程序。它有一个入口点&#xff0c;通常会在无限循环中永远运行&#xff0c;…

MWD天气图像多分类数据集,用于图像分类-共6个类别,共60000张图像数据 ,含有模型

MWD天气图像多分类数据集&#xff0c;用于图像分类- MWD天气图像多分类数据集&#xff0c;用于图像分类-共6个类别&#xff0c;共60000张图像数据 &#xff0c;含有模型 MWD天气图像多分类数据集及模型介绍 数据集概述 名称&#xff1a;MWD天气图像多分类数据集图像数量&…

大规模多传感器滑坡检测数据集,利用landsat,哨兵2,planet,无人机图像等多种传感器采集数据共2w余副图像,mask准确标注滑坡位置

大规模多传感器滑坡检测数据集&#xff0c;利用landsat&#xff0c;哨兵2&#xff0c;planet&#xff0c;无人机图像等多种传感器采集数据共2w余副图像&#xff0c;mask准确标注滑坡位置 大规模多传感器滑坡检测数据集介绍 数据集概述 名称&#xff1a;大规模多传感器滑坡检测…

AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型(LLM)应用开发平台

AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型&#xff08;LLM&#xff09;应用开发平台 目录 AGI 之 【Dify】 之 使用 Docker 在 Windows 端本地部署 Dify 大语言模型&#xff08;LLM&#xff09;应用开发平台 一、简单介绍 二、Docker 下载安…

界面控件Kendo UI for jQuery 2024 Q3亮点 - 支持切换编辑模式

随着最新的2024 Q3版本&#xff0c;Progress使用户能够使用现成的页面模板和构建块更快地构建令人惊叹的应用程序&#xff0c;使您的Telerik和Kendo UI开发体验更好。 Telerik和Kendo UI 2024 Q3版本将焦点放在新推出的页面模板和构建块上&#xff0c;每个页面模板和构建块都预…

SaaS架构:中央库存系统架构设计

大家好&#xff0c;我是汤师爷~ 近年来&#xff0c;越来越多的零售企业大力发展全渠道业务。在销售额增长上&#xff0c;通过线上的小程序、直播、平台渠道等方式&#xff0c;拓展流量变现渠道。在会员增长方面&#xff0c;通过多样的互动方式&#xff0c;全渠道触达消费者&am…

大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

TensorRT-LLM七日谈 Day4

在Day2 中&#xff0c;我们梳理了trt-llm对于TinyLLama的调用&#xff0c;在Day3,我们也熟悉了一下Trt-llm常规的三步流程。 这里其实有个问题&#xff0c;在针对tiny-llama的部署中&#xff0c;其实没有显式的进行模型转换&#xff0c;那麽其推理接口中到底包含了什么&#x…

stack - queue - priority_queue

1.stack和queue的使用 2.底层逻辑 2.1 stack和queue都是容器适配器&#xff0c;是用其他容器适配形成的 stack的逻辑是后进先出的逻辑&#xff0c;意味着会发生尾差和尾删&#xff0c;其容器就可以选择是vector和list queue的逻辑是先进先出&#xff0c;意味着会发生头删和…

Codigger Keyboard Look应用说明

Keyboard Look是一项专为Desktop设计的功能模式&#xff0c;旨在通过全面启用键盘操作&#xff0c;减少对鼠标依赖&#xff0c;从而提升用户的工作效率和操作体验。尤其对于频繁使用键盘的用户&#xff0c;如开发者&#xff0c;此模式可显著加速日常操作&#xff0c;优化工作流…

[NewStar 2024] week2

Crypto 第2周的密码依然都是签到题 这是几次方&#xff1f; 疑惑&#xff01; 给了个提示&#xff1a;hint p^e 10086 这里边不要当成乘幂&#xff0c;而且加法的优先级高于异或&#xff0c;所以phint ^ (e10086)得到p就能正常解RSA了 Since you konw something 给的c是…

HTML5实现古典音乐网站源码模板2

文章目录 1.设计来源1.1 主界面1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面1.6 联系我们界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&a…