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

电子商务网站运营与管理美国搜索引擎排名

电子商务网站运营与管理,美国搜索引擎排名,自建网站免费教程,网站建设怎样接业务目录 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://www.dtcms.com/wzjs/250938.html

相关文章:

  • 做门户网站广告成都关键词排名推广
  • crm系统网址长春seo网站排名
  • 武汉免费建站模板谷歌seo优化排名
  • iis5.1怎么发布网站收录优美图片崩了
  • 石龙网站开发网络营销策划的基本原则
  • 长泰建设局网站接app推广
  • 设置网站建设百度网盘下载
  • 视差网站网上广告怎么推广
  • 2015做啥网站能致富网络推广是做什么工作的
  • 哪些网站可以做外链杭州网站优化培训
  • 宁德蕉城住房和城乡建设部网站传播易广告投放平台
  • 最专业 汽车网站建设百度导航下载2022最新版官网
  • 网页制作工具 知乎网站seo入门基础教程
  • 免费自助设计网站网络营销ppt模板
  • 中国门户网站企业网站建设论文
  • 建设银行广州分行网站外贸推广营销公司
  • 免费网站转app网站互联网推广
  • 办网站需要备案吗百度seo培训班
  • 认证网站源码成人就业技术培训机构
  • 网站建设税点百度商业平台
  • 网站建设费摊销几年微商营销
  • 做网站如何挣钱网站关键词优化的步骤和过程
  • 长沙学校网站建设网络营销策划案怎么写
  • 镇江网站公司萝卜建站
  • 怎么查网站做404页面没yahoo搜索引擎
  • 建旅游网站多少钱抖音关键词排名查询
  • 开一个网站_只做同城交易新站整站快速排名
  • 贵阳快速建站模板怎么制作自己的网站网页
  • 如何制作漂亮的微信公众号文章seo排名快速
  • 南通建设招聘信息网站域名年龄对seo的影响