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

烟台专业网站制作公司wordpress单页主题

烟台专业网站制作公司,wordpress单页主题,潍坊seo建站,网站开发架构图目录 1.SPI通信 1.1SPI总线概括 1.2字节交换原理 1.3时序单元 1.4SPI模式 2.Flash(W25Q32) 2.1基本概括 2.2硬件电路及与SPI对应连接引脚 2.3使用注意事项 2.4常用指令代码和功能描述 3.HAL库实现SPI读写W25Q32 Flash存储器 3.1初始化 3.2擦除 3.3写入(…

目录

1.SPI通信

1.1SPI总线概括

 1.2字节交换原理

 1.3时序单元

 1.4SPI模式

2.Flash(W25Q32) 

2.1基本概括

2.2硬件电路及与SPI对应连接引脚

2.3使用注意事项

2.4常用指令代码和功能描述

3.HAL库实现SPI读写W25Q32 Flash存储器

3.1初始化

3.2擦除

3.3写入(页编程)

3.4读取

3.5部分代码实现

3.5.1 W25Q32.h

3.5.2 W25Q32.c

3.5.3 main.c

1.SPI通信

1.1SPI总线概括

SPI是全双工三线/四线同步串行外围接口,采用主从模式。

时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后;SPI接口有2根单向数据线,为全双工通信。

SPI总线被广泛地使用在FLASH、ADC、LCD等设备与MCU间,要求通讯速率较高的场合。

所有的输出口在输出的时候要配置成推挽输出,这样在没有外部上拉电阻的情况的也可以有较强的输出高低电平的能力。但需要考虑一点:当主机跟从机3进行通信的时候,从机2和从机1的MISO线如果是推挽输出(推挽必输出高电平或低电平的一种)那肯定会影响主机跟从机三的正常通信,所以为了消去这一影响,让从机SS片选线为高电平,即非选中状态时对应从机输出口置为高阻态,这样既不是高电平也不是低电平不会影响主机跟所选中从机的正常通信。

 1.2字节交换原理

字节交换是基于位交换的

移出:就是把当前移位寄存器的最高位写到信号线上,然后整体往左移动一位

移入:读取信号线的状态,然后把读到的状态放到寄存器的最低位

移入和移出都是主机和从机同时进行的

移入和移出的时机是由时钟线控制约定的,约定好第几个边沿一起移出,第几个边沿一起移入。

 1.3时序单元

起始条件:SS从高电平切换到低电平

终止条件:SS从低电平切换到高电平

CPOL:时钟极性

CPHA:时钟相位

 1.4SPI模式

由CPOL及CPHA的不同状态,SPI分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,因此通常主机要按照从机支持的模式去设置.

模式0:CPOL:0 CPHA:0 空闲时钟为低电平,奇数边沿采样

模式1:CPOL:0 CPHA:1 空闲时钟为低电平,偶数边沿采样

模式2:CPOL:1 CPHA:0 空闲时钟为高电平,基数边沿采样

模式3:CPOL:1 CPHA:1 空闲时钟为高电平,偶数边沿采样

2.Flash(W25Q32) 

2.1基本概括

这里板载Flash是W25Q32型号,32代表的是32M比特的容量,相当于4MB的存储空间。

FLASH将4MB的存储空间划分为64个块,每个块的大小为64KB。每个块进一步细分为16个扇区(Sector),每个扇区的大小为4KB。

具体的大家可以查看下面的链接,详细查看W25Q32的介绍

4M Flash W25Q32的详细介绍-电子发烧友网本文以常见的4M Flash W25Q32为例。https://www.elecfans.com/d/2021087.html

2.2硬件电路及与SPI对应连接引脚

2.3使用注意事项

写操作时:

写数据之前,必须先进行擦除操作,擦除后,所有数据位将变为1。擦除操作必须按照最小擦除单元来进行。

在写入数据之前,要先进行写使能操作。

每个数据位只能从1改写为0,而不能从0改写为1。

在连续写入多字节数据时,最多只能写入一页的数据。

写操作完成后,芯片会进入忙状态。

读操作时:

读操作时,可以直接调用读取时序,无需进行使能,读操作完成后,芯片不会进入忙状态。芯片处于忙状态时,不能进行读操作。

2.4常用指令代码和功能描述

 

3.HAL库实现SPI读写W25Q32 Flash存储器

3.1初始化

使用CubeMX分别配置SPI模式,时钟速率和SPI引脚选择

初始化GPIO引脚

配置CS引脚为输出,初始状态为高电平。

配置SCK、MOSI为输出,MISO为输入。

3.2擦除

发送写使能:0x06

发送擦除命令:0x20 + 24位地址(3字节,高位在前)。

等待擦除完成:轮询状态寄存器直至BUSY位为0。

3.3写入(页编程)

页大小:256字节

写使能:发送0x06​​​​​​​

发送页编程命令:0x02 + 24位地址 + 数据。​​​​​​​

等待写入完成:轮询状态寄存器。

3.4读取

发送读命令:0x03 + 24位地址。​​​​​​​

连续读取数据:地址自动递增,可跨页连续读。

3.5部分代码实现

3.5.1 W25Q32.h

#ifndef __W25Q32__H__
#define __W25Q32__H__#include "main.h" #define READ_REGISTER_1       0x05  //读取状态寄存器1
#define READ_REGISTER_2       0x35  //读取状态寄存器2
#define READ_DATA_CMD	    		0x03  //读取数据命令
#define WRITE_ENABLE_CMD			0x06  //写使能命令
#define SECTOR_ERASE_CMD			0x20  //扇区擦除命令
#define PAGE_PROGRAM_CMD  		0x02  //页编程命令static uint8_t W25Q32_ReadSR(uint8_t reg);	//读取W25Q32状态寄存器
int W25Q32_Read(uint8_t* buffer, uint32_t start_addr, uint16_t nbytes);		//从W25Q32读取数据
void W25Q32_EraseSector(uint32_t sector_addr);	//擦除W25Q32一个扇区
void W25Q32_WriteEnable(void);	//发送写使能命令
void W25Q32_PageProgram(uint8_t* dat, uint32_t WriteAddr, uint16_t nbytes);		//向W25Q32写入数据 #endif

3.5.2 W25Q32.c

#include "main.h"
#include "W25Q32.h"extern SPI_HandleTypeDef hspi1;/*** @brief 读取W25Q32状态寄存器* @param reg 状态寄存器编号 (1 或 2)* @return 状态寄存器的值*/
uint8_t W25Q32_ReadSR(uint8_t reg)
{uint8_t cmd = (reg == 2) ? READ_REGISTER_2 : READ_REGISTER_1; //根据reg选择读取状态寄存器1或2uint8_t sr = 0; 	//存储读取到的状态寄存器值HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); 	//拉低片选 (CS)HAL_SPI_Transmit(&hspi1, &cmd, 1, 1000);   //发送读取状态寄存器命令HAL_SPI_Receive(&hspi1, &sr, 1, 1000);     //接收状态寄存器值HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);   //拉高片选 (CS)return sr; 
}/*** @brief 等待W25Q32的BUSY位清零*/
void W25Q32_WaitBusy(void) 
{while (W25Q32_ReadSR(1) & 0x01); // 循环读取状态寄存器1, 直到BUSY位为0
}/*** @brief 从W25Q32读取数据* @param buffer 数据接收缓冲区* @param addr 读取起始地址* @param len 要读取的字节数* @return 0:成功,其他值:失败*/
int W25Q32_Read(uint8_t* buffer, uint32_t addr, uint16_t len) 
{uint8_t cmd[4] = {READ_DATA_CMD,       //读取数据命令(uint8_t)(addr >> 16), //地址高8位(uint8_t)(addr >> 8),  //地址中8位(uint8_t)addr          //地址低8位};W25Q32_WaitBusy(); // 等待Flash就绪HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); //拉低片选 (CS)HAL_SPI_Transmit(&hspi1, cmd, 4, 1000);        //发送读取命令和地址HAL_SPI_Receive(&hspi1, buffer, len, 1000);    //接收数据HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);   //拉高片选 (CS)return 0;
}/*** @brief 擦除W25Q32的一个扇区* @param sector 要擦除的扇区地址*/
void W25Q32_EraseSector(uint32_t sector) 
{uint8_t cmd[4] = {SECTOR_ERASE_CMD,      //扇区擦除命令(uint8_t)(sector >> 16), 	//地址高8位(uint8_t)(sector >> 8),  	//地址中8位(uint8_t)sector         	//地址低8位};W25Q32_WriteEnable(); 	//发送写使能命令W25Q32_WaitBusy();    //等待Flash就绪HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); 	//拉低片选 (CS)HAL_SPI_Transmit(&hspi1, cmd, 4, 1000);            	//发送擦除命令和地址HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);   	//拉高片选 (CS)W25Q32_WaitBusy(); //等待擦除完成
}/*** @brief 发送写使能命令* @note  必须在每次写入或擦除操作之前调用*/
void W25Q32_WriteEnable(void)
{uint8_t cmd = WRITE_ENABLE_CMD; 	//写使能命令HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); 	//拉低片选 (CS)HAL_SPI_Transmit(&hspi1, &cmd, 1, 1000);          //发送写使能命令HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);   //拉高片选 (CS)
}/*** @brief 向W25Q32写入数据* @param data 要写入的数据* @param addr 写入起始地址* @param len 要写入的字节数*/
void W25Q32_PageProgram(uint8_t* data, uint32_t addr, uint16_t len)
{uint8_t cmd[4] = {PAGE_PROGRAM_CMD,    //页编程命令(uint8_t)(addr >> 16), //地址高8位(uint8_t)(addr >> 8),  //地址中8位(uint8_t)addr          //地址低8位};W25Q32_WriteEnable(); 	//发送写使能命令W25Q32_WaitBusy();    	//等待Flash就绪HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); //拉低片选 (CS)HAL_SPI_Transmit(&hspi1, cmd, 4, 1000);            //发送页编程命令和地址HAL_SPI_Transmit(&hspi1, data, len, 1000);          //发送数据HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);   //拉高片选 (CS)W25Q32_WaitBusy(); // 等待写入完成
}

3.5.3 main.c

/*** @brief  外部中断回调函数,处理GPIO_PIN_0和GPIO_PIN_15的中断事件* @param  GPIO_Pin 触发中断的GPIO引脚号* @note   当GPIO_PIN_0中断触发时,擦除指定扇区并写入数据;*         当GPIO_PIN_15中断触发时,读取Flash数据并输出*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (GPIO_Pin == GPIO_PIN_0)		//GPIO_PIN_0 中断处理,写入Flash{W25Q32_EraseSector(FLASH_SIZE - 100);		//擦除目标扇区W25Q32_PageProgram((uint8_t *)TEXT_Buffer, FLASH_SIZE - 100, SIZE);		//将数据写入Flashprintf("写入FLASH成功\r\n");	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);}if (GPIO_Pin == GPIO_PIN_15)		//GPIO_PIN_15 中断处理,读取Flash{W25Q32_Read((uint8_t *)datatemp, FLASH_SIZE - 100, SIZE);		//从Flash读取数据printf("获取的FLASH里的消息为:%s\r\n", datatemp);HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);}
}

文章转载自:

http://5zd5oVjX.phLrp.cn
http://XzIsDiG4.phLrp.cn
http://BSNS0WuN.phLrp.cn
http://7hVX3ZSX.phLrp.cn
http://fdxHD9rA.phLrp.cn
http://WvqJIpJl.phLrp.cn
http://S2evs4q7.phLrp.cn
http://4e3FPhZz.phLrp.cn
http://i2uNl2Oc.phLrp.cn
http://j9WZjRMu.phLrp.cn
http://OqZLeC9B.phLrp.cn
http://nVmaCqBR.phLrp.cn
http://J2jruWRh.phLrp.cn
http://OR3c1IXi.phLrp.cn
http://xbXWCtZR.phLrp.cn
http://e3rKxMsB.phLrp.cn
http://vlVyRJye.phLrp.cn
http://HeAYVYuk.phLrp.cn
http://zd54hMtU.phLrp.cn
http://8QfWx1kW.phLrp.cn
http://KG6OuHN4.phLrp.cn
http://CBDaREd8.phLrp.cn
http://YNBr9EE1.phLrp.cn
http://7T2RsXyG.phLrp.cn
http://o9u3hFw7.phLrp.cn
http://Ruzw4ukB.phLrp.cn
http://vodiqXv2.phLrp.cn
http://h24UkBC3.phLrp.cn
http://Zv4x31w4.phLrp.cn
http://Pye18cBu.phLrp.cn
http://www.dtcms.com/wzjs/621464.html

相关文章:

  • 宿迁高端网站建设什么app推广佣金多
  • 长沙教育建设信息网站便宜点的WordPress
  • 做蛋糕哪个教程网站好网站自动更新时间代码
  • 大庆建设银行网站大型网站建设兴田德润专业
  • 安顺网站设计长沙专门做网站建设的公司
  • 10个网站用户体验优化的研究结果网站的运营费用吗
  • 泰国网站域名wordpress 登录后 地址
  • 网站app免费生成软件手机网络优化软件
  • 怎样写网站文案网站制作收费标准
  • 青海专业网站建设推广平台建设优秀网站的必备要素
  • 网站群 seo谷德设计网入口
  • 佛山专业网站开发公司网站链接跳转如何做
  • 贵州建设职业技术学院报名网站wordpress js 被改
  • vs做网站怎么做窗体备案网站名称注意事项
  • 西安网站建设首选那家成品源码1277
  • 关于学院网站建设的意见陕西省建设厅网站首页
  • 好的宝安网站建设论文课程网站 建设背景
  • 污染网站代码网站中的图片展示功能该设计什么
  • 响应式网站无法做百度联盟哈尔滨做网站设计
  • 长春网站设计长春市土建公司
  • 挂马网站现象仙桃哪里做网站
  • 社交网站开发流程正能量网站
  • 商务网站页面设计技术重庆市建设工程招投标交易信息网
  • 山东平台网站建设平台便捷的网站建设软件
  • 久久建筑网是个什么样的网站网站和管理系统的区别
  • 做网站销售东西 需要什么资质欧美网站特点
  • 黄岩建设局台州网站建设室内设计要学哪些科目
  • 网站服务器 免费台州网络优化
  • 如何让做的网站自动适应浏览器云南住房建设厅网站
  • wordpress仿站pdf城乡建设网站职业查询系统