STM32F103唯一ID读取实战:原理、代码实现与高级应用
1. 项目概述为什么需要读取STM32的“身份证”在嵌入式开发中尤其是涉及产品量产、软件授权、设备身份识别或防抄板等场景时我们常常需要一个独一无二、无法篡改的硬件标识。这个标识就像是芯片的“身份证”。对于STM32系列单片机而言这个“身份证”就是它的唯一设备标识符。今天我们就来深入聊聊如何在STM32F103这款经典且应用广泛的芯片上准确、可靠地读取这个ID。你可能会有疑问我直接用个EEPROM存个序列号不就行了为什么非要读芯片内部的ID这里面的区别和意义可大了。首先芯片内部的唯一ID是在生产过程中由ST公司激光刻录或固化在芯片内部的对于每一颗STM32都是全球唯一的无法被用户修改或擦除。这保证了标识的绝对唯一性和不可伪造性。其次它不占用任何用户存储空间Flash或RAM是芯片的“原生属性”。基于这个ID我们可以实现许多高级功能比如生成绑定此硬件的软件激活码防止程序被复制到其他板子上运行在物联网应用中作为设备的唯一MAC地址或设备标识符在量产测试中自动记录每块板子对应的芯片信息实现精准溯源。STM32F103的ID存储在一个特定的内存地址区域读取它本质上就是去访问这个只读的内存区域。听起来简单但实际操作中从地址的理解、数据的读取到格式的转换每一步都有需要注意的细节。接下来我将带你从原理到实践完整走一遍这个过程并分享我在实际项目中积累的实操经验和避坑指南。2. 核心原理与存储结构深度解析要正确读取ID首先得知道它放在哪里、长什么样。STM32F103的唯一ID是一个96位即12字节的数据。根据ST官方参考手册这个ID的存储地址是0x1FFFF7E8到0x1FFFF7F4不同STM32系列地址可能不同F103是这个。这96位数据并不是随意排列的它包含了芯片的多种信息。2.1 ID地址映射与数据含义我们通过指针直接访问这个地址区域。具体来说0x1FFFF7E8开始的4个字节32位通常与芯片的晶圆批次相关。0x1FFFF7EC开始的4个字节是芯片在晶圆上的X坐标。0x1FFFF7F0开始的4个字节是芯片在晶圆上的Y坐标。这X、Y坐标的组合保证了在同一个晶圆批次内每颗芯片的ID也是唯一的。当我们读取时通常将这12个字节作为一个整体即一个96位的唯一标识符。在程序中我们常将其转换为一个16字节的十六进制字符串因为每个字节需要两个十六进制字符表示或者一个24字节的ASCII字符串如果你用%02X格式输出。注意虽然手册给出了地址但强烈建议使用ST标准外设库或HAL库中定义的宏来访问而不是直接写死0x1FFFF7E8。例如在标准外设库中这个地址通常被定义为(uint32_t*)0x1FFFF7E8或通过UID_BASE这样的宏。这样做的好处是如果你的项目未来需要更换到另一款STM32如F4系列其ID地址不同只需更新库文件你的代码无需修改可移植性大大增强。2.2 读取操作的硬件与软件本质从硬件层面看这个ID存储在一块特殊的OTP一次性可编程存储器或类似的只读存储单元中。CPU通过内部总线通常是AHB或APB总线访问这个物理地址。这个过程是只读的任何写操作都是无效的这从硬件上保证了ID的安全性。从软件层面看我们的代码需要做以下几件事声明指针定义一个指向uint32_t或uint8_t类型的指针并将其指向ID的起始地址。由于内存访问最好以32位对齐通常使用uint32_t*指针一次读取4字节效率更高。解引用读取通过指针解引用获取该地址存储的数据。数据重组将读取到的多个32位数据按照我们需要的顺序通常是大端或小端组合成最终的96位ID。格式化输出将二进制数据转换为便于显示、存储或传输的格式如十六进制字符串。这里有一个关键点STM32的内存系统是小端模式。也就是说一个32位数据例如0x12345678存储在内存中低字节0x78在低地址。当我们用uint32_t*指针从0x1FFFF7E8读取时读到的就是0x?? ?? ?? ??这个完整的32位值顺序是符合我们直觉的。但如果我们用uint8_t*指针逐个字节读取就需要关注字节序问题。不过在将ID转换为字符串时我们通常按照地址递增的顺序依次处理每个字节这样得到的字符串顺序是固定的、可预期的。3. 三种实战代码实现与对比理解了原理我们来看代码。我将展示三种不同开发环境下的实现方法标准外设库、HAL库以及纯寄存器操作。你可以根据你的项目情况选择。3.1 基于标准外设库的实现如果你的项目使用的是经典的STM32标准外设库StdPeriph Lib实现如下。首先确保你的工程包含了stm32f10x.h和相关头文件。#include stm32f10x.h #include stdio.h // 用于sprintf /** * brief 读取STM32F103的唯一ID96位 * param uidArray: 用于存储ID的数组至少12字节 * retval None */ void Get_STM32F103_UID(uint8_t *uidArray) { uint32_t *uid_addr (uint32_t*)0x1FFFF7E8; // 使用宏更好如 (uint32_t*)UID_BASE // 读取3个32位数据共96位 uint32_t uid_part0 uid_addr[0]; // 地址: 0x1FFFF7E8 uint32_t uid_part1 uid_addr[1]; // 地址: 0x1FFFF7EC uint32_t uid_part2 uid_addr[2]; // 地址: 0x1FFFF7F0 // 将32位数据分解为字节存入数组 // 注意内存布局这里按小端顺序将低地址字节放在数组前端是常见做法 uidArray[0] (uid_part0 0) 0xFF; uidArray[1] (uid_part0 8) 0xFF; uidArray[2] (uid_part0 16) 0xFF; uidArray[3] (uid_part0 24) 0xFF; uidArray[4] (uid_part1 0) 0xFF; uidArray[5] (uid_part1 8) 0xFF; uidArray[6] (uid_part1 16) 0xFF; uidArray[7] (uid_part1 24) 0xFF; uidArray[8] (uid_part2 0) 0xFF; uidArray[9] (uid_part2 8) 0xFF; uidArray[10] (uid_part2 16) 0xFF; uidArray[11] (uid_part2 24) 0xFF; } /** * brief 将UID数组转换为十六进制字符串 * param uidArray: UID数组 * param strBuffer: 输出字符串缓冲区至少需要25字节12字节*2 结束符 * retval None */ void UID_To_HexString(uint8_t *uidArray, char *strBuffer) { for(int i 0; i 12; i) { sprintf(strBuffer[i*2], %02X, uidArray[i]); // 格式化为大写十六进制 } strBuffer[24] \0; // 添加字符串结束符 } // 使用示例 int main(void) { uint8_t uid[12]; char uidStr[25]; Get_STM32F103_UID(uid); UID_To_HexString(uid, uidStr); // 现在可以通过串口打印 uidStr或者用于其他逻辑 // printf(Chip UID: %s\r\n, uidStr); while(1) { // 主循环 } }实操心得在标准库中直接使用地址指针是最快的方式。但务必注意0x1FFFF7E8这个地址位于系统内存区域不是Flash也不是RAM你的调试器在正常运行时可能无法直接查看这个地址的内容。我建议将读取到的UID通过串口打印出来这是最可靠的验证方式。另外数组uid的字节顺序即哪个字节算作UID的最高位取决于你的应用协议上述代码将uid_part0的最低字节放到了uid[0]这是按内存地址递增的常见顺序与用uint8_t*指针逐个读取的结果一致。3.2 基于HAL库的实现对于使用STM32CubeMX和HAL库的新项目过程类似但我们可以利用HAL库可能已经定义好的宏尽管HAL库本身没有专门读取UID的函数。通常我们需要自己定义地址或者查看stm32f1xx_hal.h中是否有相关定义。#include main.h #include stm32f1xx_hal.h // 如果HAL库未定义我们自己定义UID基地址对于F103 #define UID_BASE_ADDRESS 0x1FFFF7E8U void Get_Chip_UID_HAL(uint8_t *buffer) { uint32_t *pUID (uint32_t *)UID_BASE_ADDRESS; // 一次性读取三个32位字 uint32_t word0 pUID[0]; uint32_t word1 pUID[1]; uint32_t word2 pUID[2]; // 使用联合体(union)或内存拷贝进行转换这里使用更直观的移位操作 buffer[0] (uint8_t)(word0 0); buffer[1] (uint8_t)(word0 8); buffer[2] (uint8_t)(word0 16); buffer[3] (uint8_t)(word0 24); buffer[4] (uint8_t)(word1 0); buffer[5] (uint8_t)(word1 8); buffer[6] (uint8_t)(word1 16); buffer[7] (uint8_t)(word1 24); buffer[8] (uint8_t)(word2 0); buffer[9] (uint8_t)(word2 8); buffer[10] (uint8_t)(word2 16); buffer[11] (uint8_t)(word2 24); } // 或者一个更简洁的版本直接按字节指针访问 void Get_Chip_UID_HAL_Simple(uint8_t *buffer) { uint8_t *pUID (uint8_t *)UID_BASE_ADDRESS; for(int i 0; i 12; i) { buffer[i] pUID[i]; } }注意事项Get_Chip_UID_HAL_Simple函数更加简洁它直接以字节为单位遍历内存。这两种方法在结果上是等效的。在HAL库项目中我更喜欢第二种方法因为它意图更清晰——我们就是要12个连续的字节。同时建议将UID_BASE_ADDRESS的定义放在一个独立的头文件如chip_id.h中方便不同源文件引用和管理。3.3 纯寄存器操作实现如果你在写裸机程序或者追求极致的效率和可控性可以直接操作寄存器。对于读取固定地址内存来说这和上面的指针操作没有本质区别但可以让你更清楚地看到发生了什么。// 假设在一个没有标准库的环境下 #define UID_START_ADDR 0x1FFFF7E8 typedef volatile uint32_t vu32; typedef volatile uint8_t vu8; void Read_Chip_ID_Register(uint8_t uid_out[12]) { // 方法1使用32位访问 vu32* uid_reg (vu32*)UID_START_ADDR; vu32 w0 uid_reg[0]; vu32 w1 uid_reg[1]; vu32 w2 uid_reg[2]; // 将字数据分解到字节数组 *((vu32*)(uid_out[0])) w0; // 注意这依赖于编译器的字节序不推荐。 // 更安全的方法仍是逐字节赋值 uid_out[0] (w0 0) 0xFF; // ... 省略后续赋值同前例 // 方法2直接使用8位指针访问推荐清晰无歧义 // vu8* uid_byte (vu8*)UID_START_ADDR; // for(int i0; i12; i) { // uid_out[i] uid_byte[i]; // } }踩坑记录在早期的一次项目中我曾试图用*((uint32_t*)(uid_out)) w0;这样的内存拷贝来快速赋值结果在不同优化等级的编译下出现了字节序错乱的问题。这是因为这种操作直接操作了内存而编译器的行为可能不一致。血的教训是在处理这种需要精确字节顺序的数据时显式地使用移位和掩码操作或者逐字节拷贝是最安全、可移植性最好的方法不要为了所谓的“优化”而引入不确定性。4. 高级应用与功能扩展仅仅读出ID还不够关键在于怎么用。下面分享几个我在实际产品中用到的扩展应用。4.1 生成设备唯一序列号96位的ID很长直接使用不方便。我们可以通过一个哈希函数如CRC32、MD5或简单的自定义算法将其压缩成一个固定长度的短序列号例如4字节或8字节。#include stdint.h // 一个简单的哈希函数示例FNV-1a变种用于从UID生成一个32位序列号 uint32_t Generate_Serial_From_UID(uint8_t *uid, uint8_t len) { uint32_t hash 2166136261u; // FNV偏移基础值 for(int i0; ilen; i) { hash ^ uid[i]; hash * 16777619u; } return hash; } // 使用示例 uint8_t my_uid[12]; Get_STM32F103_UID(my_uid); uint32_t device_sn Generate_Serial_From_UID(my_uid, 12); // device_sn 可以作为设备的短序列号这个device_sn可以烧录到Flash的某个固定位置作为设备出厂信息的一部分比直接存储96位ID更节省空间。4.2 实现简易软件授权与防复制利用UID可以实现简单的软件绑定。思路是在程序初始化时读取UID然后与一个预先设定的“密钥”或算法进行计算得到一个结果。将这个结果与存储在Flash中的另一个值激活码进行比较只有匹配时软件才进入正常工作模式。#define ACTIVATION_CODE_ADDR 0x0800FC00 // Flash中存储激活码的地址示例 uint8_t Check_Software_License(void) { uint8_t uid[12]; uint32_t calculated_key; uint32_t stored_key; // 1. 读取芯片UID Get_Chip_UID_HAL_Simple(uid); // 2. 使用一个算法和主密钥计算本机的“激活码” calculated_key Your_License_Algorithm(uid, MASTER_SECRET_KEY); // 3. 从Flash指定地址读取之前存储的激活码 stored_key *(uint32_t*)ACTIVATION_CODE_ADDR; // 4. 比较 if(calculated_key stored_key) { return 1; // 授权成功 } else { return 0; // 授权失败可进入演示模式或限制功能 } }这里的Your_License_Algorithm是你自己设计的算法可以结合UID和一个只有你知道的MASTER_SECRET_KEY这个密钥不能出现在客户端代码中否则会被反编译找到进行计算。在量产时你通过一个离线工具根据每颗芯片的UID计算出对应的激活码然后通过烧录器写入到Flash的ACTIVATION_CODE_ADDR地址。这样程序就被绑定到了这块具体的硬件上。重要安全提示这种方法只能防君子不防小人对于有经验的破解者通过反汇编找到算法和比较点仍然可以绕过。但它能有效防止普通的程序复制粘贴显著提高了抄袭的门槛。对于高安全需求建议使用带有硬件加密功能的STM32系列如STM32L5。4.3 在物联网中作为设备标识在MQTT、CoAP等物联网协议中设备需要一个Client ID或Endpoint Name。直接使用UID的十六进制字符串就是一个绝佳的选择保证了全球唯一性。void Get_Device_ClientID(char *clientIdBuffer) { uint8_t uid[12]; char uidStr[25]; Get_STM32F103_UID(uid); UID_To_HexString(uid, uidStr); // 可以添加前缀如 DEV_ sprintf(clientIdBuffer, DEV_%s, uidStr); } // 得到的clientIdBuffer类似DEV_1234567890ABCDEF12345678将这个Client ID用于连接阿里云、AWS IoT、腾讯云等物联网平台可以免去你手动分配和管理设备标识的麻烦。平台后台可以直接用这个ID来区分设备。5. 调试技巧与常见问题排查实录即使原理和代码都清楚了第一次实操时还是可能遇到各种问题。下面是我总结的常见“坑点”和解决方法。5.1 问题一读出来的ID全是0xFF或0x00现象通过调试器查看内存地址0x1FFFF7E8或者串口打印出来的UID全部是0xFFFFFFFF或0x00000000。排查思路地址错误首先确认芯片型号是STM32F103并且你使用的地址是正确的。不同STM32系列的UID地址不同F1是0x1FFFF7E8F4是0x1FFF7A10一定要核对《参考手册》。调试器访问限制在调试模式下某些调试器特别是通过SWD接口可能无法直接访问系统内存区域。最可靠的验证方法不是看调试器的Memory窗口而是通过你的代码将数据打印到串口。在代码中读取UID后通过printf发送到串口用串口助手查看。代码优化检查编译器优化等级。如果读取UID的代码被编译器认为是“无副作用”的无效代码可能会被优化掉。确保存储UID的变量是volatile的或者将读取UID的函数返回值用于实际操作如打印、计算避免被优化。芯片问题极少数情况下可能是芯片本身的问题。换一颗同型号芯片测试一下。5.2 问题二每次上电读出的ID不一致现象程序运行中多次读取UID或者复位后重新读取得到的值不一样。排查思路指针或数组越界这是最常见的原因。检查你的数组是否足够大至少12字节检查指针操作是否越界破坏了相邻内存的数据。栈或堆溢出如果读取UID的函数使用了局部数组并且栈空间不足或者程序其他部分有内存溢出可能会覆盖这块内存。确保栈空间设置合理。缓存问题STM32F103没有数据缓存所以不是缓存一致性问题。但如果你是在有Cache的高端芯片如F7、H7上遇到此问题则需要考虑Cache的影响在访问这类特定内存地址前清空或禁用Cache。软件逻辑错误仔细检查你的读取和转换代码特别是字节序处理部分。用一个已知的模拟UID例如在内存中定义一个常量数组测试你的转换和打印函数确保逻辑正确。5.3 问题三UID转换的字符串格式不对现象读出的字节数据看起来是随机的但转换成字符串后与别人读出的格式不同比如字节顺序反了。解决方案明确你的需求。你需要的是大端序还是小端序的字符串通常按照内存地址从低到高依次排列字节得到的字符串是一种最自然、最常用的格式。编写一个测试函数用一组固定的字节数组如{0x12, 0x34, 0x56, 0x78, ...}输入给你的UID_To_HexString函数看输出是否符合你的预期。记录下你确定的转换规则并在整个项目包括上位机软件中保持一致。5.4 调试与验证最佳实践串口打印是王道无论你用什么调试器将UID以十六进制字符串形式通过串口打印出来是最直观、最不容易出错的方法。用串口助手或逻辑分析仪捕获这个字符串。编写单元测试为你的UID读取和转换函数编写简单的测试代码在开发初期就验证其正确性。对比官方工具如果条件允许使用ST官方的编程软件如ST-LINK Utility连接芯片它通常有一个“芯片信息”或“Unique ID”的查看界面将你读出的ID与工具显示的进行对比这是终极验证。注意供电稳定性在极端不稳定的电源环境下读取系统内存区域可能会出错。确保你的板子在读取ID时供电充足、稳定。读取STM32的芯片ID是一个小而精的必备技能它连接着硬件身份与软件逻辑。掌握它不仅能让你轻松完成设备标识、软件授权等任务更能加深你对单片机内存布局和底层访问的理解。希望这篇详尽的拆解和实战记录能让你在下次需要用到这个功能时信手拈来游刃有余。在实际项目中我习惯将UID读取函数封装成一个独立的模块并提供获取字符串、哈希值等不同格式的接口这样在任何需要的地方都能方便地调用让代码更加整洁和模块化。

相关新闻

NET生态下 OAuth2.0+OIDC 统一身份平台搭建,解决多系统登录互通难题

NET生态下 OAuth2.0+OIDC 统一身份平台搭建,解决多系统登录互通难题

随着企业数字化系统持续扩建,多数公司会陆续上线 CRM 客户管理、ERP 生产系统、小程序后端、MES 车间管理、OA 办公平台多套业务系统。 早期单体项目依靠 Session 完成登录校验,系统数量少的时候可以稳定运行;当业务拆分为多个ASP.NET Core 独立服务之后,登录状态不互通、账…

2026/10/16 8:36:25 阅读更多 →
重拳整治生物医药检验造假之风,IACheck AI 报告审核构建全天候智能质控屏障

重拳整治生物医药检验造假之风,IACheck AI 报告审核构建全天候智能质控屏障

近些年,生物医药产业作为国民健康支柱产业,迎来了飞速发展期。创新药研发、医疗器械投产、体外诊断试剂量产、临床试验开展、药企出厂质量检测…… 整条产业链蓬勃扩张的背后,潜藏已久的检验报告造假、数据篡改、检测结果随意修订、原始记录与…

2026/10/15 9:21:15 阅读更多 →
安全帽检测基pysie6 yolo8的安全帽检测系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

安全帽检测基pysie6 yolo8的安全帽检测系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

安全帽检测基pysie6 yolo8的安全帽检测系统31(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 技术栈:yolo8pyside6 可以识别两类:安全帽、未佩戴安全帽 中文标签输出 视频图片等比缩放保证不失真 [1]可以识别图片识别,…

2026/10/15 3:53:28 阅读更多 →

最新新闻

AgenticRAN架构解析:无线接入网向智能体自治演进

AgenticRAN架构解析:无线接入网向智能体自治演进

最近我在梳理一份关于"AgenticRAN架构"的专项调研,项目名字虽然挂在某头部设备商头上,但真正让我花时间的,是"Agentic"这三个字母到底给无线接入网带来了什么本质变化。调研过程中我翻了大量公开材料、专利布局、标准化提…

2026/10/17 7:20:06 阅读更多 →
AI与数字孪生融合进PLM,解锁产品数据闭环价值

AI与数字孪生融合进PLM,解锁产品数据闭环价值

头一回见到把AI和数字孪生同时塞进PLM架构里做深度集成的项目,是在瑞华丽这款国产PLM的升级方案评审现场。做了十多年制造业软件实施,我看过太多PLM项目最后做着做着就变成了图文档柜——上传、审批、归档,业务流转倒是顺了,可产品…

2026/10/17 7:20:06 阅读更多 →
SMOKE单目3D检测的TensorRT部署全指南:从ONNX导出到FP16精度调优

SMOKE单目3D检测的TensorRT部署全指南:从ONNX导出到FP16精度调优

车载端部署单目3D检测,最磨人的往往不是模型效果本身,而是从PyTorch训练产物到TensorRT推理引擎之间那段路。SMOKE这类基于关键点回归的单阶段方法,好处是网络结构清爽、不依赖LiDAR,非常适合做嵌入式落地;但真到了Ten…

2026/10/17 7:20:06 阅读更多 →
从原型到生产:用LangGraph构建可持久化、可观测的AI智能体

从原型到生产:用LangGraph构建可持久化、可观测的AI智能体

最近这半年,我身边陆续有好几个团队在搞AI智能体,但说句实话:真正敢把智能体放到生产环境里,让真实用户天天用的,屈指可数。大部分人停在了“Demo很惊艳,一上线就翻车”的阶段——会话状态说丢就丢&#xf…

2026/10/17 7:20:06 阅读更多 →
DMA与RDMA:拧干分布式训练中的通信内耗,把GPU算力真正用满

DMA与RDMA:拧干分布式训练中的通信内耗,把GPU算力真正用满

做分布式训练的朋友,不少都遇到过这么一种怪象:GPU 明明在跑,可训练吞吐就是上不去,卡越多越觉得亏。看监控时更是焦虑,CPU 使用率忽高忽低,网卡带宽明明占用不少,延迟却飘忽不定。最后定位半天…

2026/10/17 7:20:06 阅读更多 →
AI写教材如何规避重复率陷阱?低查重工具选型与提示词策略

AI写教材如何规避重复率陷阱?低查重工具选型与提示词策略

最近半年我一直在帮某课程团队整理一本专业基础课教材,从大纲到初稿全程用 AI 协作,中间最头疼的倒不是“AI 写不出来”,而是“AI 写出来之后,原创性和教学深度都撑不住”。团队里三位老师拿着初稿去和已出版教材比对,…

2026/10/17 7:19:06 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →