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

STM32F429IGT6使用CubeMX配置SPI通信(W25Q256芯片)

1、硬件电路

需要系统性的看一下W25Q256芯片手册 

2、设置RCC,选择高速外部时钟HSE,时钟设置为180MHz

3、配置SPI

 

4、生成工程配置

 

5、相关代码

#define sFLASH_ID 0XEF4019 // W25Q256#define SPI_FLASH_PageSize 256
#define SPI_FLASH_PerWritePageSize 256#define W25Q256_WriteEnable 0x06    // 写使能指令
#define W25Q256_WriteDisable 0x04   // 写屏蔽指令
#define W25Q256_ReadStatusReg 0x05  // 读取状态寄存器1
#define W25Q256_WriteStatusReg 0x01 // 写入状态寄存器1
//#define W25Q256_ReadData 0x03       // 3字节模式读取数据指令
#define W25Q256_ReadData 0x13       // 4字节模式读取数据指令
#define W25Q256_FastReadData 0x0B   //
#define W25Q256_FastReadDual 0x3B
#define W25Q256_PageProgram 0x02 // 页写入指令
#define W25Q256_BlockErase 0xD8
#define W25Q256_SectorErase 0x20
#define W25Q256_ChipErase 0xC7
#define W25Q256_PowerDown 0xB9
#define W25Q256_ReleasePowerDown 0xAB
#define W25Q256_DeviceID 0xAB
#define W25Q256_ManufactDeviceID 0x90
#define W25Q256_JedecDeviceID 0x9F
#define W25Q256_Enter4ByteMode 0xB7 // 4字节地址模式指令
#define W25Q256_ReadStatusRegister3 0x15
#define W25Q256_WriteStatusRegister3 0x11   //写状态寄存器3指令
#define WIP_Flag 0x01
#define Dummy_Byte 0xFF#define FLASH_WriteAddress 0x00000
#define FLASH_ReadAddress FLASH_WriteAddress
#define FLASH_SectorToErase FLASH_WriteAddress/* 获取缓冲区的长度 */
#define TxBufferSize1 (countof(TxBuffer1) - 1)
#define RxBufferSize1 (countof(TxBuffer1) - 1)
#define countof(a) (sizeof(a) / sizeof(*(a)))
#define BufferSize (countof(Tx_Buffer) - 1)#define FLASH_WriteAddress 0x00000
#define FLASH_ReadAddress FLASH_WriteAddress
#define FLASH_SectorToErase FLASH_WriteAddress/* 发送缓冲区初始化 */
extern uint8_t ReadBuff[4096];
extern uint8_t WriteBuff[4096];

/*** @brief   拉低片选线* @param   无* @retval  无*/
void SPI_FLASH_NSS_LOW(void)
{HAL_GPIO_WritePin(SPI5_NSS_GPIO_Port, SPI5_NSS_Pin, GPIO_PIN_RESET);
}/*** @brief   拉高片选线* @param   无* @retval  无*/
void SPI_FLASH_NSS_HIGH(void)
{HAL_GPIO_WritePin(SPI5_NSS_GPIO_Port, SPI5_NSS_Pin, GPIO_PIN_SET);
}/*** @brief   获取 FLASH ID* @param   无* @retval  FLASH ID*/
uint32_t SPI_FLASH_ReadID(void)
{uint32_t temp = 0;uint32_t temp0 = 0;uint32_t temp1 = 0;uint32_t temp2 = 0;// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送获取W25Q256芯片ID指令SPI_FLASH_SendByte(W25Q256_JedecDeviceID);// 接收数据temp0 = SPI_FLASH_ReadByte();temp1 = SPI_FLASH_ReadByte();temp2 = SPI_FLASH_ReadByte();// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();temp = temp0 << 16 | temp1 << 8 | temp2;return temp;
}/*** @brief   发送一个字节* @param   无* @retval  无*/
void SPI_FLASH_SendByte(uint8_t ch)
{HAL_SPI_Transmit(&hspi5, &ch, 1, 500);
}/*** @brief   发送n个字节* @param   pData:发送数据首地址* @param   data_number:发送数据个数(以字节为单位)* @retval  无*/
void SPI_FLASH_SendnByte(uint8_t *pData, uint32_t data_number)
{HAL_SPI_Transmit(&hspi5, pData, data_number, 500);
}/*** @brief   接收一个字节* @param   无* @retval  接收的数据*/
uint8_t SPI_FLASH_ReadByte(void)
{uint8_t rxData = 0;HAL_SPI_Receive(&hspi5, &rxData, 1, 500);return rxData;
}/*** @brief   接收n个字节* @param   pData:接收数据首地址* @param   data_number:接收数据个数(以字节为单位)* @retval  无*/
void SPI_FLASH_ReadnByte(uint8_t *pData, uint32_t data_number)
{HAL_SPI_Receive(&hspi5, pData, data_number, 500);
}/*** @brief   使能写命令* @param   无* @param   无* @retval  无*/
void SPI_FLASH_WriteEnable(void)
{// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送写使能指令SPI_FLASH_SendByte(W25Q256_WriteEnable);// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();
}/*** @brief   等待写入、擦除等操作完成* @param   无* @param   无* @retval  无*/
void SPI_FLASH_WaitForWriteEnd(void)
{uint8_t FLASH_Status = 0;// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送写状态寄存器1指令SPI_FLASH_SendByte(W25Q256_ReadStatusReg);do{// 获取写状态寄存器1的值并做判断。0:空闲、1:忙碌FLASH_Status = SPI_FLASH_ReadByte();} while (SET == (FLASH_Status & WIP_Flag));// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();
}/*** @brief   擦除扇区* @param   SectorAddr:擦除扇区首地址* @retval  无*/
void SPI_FLASH_SectorErase(uint32_t SectorAddr)
{// uint8_t ADDR[4] = {0x00,0x00,0x00,0x00};//  使能写命令SPI_FLASH_WriteEnable();// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送擦除扇区命令SPI_FLASH_SendByte(W25Q256_SectorErase);// 发送擦除地址24 ~ 31bitSPI_FLASH_SendByte((SectorAddr & 0xFF000000) >> 24);// 发送擦除地址16 ~ 23bitSPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);// 发送擦除地址8 ~ 15bitSPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);// 发送擦除地址0 ~ 7bitSPI_FLASH_SendByte(SectorAddr & 0xFF);// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();// HAL_Delay(3000);// 等待擦除操作结束SPI_FLASH_WaitForOperaEnd();
}/*** @brief   配置4字节模式* @param   无* @retval  无*/
void SPI_FLASH_FOUR_MODE(void)
{uint8_t temp = 0;// 使能写命令SPI_FLASH_WriteEnable();// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送写状态寄存器3命令SPI_FLASH_SendByte(W25Q256_WriteStatusRegister3);// 发送要写的数据SPI_FLASH_SendByte(0x02);// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送读状态寄存器3命令SPI_FLASH_SendByte(W25Q256_ReadStatusRegister3);// 读取数据temp = SPI_FLASH_ReadByte();// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();if (1 == (0x02 & temp)){// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送配置四字节模式指令SPI_FLASH_SendByte(W25Q256_Enter4ByteMode);// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();}SPI_FLASH_WaitForOperaEnd();
}/*** @brief   对 FLASH 按页写入数据,调用本函数写入数据前需要先擦除扇区* @param   pBuffer:要写入数据的指针* @param   WriteAddr:写入数据地址* @param   NumByteToWrite:写入数据长度。必须小于等于SPI_FLASH_PerWritePageSize* @retval  无*/
void SPI_FLASH_PageWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{// 使能写命令SPI_FLASH_WriteEnable();// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送页写入指令SPI_FLASH_SendByte(W25Q256_PageProgram);// 发送写入地址[24,31]bitSPI_FLASH_SendByte((WriteAddr & 0xFF000000) >> 24);// 发送写入地址[16,23]bitSPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);// 发送写入地址[8,15]bitSPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);// 发送写入地址[0,7]bitSPI_FLASH_SendByte(WriteAddr & 0xFF);if (NumByteToWrite > SPI_FLASH_PerWritePageSize){NumByteToWrite = SPI_FLASH_PerWritePageSize;printf("256\r\n");}for (int i = 0; i < NumByteToWrite; i++){SPI_FLASH_SendByte(pBuffer[i]);}// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();
}/*** @brief   FALSH不定量数据写入函数,调用本函数写入数据前需要先擦除扇区* @param   pBuffer:要写入数据的指针* @param   WriteAddr:写入数据地址* @param   NumByteToWrite:写入数据长度* @retval  无*/
void SPI_FLASH_BufferWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{uint8_t NumOfPage = 0;uint8_t NumOfSingle = 0;uint8_t Addr = 0;uint8_t count = 0;uint8_t temp = 0;/*mod 运算求余,若 writeAddr 是 SPI_FLASH_PageSize 整数倍,运算结果 Addr 值为0*/Addr = WriteAddr % SPI_FLASH_PageSize;/* 差 count 个数据值,刚好可以对齐到页地址 */count = SPI_FLASH_PageSize - Addr;/* 计算出要写多少整数页 */NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;/*mod 运算求余,计算出剩余不满一页的字节数 */NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;/* Addr=0, 则 WriteAddr 刚好按页对齐 aligned */if (0 == Addr){/*NumByteToWrite < SPI_FLASH_PageSize*/if (0 == NumOfPage){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}else{/* 先把整数页都写了 */for (int i = 0; i < NumOfPage; i++){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr += SPI_FLASH_PageSize;pBuffer += SPI_FLASH_PageSize;}/* 若有多余的不满一页的数据,把它写完 */SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}else /* 若地址与 SPI_FLASH_PageSize 不对齐 */{/*NumByteToWrite < SPI_FLASH_PageSize*/if (0 == NumOfPage){/* 当前页剩余的 count 个位置比 NumOfSingle 小,写不完 */if (NumOfSingle > count){temp = NumOfSingle - count;/* 先写满当前页 */SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr += count;pBuffer += count;/* 再写剩余的数据 */SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}else /* 当前页剩余的 count 个位置能写完 NumOfSingle 个数据 */{SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}else /*NumByteToWrite > SPI_FLASH_PageSize*/{/*先把距离页地址的count个数据减去,计算需要写的页数和NumOfSingle,然后写数据时先把原来减去的count个数据写入,写满当前页*//*再写剩余数据,即计算好的NumOfPage和NumOfSingle*/NumByteToWrite -= count;NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr += count;pBuffer += count;/* 把整数页都写了 */for (int i = 0; i < NumOfPage; i++){SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr += SPI_FLASH_PageSize;pBuffer += SPI_FLASH_PageSize;}if (0 != NumOfSingle){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}}
}/*** @brief   读取FLASH数据* @param   pBuffer:存储读出数据的指针* @param   WriteAddr:读取地址* @param   NumByteToRead:读取数据长度* @retval  无*/
void SPI_FLASH_BufferRead(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送读取数据指令SPI_FLASH_SendByte(W25Q256_ReadData);// 发送读取地址[24,31]bitSPI_FLASH_SendByte((ReadAddr & 0xFF000000) >> 24);// 发送读取地址[16,23]bitSPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);// 发送读取地址[8,15]bitSPI_FLASH_SendByte((ReadAddr & 0xFF00) >> 8);// 发送读取地址[0,7]bitSPI_FLASH_SendByte(ReadAddr & 0xFF);// 读取数据for (int i = 0; i < NumByteToRead; i++){// 读取一个字节数据pBuffer[i] = SPI_FLASH_ReadByte();}// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();SPI_FLASH_WaitForOperaEnd(); // 等待操作完成
}/*** @brief   等待写入、擦除等操作结束* @param   none* @param   none* @param   none* @retval  none*/
void SPI_FLASH_WaitForOperaEnd(void)
{uint8_t FLASH_Status = 0;// 拉低片选线,开始通信SPI_FLASH_NSS_LOW();// 发送读状态寄存器1指令SPI_FLASH_SendByte(W25Q256_ReadStatusReg);do{// 接收读取状态寄存器1寄存器内容FLASH_Status = SPI_FLASH_ReadByte();} while (SET == (FLASH_Status & WIP_Flag));// 拉高片选线,结束通信SPI_FLASH_NSS_HIGH();
}
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_SPI5_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */// 进入4字节地址模式SPI_FLASH_FOUR_MODE();printf("W25Q256 SPI readwrite test!!!\r\n");device_ID = SPI_FLASH_ReadID();printf("device_ID = 0x%x\r\n", device_ID);SPI_FLASH_SectorErase(0x00); // 擦除扇区数据// 读取擦除后的数据SPI_FLASH_BufferRead(ReadBuff, 0x00, 4096);printf("*****************读取擦出后的数据*****************\r\n");for (int i = 0; i < 4096; i++){printf("ReadBuff[%d] = 0x%02x\t", i, ReadBuff[i]);if (0 == (i + 1) % 8 && (i + 1) >= 8){printf("\r\n");}}for (int i = 0; i < 256; i++){WriteBuff[i] = i;}SPI_FLASH_BufferWrite(WriteBuff, 0xFF, 256);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成// 读数据SPI_FLASH_BufferRead(ReadBuff, 0xFF, 256);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成printf("*****************读取写入后的数据*****************\r\n");for (int i = 0; i < 256; i++){printf("ReadBuff[%d] = 0x%02x\t", i, ReadBuff[i]);if (0 == (i + 1) % 8 && (i + 1) >= 8){printf("\r\n");}}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */LED_TIME();}/* USER CODE END 3 */
}

6、实验现象

 

相关文章:

STM32F429IGT6使用CubeMX配置SPI通信(W25Q256芯片)

1、硬件电路 需要系统性的看一下W25Q256芯片手册 2、设置RCC&#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置SPI 4、生成工程配置 5、相关代码 #define sFLASH_ID 0XEF4019 // W25Q256#define SPI_FLASH_PageSize 256 #define SPI_FLASH_PerWritePageSize 256#def…...

C++11异步与通信之 packaged_task

概念简介 packaged_task 用于包装可调用目标(Callable)为一个对象,如lambda&#xff0c;普通函数&#xff0c;小括号重载等&#xff0c;用于异步调用。 其返回值或所抛异常被存储于能通过 std::future 对象访问的共享状态中&#xff0c;和promise类似。 将函数的调用与函数返…...

磁盘的管理

一、磁盘的分区 查看磁盘 lsblk fdisk -l 2、分区 没有e扩展&#xff0c;则都是主分区&#xff0c;已经有三个主分区了&#xff0c;剩下的全设置为扩展 查看分区结果&#xff1a; 二、格式化 三、挂载...

数据结构:完全二叉树的性质

完全二叉树的性质&#xff1a; 具有 n n n个结点的完全二叉树的深度为 [ l o g 2 n ] 1 ( [ x ] 表示不大于 x 的最大整数 ) [log_2n]1([x]表示不大于x的最大整数) [log2​n]1([x]表示不大于x的最大整数) 对于任意一个结点 &#xff08; 1 < i < n &#xff09; &…...

【数据结构】‘双向链表’冲冲冲

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

Linux 编译CEF源码详细记录

Linux CEF&#xff08;Chromium Embedded Framework&#xff09;源码下载编译 背景 由于CEF默认的二进制分发包不支持音视频播放&#xff0c;需要自行编译源码&#xff0c;将ffmpeg开关打开才能支持。这里介绍的是Linux平台下的CEF源码下载编译过程。 Windows平台参考&#…...

LeetCode 2810. Faulty Keyboard【模拟,双端队列,字符串】简单

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

两个数组的交集-C语言/Java

描述 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序。&#xff08;1 < nums1.length, nums2.length < 1000&#xff0c;0 < nums1[i], nums2[i] < 1000&#xff09; 示例1 输入…...

Arduino+esp32学习笔记

学习目标&#xff1a; 使用Arduino配置好蓝牙或者wifi模块 学习使用python配置好蓝牙或者wifi模块 学习内容&#xff08;笔记&#xff09;&#xff1a; 一、 Arduino语法基础 Arduino语法是基于C的语法,C又是c基础上增加了面向对象思想等进阶语言。那就只记录没见过的。 单多…...

计算机网络-专业术语

计算机网络-专业术语 实体 实体:任何可发送或接收信息的硬件或软件进程 对等实体:收发双方相同层次中的实体 协议 控制两个对等实体进行逻辑通信的规则的集合 协议三要素 语法 定义所交换的信息的格式 是用户数据与控制信息的结构和格式 语义 定义收发双方所需要完成的操作…...

E. Maximum Monogonosity

You are given an array aa of length nn and an array bb of length nn. The cost of a segment [l,r][l,r], 1≤l≤r≤n1≤l≤r≤n, is defined as |bl−ar||br−al||bl−ar||br−al|. Recall that two segments [l1,r1][l1,r1], 1≤l1≤r1≤n1≤l1≤r1≤n, and [l2,r2][l2,…...

已解决Excel file format cannot be determined, you must specify an engine manually

问题 我使用以下语句时出现错误 data pd.read_excel(temp_inputc.csv, headerNone)出现错误&#xff1a; Excel file format cannot be determined, you must specify an engine manually有很多人说添加engine&#xff0c;但接下来会出现这个错误&#xff1a; File is not…...

Centos yum命令大全

1.使用YUM查找软件包 $ yum search python 2.列出所有可安装的软件包 $ yum list | grep python 3.列出所有可更新的软件包 $ yum list updates 4.列出所有已安装的软件包 $ yum list installed | grep python...

内网横向移动—ARP攻击图片捕捉数据劫持DNS劫持

内网横向移动—ARP攻击&图片捕捉&数据劫持&DNS劫持 1. ARP1.1. APR介绍1.1.1. ARP工作原理1.1.2. APR欺骗工作原理 1.2. 环境准备1.3. 适用场景 2. ARP断网攻击演示2.1. 使用kali进行演示2.1.1. nmap判断存活2.1.2. 安装工具2.1.3. 攻击Windows 10虚拟机2.1.3.1. 查…...

react之Hooks的介绍、useState与useEffect副作用的使用

react之Hooks的介绍、useState与useEffect副作用的使用 一、Hooks的基本介绍二、useState的使用2.1 简单使用2.2 数组结构简化2.3 状态的读取和修改2.3 组件的更新过程 三、useEffect的使用3.1 副作用介绍3.2 基本使用3.3 依赖3.4 不要对依赖项撒谎3.5 依赖项可以是空数组3.6 清…...

django——创建 Django 项目和 APP

2.创建 Django 项目和 APP 命令&#xff1a; 创建Django项目 django-admin startproject name 创建子应用 python manager.py startapp name 2.1 创建工程 在使用Flask框架时&#xff0c;项目工程目录的组织与创建是需要我们自己手动创建完成的。 在django中&#xff0c;…...

== 和 equals 的对比 [面试题]

和 equals 的对比[面试题] 文章目录 和 equals 的对比[面试题]1. 和 equals 简介2. Object 类中 equals() 源码3. String 类中 equals() 源码4. Integer 类中 equals() 源码5. 如何重写 equals 方法 1. 和 equals 简介 是一个比较运算符 &#xff1a;既可以判断基本数据类型…...

SpringBoot集成Redis及Redis使用方法

目录 应用背景 Redis简介 更新问题 一&#xff1a;环境配置 1.1: 在pom.xml文件中添加依赖 1.2&#xff1a;配置SpringBoot核心配置文件application.properties 二&#xff1a;在Config文件夹中创建RedisConfig配置文件类 2.1&#xff1a;RedisTemplate中的几个角色&am…...

Redis可以用作数据库吗?它的适用场景是什么?

是的&#xff0c;Redis可以用作数据库。虽然Redis通常被认为是一个内存数据库&#xff08;in-memory database&#xff09;&#xff0c;但它也可以通过持久化机制将数据保存在磁盘上&#xff0c;以便在重启后恢复数据。 Redis的适用场景包括但不限于以下几个方面&#xff1a; …...

@Param详解

文章目录 背景什么是ParamParam的使用方法使用方法&#xff1a;遇到的问题及因Param解决了什么问题使用与不使用对比 Param是如何进行映射的总结 背景 最近在开发过程中&#xff0c;在写mapper接口是在参数前加了Param注解&#xff0c;但是在运行的时候就会报错&#xff0c;说…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...