STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
- 参考例程
- 例程说明
- 一、存储到Flash中的数据
- 二、Flash最底层操作(解锁,加锁,擦除,读写)
- 三、从Flash块中读取数据
- 五、测试验证
参考例程
STM32G0xx HAL和LL库Flash读写擦除操作
STM32G030Cx HAL库Flash擦除或编程操作出错的解决办法
例程说明
1.Flash存储数据采用页分块方式,实现一次擦除多次写入,每块128Byte总共16块,当存满16块后擦除一次
2.将数据写入Flash前,需要前后对比数据,只有数据发生变化才能写入Flash中
3.从Flash读取数据后,进行CRC校验,校验不通过往前继续读取数据,然后重新校验数据
4.将数据写如Flash前需要确保改块都是0xFF,保证写入数据成功
一、存储到Flash中的数据
说明:
- Header用来标识存储的头部信息,在Flash读取或写入时用到
- ubRes用来作块对齐使用,默认进行128Byte对齐
#define FLASH_STORE_PARM_HEADER_TAG (0x6C5A) //固定头信息
#define FLASH_STORE_PARM_BLOCK_SIZE (128) //块大小
#define FLASH_STORE_PARM_BLOCK_COUNT (u16)(FLASH_PAGE_SIZE / FLASH_STORE_PARM_BLOCK_SIZE) //1页分块的数量#pragma pack(1)
typedef struct
{........................
}GlobalParamStore, * GlobalParamStore_t;typedef struct
{........................
}DemarParamStore, * DemarParamStore_t, * pDemarParamStore;typedef struct
{........................
}ExceptionTrace;typedef struct
{........................
}ExtraLibPara;typedef struct
{u16 HeaderTag;u16 StoreIndex;
}FlashStoreHeader, * FlashStoreHeader_t;typedef struct
{FlashStoreHeader Header;GlobalParamStore SysPar;DemarParamStore DemarPar;ExceptionTrace ExpTrace;ExtraLibPara ExtLibPar;u8 ubRes[16];u8 ubCRC8;
}SystemParamStore, * SystemParamStore_t;
#pragma pack()
二、Flash最底层操作(解锁,加锁,擦除,读写)
说明:
- XSUPER_STM32G0_LL_LIB_ENABLE 被使能使用LL库
- Flash相关操作失败可多次尝试,尽可能让操作成功
#define FLASH_OPT_OVERTIMER (0x1FFFF)
#define FLASH_OPT_TRY_COUNT (5)/* Unlock the FLASH control register access */
static u8 ubFLASH_Unlock(void)
{u8 sta = 0;if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U){/* Authorize the FLASH Registers access */WRITE_REG(FLASH->KEYR, FLASH_KEY1);WRITE_REG(FLASH->KEYR, FLASH_KEY2);/* verify Flash is unlock */if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U){sta = 1;}}return sta;
}/* Lock the FLASH control register access */
static u8 ubFLASH_Lock(void)
{u8 sta = 1;/* Set the LOCK Bit to lock the FLASH Registers access */SET_BIT(FLASH->CR, FLASH_CR_LOCK);/* verify Flash is locked */if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u){sta = 0;}return sta;
}/* Gets the page of a given address */
static u32 ulGetPage(u32 startAddr)
{return ((startAddr - FLASH_BASE) / FLASH_PAGE_SIZE);
}/* Erase the specified FLASH memory page */
static u8 ubFLASH_PageErase(u32 page)
{u32 tmp = 0;u32 time = 0;u8 res = 0;/* Get configuration register, then clear page number */tmp = (FLASH->CR & ~FLASH_CR_PNB);/* Set page number, Page Erase bit & Start bit */FLASH->CR = (tmp | (FLASH_CR_STRT | (page << FLASH_CR_PNB_Pos) | FLASH_CR_PER));/* wait for BSY1 in order to be sure that flash operation is ended before allowing prefetch in flash */while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U){if ((++time) > FLASH_OPT_OVERTIMER){res = 1;break;}}/* If operation is completed or interrupted, disable the Page Erase Bit */CLEAR_BIT(FLASH->CR, FLASH_CR_PER);return res;
}/* Program double-word (64-bit) at a specified address */
/* Must EN PG bit before and DIS PG bit after */
static u8 ubFLASH_Program_DoubleWord(u32 addr, u64 data)
{u32 time = 0;/* Wait for last operation to be completed */while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U){if ((++time) > FLASH_OPT_OVERTIMER){return 1;}}/* Set PG bit */SET_BIT(FLASH->CR, FLASH_CR_PG);/* Program first word */*(u32 *)addr = (u32)data;/* Barrier to ensure programming is performed in 2 steps, in right order(independently of compiler optimization behavior) */__ISB();/* Program second word */*(u32 *)(addr + 4U) = (u32)(data >> 32U);/* Wait for last operation to be completed */while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U){if ((++time) > FLASH_OPT_OVERTIMER){return 2;}}return 0;
}/* Wait for a FLASH operation to complete */
static u8 ubFlash_WaitFor_Operate(u32 timeOut)
{u32 timer = 0;u32 error = 0;while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U){if ((++timer) >= timeOut){return 1;}}#if ( XSUPER_STM32G0_LL_LIB_ENABLE > 0)/* check flash errors */error = (FLASH->SR & FLASH_FLAG_SR_ERROR);/* Clear SR register */FLASH->SR = FLASH_FLAG_SR_CLEAR;
#endif#if ( XSUPER_STM32G0_HAL_LIB_ENABLE > 0)/* check flash errors */error = (FLASH->SR & FLASH_SR_ERRORS);/* Clear SR register */FLASH->SR = FLASH_SR_CLEAR;
#endifif (error != 0x00U){return 2;}timer = 0;while ((FLASH->SR & FLASH_SR_CFGBSY) != 0x00U){if ((++timer) > timeOut){return 3;}}return 0;
}/* Read double-word (64-bit) at a specified address */
void vFlash_Read_DoubleWord(u32 startAddr, u64 * pDat, u16 len)
{u16 i = 0;for(i = 0; i < len; ++i){*pDat++ = *(volatile u64 *)(startAddr + (i << 3));}
}static u8 xSuper_Flash_Unlock(void)
{u8 tryCount = 0;for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount){if (!ubFLASH_Unlock()) return 0;ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);}return 1;
}static u8 xSuper_Flash_Lock(void)
{u8 tryCount = 0;for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount){if (!ubFLASH_Lock()) return 0;ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);}return 1;
}static u8 xSuper_Flash_EreasePage(u32 startAddr)
{u8 tryCount = 0;u32 page = ulGetPage(startAddr);for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount){if (!ubFLASH_PageErase(page)) return 0;ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);}return 1;
}static u8 xSuper_Flash_Program(u32 startAddr, u64 * pDat, u16 len)
{u64 rData = 0;u16 i = 0;u8 tryCount = 0;for (i = 0; i < len; ++i){for (tryCount = 0; tryCount < FLASH_OPT_TRY_COUNT; ++tryCount){if(!ubFLASH_Program_DoubleWord(startAddr , pDat[i])){rData = *(volatile u64 *)(startAddr);if (rData != pDat[i]){return 1;}else{startAddr += 8;tryCount = 0;break;}}else{ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);}}if (tryCount) return 2;}return 0;
}u8 ubFlash_Write_DoubleWord_EreasePage(u32 startAddr, u64 * pDat, u16 len, u8 mode)
{//避免HardFault,三级流水线__asm volatile("NOP"); __asm volatile("NOP"); __asm volatile("NOP");__DMB(); __DSB(); __ISB();__asm volatile("NOP"); __asm volatile("NOP"); __asm volatile("NOP");if (xSuper_Flash_Unlock()){#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Unlock Error...\r\n");#endifreturn 1;}if (mode){if (xSuper_Flash_EreasePage(startAddr)){xSuper_Flash_Lock();#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Erease Error...\r\n");#endifreturn 2;}#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Erease OK...\r\n");#endif}if (xSuper_Flash_Program(startAddr, pDat, len)){xSuper_Flash_Lock();#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Program Error...\r\n");#endifreturn 3;}if (xSuper_Flash_Lock()){#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Lock Error...\r\n");#endifreturn 4;}return 0;
}
三、从Flash块中读取数据
- vRead_System_Parameter开始打印每个结构体大小,便于调试对齐使用

/* 获取读Flash块索引 */
static u16 usGet_Flash_Read_Index(void)
{u16 dat = 0, i = 0;u8 crc = 0;for (i = 0; i < FLASH_STORE_PARM_BLOCK_COUNT; ++i){dat = *(volatile u16 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i)));if (dat == FLASH_STORE_PARM_HEADER_TAG) {crc = ubCheckSum_CRC8((void *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i))), XOFS(SystemParamStore , ubCRC8));dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i)) + (FLASH_STORE_PARM_BLOCK_SIZE - 1));if (dat == crc){return (FLASH_STORE_PARM_BLOCK_COUNT - 1 - i);}}}return FLASH_STORE_PARM_BLOCK_COUNT;
}static void vRead_GlobalSystem_Parameter(void)
{u16 index = usGet_Flash_Read_Index();if (index < FLASH_STORE_PARM_BLOCK_COUNT){/* 读取块内容 */vFlash_Read_DoubleWord(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * index), (u64 *)&SystemParam, (FLASH_STORE_PARM_BLOCK_SIZE >> 3));#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Read Param OK...%u\r\n", SystemParam.Header.StoreIndex);#endif}else{/* 块索引无效 恢复默认值 */vRestoreDefault_GlobalSystemParam();#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Restore Param...%u\r\n", SystemParam.Header.StoreIndex);#endif}/* 打印块数据 */#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("\r\n");dprintf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F \r\n");dprintf("-------------------------------------------------------------\r\n");for (index = 0; index < FLASH_STORE_PARM_BLOCK_SIZE; ++index){if (index && (index % 16 == 0)) dprintf("\r\n");if (index % 16 == 0) dprintf("0x%08X ", (SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index));dprintf("%02X ", *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index));}dprintf("\r\n\r\n");#endif
}void vRead_System_Parameter(void)
{#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Header Size :%u\r\n", sizeof(FlashStoreHeader));dprintf("SysPar Size :%u\r\n", sizeof(GlobalParamStore));dprintf("DemarPar Size :%u\r\n", sizeof(DemarParamStore));dprintf("ExpTrace Size :%u\r\n", sizeof(ExceptionTrace));dprintf("ExtLibPar Size:%u\r\n", sizeof(ExtraLibPara));dprintf("SystemParamStore Size......%u\r\n", sizeof(SystemParamStore));if (sizeof(SystemParamStore) != FLASH_STORE_PARM_BLOCK_SIZE) while (1);#endifvRead_GlobalSystem_Parameter();
}
四、将数据写入Flash块中
static u16 usGet_Flash_Write_Index(void)
{u16 dat = 0, i = 0, x = 0;u8 uFlg = 0;for (i = 0; i < FLASH_STORE_PARM_BLOCK_COUNT; ++i){dat = *(volatile u16 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * i));if (dat == 0xFFFFU){uFlg = 0;for (x = 0; x < FLASH_STORE_PARM_BLOCK_SIZE; ++x){dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * i) + x);if (dat != 0xFFU){uFlg = 1;break;}}if (!uFlg) {return i;}}}return FLASH_STORE_PARM_BLOCK_COUNT;
}static void vSave_GlobalSystem_Parameter(void)
{u8 * pSrc = (u8 *)&SystemParam;u8 mode = 0, dat = 0;u16 index = 0;for (index = 0; index < FLASH_STORE_PARM_BLOCK_SIZE; ++index){dat = *(volatile u8 *)(SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex) + index);if (dat != *pSrc++){mode = 1;break;}}if (!mode){#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Pram Same...%u\r\n", SystemParam.Header.StoreIndex);#endifreturn;}mode = 0;index = usGet_Flash_Write_Index();if (index < FLASH_STORE_PARM_BLOCK_COUNT){SystemParam.Header.StoreIndex = index;}else{SystemParam.Header.StoreIndex = 0;mode = 1;}SystemParam.ubCRC8 = ubCheckSum_CRC8((void *)(&SystemParam), XOFS(SystemParamStore , ubCRC8));if (ubFlash_Write_DoubleWord_EreasePage((SYSTEM_ARG_STORE_START_ADDRE + (FLASH_STORE_PARM_BLOCK_SIZE * SystemParam.Header.StoreIndex)), (u64 *)&SystemParam, (FLASH_STORE_PARM_BLOCK_SIZE >> 3), mode)){#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Write Error...%u\r\n", SystemParam.Header.StoreIndex);#endif}else{#if defined(DEBUG_RELEASE_VERSION_ENABLE) && (DEBUG_RELEASE_VERSION_ENABLE == 0)dprintf("Flash Write OK...%u CRC:%02X\r\n", SystemParam.Header.StoreIndex, SystemParam.ubCRC8);#endif}
}void vSave_System_Parameter(void)
{vSave_GlobalSystem_Parameter();
}
五、测试验证
只需调用一下函数即可:
从Flash块中读取数据
void vSave_System_Parameter(void)
将数据写入Flash块中
void vRead_System_Parameter(void)




相关文章:
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入 参考例程例程说明一、存储到Flash中的数据二、Flash最底层操作(解锁,加锁,擦除,读写)三、从Flash块中读取数据五、测试验证 参考例程 STM32G0xx HAL和LL库Flash读写擦除操…...
SAP B1 认证考试习题 - 解析版(三)
前一篇:《SAP B1 认证考试习题 - 解析版(二)》 题目纯享版合集:《SAP B1 认证考试习题 - 纯享版》 五、运费(附加费用) 57. 以下哪个选项能够影响库存商品的价格 A. 仅为总量级别的附加费用 B. 只为行级…...
数据库开发规范
一、概述 本规范规定了,软件项目团队开发数据库的全流程规范。规范覆盖了数据库设计、管理及配套文件等。 二、项目阶段 项目阶段包括需求评审(需求分析阶段)、技术评审(方案阶段)、数据库开发…...
使用python向钉钉群聊发送消息
使用python向钉钉群聊发送消息 一、在钉钉群中新建机器人二、使用代码发送消息 一、在钉钉群中新建机器人 在群设置中添加机器人 选择自定义 勾选对应的安全设置 完成后会展示webhook,将地址复制出来,并记录,后面会用到 二、使用代码发送消…...
YOLOv11改进:SE注意力机制【注意力系列篇】(附详细的修改步骤,以及代码,与其他一些注意力机制相比,不仅准确度更高,而且模型更加轻量化。)
如果实验环境尚未搭建成功,可以参考这篇文章 ->【YOLOv11超详细环境搭建以及模型训练(GPU版本)】 文章链接为:YOLOv11超详细环境搭建以及模型训练(GPU版本)-CSDN博客 -------------------------------…...
STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用
如果有什么不懂的地方欢迎私聊博主,欢迎小白,博主必一一解答。 在 STM32 中,GPIO(通用输入输出)是与外部硬件接口进行交互的主要方式之一。STM32 HAL 库提供了简洁的接口来配置和控制 GPIO 引脚。下面是使用 STM32 HA…...
【毫米波雷达(七)】自动驾驶汽车中的精准定位——RTK定位技术
一、什么是RTK? RTK,英文全名叫做Real-time kinematic,也就是实时动态。这是一个简称,全称其实应该是RTK(Real-time kinematic,实时动态)载波相位差分技术。 二、RTK的组装 如上图所示&#x…...
Transformer和BERT的区别
Transformer和BERT的区别比较表: 两者的位置编码: 为什么要对位置进行编码? Attention提取特征的时候,可以获取全局每个词对之间的关系,但是并没有显式保留时序信息,或者说位置信息。就算打乱序列中token…...
linux 加载uPD720201固件
硬件 jetson orin nano jetpack 35.5.0 uPD720201是瑞萨推出的怕pcie扩展usb3.0芯片,支持flash主动加载与在系统被动加载 本文介绍如何做到没接flash情况下由系统加载固件 在uPD720201没接spi flash时候nano启动会报XhciDxe错误而自动重启,首先需要在ue…...
C语言中的信号量semaphore详解
在C语言中,**信号量(Semaphore)**是一种常用的同步机制,用于控制多个线程或进程对共享资源的访问。信号量可以实现类似于锁的效果,但更为灵活,适用于并发编程场景。 1. 什么是信号量 信号量可以看作是一个…...
0087__DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区
DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区-CSDN博客...
Windows换机华为擎云(银河麒麟V10+麒麟9000C CPU)后,使用selenium的程序怎么办(20241030)
原本的 seleniumChrome 已无法正常工作。chromedriver 报错:不支持 Linux/aarch64。 1、尝试Firefox、edge驱动。Firefox有一个geckodriver版本与Firefox版本的对照表,我看了一下,感觉他们是始终跟进新技术的。银河麒麟的很多库都是几年前的…...
linux 下 signal() 函数的用法,信号类型在哪里定义的?
--------------------------------------------------- author: hjjdebug date: 2024年 11月 07日 星期四 14:47:33 CST description: linux 下 signal() 函数的用法 --------------------------------------------------- signal 是linux 下最基础的进程通讯机制…...
享元模式及其运用场景:结合工厂模式和单例模式优化内存使用
介绍 享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来减少内存使用,尤其是对于大量相似对象的场景。享元模式通常与工厂模式和单例模式结合使用,从而有效地控制和复用对象的创建。在享元模式中&am…...
【物联网技术】ESP8266 WIFI模块在STA模式下实现UDP与电脑/手机网络助手通信——UDP数据透传
前言:完成ESP8266 WIFI模块在STA模式下实现UDP与电脑/手机网络助手通信——实现UDP数据透传 STA模式,通俗来说就是模块/单片机去连接路由器/热点来通信。 UDP协议,是传输层协议,UDP没有服务器和客户端的说法。 本实验需要注意,wifi模块/单片机与电脑/手机需要连接在同一个…...
【SQL Server】华中农业大学空间数据库实验报告 实验一 数据库
实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法,认识界面,了解其两个基本操作系统文件,并能熟练区分与应用交互式与T-SQL式两种方法在SQL Server中如何进行操作;学习有关数据库的基本操作,包括:…...
操作系统页面置换算法Java实现(LFU,OPT,LRU,LFU,CLOCK)
FIFO先进先出算法 java import java.util.LinkedList; import java.util.Queue; public class Main { //先进先出的思想 是 用一个队列去模拟数据 如果当前不存在就是发生缺页中断了 就需要添加 如果已经满了 将队头的元素出队 即可 //先进先出 就是一个数组 frameCount publi…...
Request和Response
前言 这一节主要讲的是Request和Response还有一些实例 1. 介绍 就是这两个参数 WebServlet("/demo7") public class ServletDemo7 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExcepti…...
【青牛科技】GC8549替代LV8549/ONSEMI在摇头机、舞台灯、打印机和白色家电等产品上的应用分析
引言 在现代电子产品中,控制芯片的性能直接影响到设备的功能和用户体验。摇头机、舞台灯、打印机和白色家电等领域对控制精度、功耗和成本等方面的要求日益提高。LV8549/ONSEMI等国际品牌的芯片曾是这些产品的主要选择,但随着国内半导体技术的进步&…...
(十二)JavaWeb后端开发——MySQL数据库
目录 1.数据库概述 2.MyQSL 3.数据库设计 DDL 4.MySQL常见数据类型 5.DML 1.数据库概述 数据库:DataBase(DB),是存储和管理数据的仓库 数据库管理系统:DataBase ManagementSystem(DBMS),操纵和管理数据库的大型软件 SQL&a…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
