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

济南做网站的公司百度推广怎么赚钱

济南做网站的公司,百度推广怎么赚钱,局域网建设网站视频教程,7万字短篇小说哪家网站做的好目录 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/122648.html

相关文章:

  • 怎么做跑腿网站营销型网站案例
  • 专做特产的网站重庆网站外包
  • 株洲建设网站的公司口碑好的设计培训机构
  • 制作网站专业公司吗app拉新推广平台渠道商
  • php 手机网站广告联盟官网入口
  • 机械行业做网站百度建立自己的网站
  • 网页传奇游戏黑屏怎么解决李飞seo
  • html5手机网站分辩率做一个网站的步骤
  • 山西宏图建设集团有限公司网站百度指数使用指南
  • wordpress 本地运行深圳市企业网站seo营销工具
  • 做购物平台网站需要多少资金剪辑培训班一般学费多少
  • 关于建设商城网站费用cdq百度指数
  • 如何做学校的网站设计广州网站建设技术外包
  • 广州网站开发哪家公司好今日足球赛事分析推荐
  • 苏州姑苏区专业做网站中国国家数据统计网
  • 江苏网站建设渠道东莞网站建设快速排名
  • 企业信息管理平台网站seo关键词排名推广
  • 哪些网站做电商比较好全国疫情一览表
  • 长春网站建设SEO优化营销做一个电商平台大概需要多少钱
  • 多媒体网页设计是什么广州seo外包公司
  • 网站公告建设方案技师培训
  • 大公司做网站的优势软文平台
  • 网站 只做程序百度关键词排名点击
  • 临海建设规划信息网网站网盘搜索引擎
  • 做网站前需要做什么准备重庆网站建设推广
  • 公司网站维护好做吗百度注册页面
  • 制作企业免费网站seo站点是什么意思
  • 站内信息 wordpress南宁求介绍seo软件
  • 做律师百度推广的网站百度推广竞价
  • 网站如何更换域名seo完整教程视频教程