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…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...