PSoC+RC522的RFID-UART读写:固件架构与避坑指南

简介:一套基于可编程片上系统(PSoC)的射频识别(RFID)读写器完整工程,面向嵌入式开发者、电子工程类学生及物联网工程技术人员,用于解决RFID读写器与上位机之间通过通用异步收发器(UART)串行通信的实现问题。工程以PSoC芯片为控制核心,借助其内部集成UART模块完成标签数据的收发与控制指令解析,内容涵盖RFID工作原理、PSoC架构配置、UART波特率及帧格式设置、C语言固件编写和常见调试方法。压缩包含271个文件,大小约2.4MB,主体为56个C源码与60个头文件,同时包含Keil工程配置、汇编启动文件、hex/ihx固件、硬件设计文件与日志记录,能够完整体现从工程创建、代码编译到烧录运行的整个流程。目前已有203人学习,适合初学者对照源码理解读写器工作流程,也适合有经验者参考其中UART通信协议和硬件布局思路,快速迁移到库存管理、物流追踪、门禁控制等应用场景。

1. 用 PSoC 做 RFID-UART 读写,为什么先卡在“通信”而不是“RFID”

年前帮一位朋友调门禁模拟项目,主控选的是 PSoC 5LP,读卡模块是 RC522,当时第一版固件跑起来之后最扎眼的不是读不到卡,而是串口助手里的乱码和丢字节。查了一圈才发现问题出在 UART 链路:波特率对不上、时钟没配稳、模块的软复位时序被主循环拖死了。这三类问题在我后来拆过的几个 RFID 工程里反复出现,也是最初决定把整套固件整理成资源包的原因。这个资源是一个完整的 PSoC 固件工程,PSoC 通过两路 UART 分别对接 PC 与 RFID 读卡模块,把模块返回的原始字节解析成干净的卡号并上报。适合正在做门禁、出勤、资产盘点类原型、希望直接复用通信层而不是从头啃寄存器手册的开发者。

2. 选型与接线:PSoC 为什么适合“UART 桥 + RFID 网关”

2.1 可编程外设:一块芯片顶两个串口、三路中断

PSoC 5LP 属于片上可编程系统,最大的特点不是某个外设功能强,而是模拟和数字资源都放在可配置的 UDB(通用数字模块)里。你在图形化设计页里拖一个 UART 组件,它就占一块数字逻辑,配置好之后路由到任意 GPIO 引脚。这意味着板上不需要额外的电平转换和串口扩展芯片,两路 UART、一个定时器、几个 GPIO 中断都可以在同一颗芯片里共存。

这个资源实际用了两路 UART:

  • UART_PC:连接上位机,固定 115200,8 数据位、1 停止位、无校验。
  • UART_RFID:连接 RC522 模块,常用 19200,同样 8/1/N。

两路串口的波特率不同,在传统单片机里往往会争抢同一个波特率分频器,或者要手动改寄存器。PSoC 里每个 UART 组件自带分频器,参数互相独立。我这个工程里两个组件分别叫 UART_PC 和 UART_RFID,生成代码后调用的 API 也是分开的,不需要在代码里来回切换波特率设置。

还有一点容易被忽略:PSoC 的 UART 组件带硬件 FIFO,深度十几字节。PC 侧发来的数据可能是一整帧,RFID 模块的响应也是一整段,有 FIFO 做缓冲之后,主循环不需要在收到每个字节时都跑一遍状态机,可以减少小延迟。

2.2 RC522 模块三种接口与 UART 模式接线

RC522 是 13.56MHz 的 ISO14443A 读卡前端芯片,支持 Mifare S50/S70 等常用卡。市面上绝大多数模块默认跑 SPI,但它其实还支持 I2C 和 UART 两种模式。做“RFID-UART 读写”这个课题,最合适的选型就是直接让 RC522 跑 UART 模式,免掉 SPI 换串口的中间层。

三种接口在这个场景下的取舍:

接口接线数速率适合场景
SPI4 根(SCK、MOSI、MISO、SDA)高高速连续读写,但占引脚
I2C2 根(SDA、SCL)中节省引脚,但地址冲突和时序麻烦
UART2 根(TX、RX)中与 PC 侧协议天然对齐,调试直观

模块型号不同,UART 模式的启用方式也略有差异,常见做法是把模块背面的模式焊盘处理一下。我的经验是:拿到模块先看背面丝印,如果标着 SPI/I2C/UART 三组焊盘,就把地址选择那个短接点焊上,SDA 和 SCL 两个引脚就会切换成串口数据线。注意不同批次的模块丝印不一样,别照搬网上的图,拿万用表量一下模块上的主控引脚定义最稳妥。

接线参考:

PSoC 引脚RC522 模块引脚说明
P8_0(TX)RX(原 SDA)PSoC 发数据给模块
P8_1(RX)TX(原 SCL)模块发数据给 PSoC
P8_2(GPIO)RST模块复位控制
3.3VVCC模块供电
GNDGND共地

这里的 RX/TX 是交叉关系,但不同模块标注混乱,我在避坑章节里会专门讲这个。建议第一次接线时先不要焊死,用杜邦线留出对调的空间。

2.3 波特率、时钟分配与无硬件流控的取舍

UART 通信失败通常不是逻辑错误,而是时钟和波特率没有真正对上。PSoC 生成 UART 组件时,时钟源默认是总线时钟分频。组件配置界面里填波特率,但是时钟树的源头还要确认:如果系统时钟是 48MHz,UART 时钟分频到 3MHz、再 16 倍过采样,19200 是不好除尽的,实际波特率就偏了。这个工程里我给它单独分了一个 24MHz 时钟,19200 正好能除尽,PC 侧 115200 也完全正常,减少时钟误差带来的偶发性乱码。

RC522 模块的 UART 从机端,实际波特率做过校准,标称 19200 的模块误差通常在 1% 以内。但市面上模块出厂默认值五花八门,有些被卖家改成 9600 才出货。调不通时先用逻辑分析仪看模块 TX 引脚的实际波形周期,再回头改 PSoC 组件参数,别在代码里反复猜。

无硬件流控是这组方案最大的静态风险。RC522 模块基本不引出 CTS/RTS,PSoC 收到的数据只能靠软件消化。如果主循环里做耗时的 RFID 寻卡流程,期间模块又连续回数据,FIFO 会溢出。资源包里给了一个解决办法:RX 中断进环形缓冲,主循环有活就先干,缓冲满了再决定是丢帧还是重发。PC 侧上位机发来的命令帧很稀疏,瓶颈只在 RFID 响应方向上,环形缓冲足够用。

3. 固件实战:PSoC Creator 工程搭建与接收状态机

3.1 建工程、添加 UART 组件、分配引脚

用 PSoC Creator 打开工程后,设计页里能看到两个 UART 组件实例。组件的核心配置参数如下,照着填就行:

参数UART_PCUART_RFID
方向TX+RXTX+RX
波特率11520019200
数据位88
停止位11
奇偶校验NoneNone
接收缓冲FIFO(4 字节以上)FIFO(高水位中断)
中断源RX 有数据触发同上

引脚分配我习惯在 .cydwr 文件里手动指定:

  • UART_PC 的 TX 和 RX 接 USB 转串口芯片那侧的引脚。
  • UART_RFID 的 TX/RX 接 RC522 模块。
  • 模块 RST 引脚接普通 GPIO,用来做上电复位时序。

PSoC 组件生成代码之后,API 名是组件名加后缀。初始化代码在 main.c 里,看起来是这样:

#include "project.h" int main(void) { CyGlobalIntEnable; /* 开全局中断 */ UART_PC_Start(); /* PC 侧串口,115200 */ UART_RFID_Start(); /* RFID 模块串口,19200 */ RFID_Rst_Write(0); /* RST 拉低 */ CyDelay(10); /* 保持 10ms 复位 */ RFID_Rst_Write(1); /* 拉高,释放复位 */ CyDelay(50); /* 等模块稳定 */ UART_PC_UartPutString("RFID-UART Bridge Ready\r\n"); UART_PC_UartPutString("UID: --\r\n"); for(;;) { /* 主循环,稍后补状态机逻辑 */ } }

逻辑说明:UART_PC_Start 和 UART_RFID_Start 是对应组件的启动 API,必须先启动再读写,否则数据进不了 FIFO。RFID_Rst_Write 是 GPIO 输出控制,RC522 的复位时序是低电平保持一段时间再拉高,拉高之后还要等模块内部上电稳定。如果省略这里的延时,模块经常出现第一次命令无响应的情况,这个细节在避坑章节会再展开。

参数上注意 CyGlobalIntEnable 必须放在所有中断源使能之前。PSoC 的默认启动流程不自动开全局中断,很多从普通单片机转过来的开发者在这吃了亏,表现为“中断回调函数写了但永远不执行”。

3.2 串口中断 + 环形缓冲,别在中断里做卡顿的事

UART 接收最忌讳的做法是在中断回调里直接解析整帧。因为 RFID 模块回包可能是几字节一段,中断一次只来一个字节,解析状态机要跨多次中断维护,稍不留神就出错。更稳的做法是中断只负责把字节塞进环形缓冲,主循环空闲时再取出来解析。

工程里我建了两个环形缓冲,分别对应两路串口,核心代码:

#define RING_SIZE 64 static volatile uint8_t ring_pc[64]; static volatile uint8_t ring_rfid[64]; static volatile uint8_t head_pc, tail_pc; static volatile uint8_t head_rfid, tail_rfid; CY_ISR(UART_RFID_ISR) { uint8_t ch = UART_RFID_ReadRxData(); /* 读一个字节 */ uint8_t next = (head_rfid + 1) & (RING_SIZE - 1); if (next != tail_rfid) { /* 环形区未满 */ ring_rfid[head_rfid] = ch; head_rfid = next; } UART_RFID_ClearRxInterrupt(); }

逻辑说明:RING_SIZE 必须是 2 的幂,这样(head + 1) & (RING_SIZE - 1)才能正确实现取模。写的时候先判断 next 是否等于 tail,等于说明追上读指针了,缓冲已满,此时直接丢字节,避免覆盖未读数据。UART_RFID_ReadRxData 每次读出一个字节,FIFO 里还有未读字节时中断会自动再次触发,所以不需要手动清空 FIFO。

这套机制的关键是中断里不调用任何耗时函数——不解析帧、不打印、不调用 CyDelay,只做一次赋值。解析在 main 函数里做,主循环从缓冲取字节并送入状态机。

PC 侧的中断回调结构与上面完全相同,只是替换成 UART_PC 组件的 API,代码里共用一套缓冲结构时要注意两路串口的读写指针是独立的,不能互相覆盖。资源包里这两组变量命名都带后缀,方便区分。

3.3 寻卡、防碰撞、读卡号的命令流程

RFID 侧的核心流程是按 ISO14443A 协议的短命令走:REQA 询问附近有没有卡、防碰撞时从多张卡里选出目标、再取卡号。RC522 在 UART 模式下,PSoC 向模块发命令字节,模块自己处理射频通信,然后把结果从串口回出来。

这个工程里我封装了一个简化版的命令函数,流程如下:

uint8_t rfid_read_uid(uint8_t *uid_out) { uint16_t atqa; uint8_t cmd_reqa = 0x26; /* REQA */ uint8_t buf[8]; /* 1. 发 REQA,期望返回 2 字节 ATQA + 2 字节 CRC */ UART_RFID_ClearRxBuffer(); UART_RFID_WriteTxData(cmd_reqa); if (!rfid_wait_response(buf, 4, 50)) { return 0; /* 无卡响应 */ } /* 2. 防碰撞,期望返回 5 字节(4 字节 UID + 1 字节校验) */ UART_RFID_ClearRxBuffer(); UART_RFID_WriteTxData(0x93); UART_RFID_WriteTxData(0x20); if (!rfid_wait_response(buf, 5, 50)) { return 0; /* 防碰撞失败 */ } /* 3. 校验和 */ uint8_t xor_sum = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; if (xor_sum != buf[4]) { return 2; /* 校验失败,重发 */ } /* 4. 注意字节顺序:低字节在前,这里翻成高位在前 */ for (int i = 0; i < 4; i++) { uid_out[i] = buf[3 - i]; } return 1; }

逻辑说明:第 1 步 REQA 只有一个命令字节,RC522 检测到卡后返回 4 字节,其中前 2 字节是 ATQA,后 2 字节是硬件计算的 CRC。如果 PSoC 发出的波特率或电平不对,这里会一直等不到数据。第 2 步防碰撞命令返回 5 字节:4 字节 UID 加 1 字节 XOR 校验。第 4 步把低字节序翻成高位在前,是为了让上位机显示的卡号与卡面印刷的常见习惯一致,避坑章节会讲这个字节序问题。

rfid_wait_response 是超时等待函数,我一般设置 50ms 超时。RFID 模块的 13.56MHz 射频场建立需要时间,命令发出后如果卡在主循环里死等,PC 侧立刻卡死。超时机制做成独立函数,后续调整响应时间只改一处。

这里要注意一个常见误用:有人把 REQA 和防碰撞两条命令连发,中间不隔时间,导致模块上一帧没处理完就把新命令吞了。正确做法是每次发完命令必须等待模块回完当前帧,再发下一条。

4. 帧协议与脏数据防线:一帧该由什么组成

4.1 帧格式设计与各字段参数

UART 是字节流,上位机怎么知道一帧从哪里开始、到哪里结束?答案只有一个:协议。工程里 PC 与 PSoC 之间的通信帧定义成如下固定格式:

帧字段长度说明
帧头2 字节固定 0xAA 0x55
长度1 字节数据区长度(不含帧头、长度本身)
命令1 字节0x01 查卡、0x02 上报卡号、0x03 错误
数据区0~8 字节UID 等有效数据
CRC81 字节从长度到数据区末尾的校验值

上电后 PSoC 主动上报的“UID: --”文本是调试输出,走的是另一个通道;正式命令走的是二进制帧。这样做的原因是文本打印适合人看,二进制帧适合程序解析,两者混在一起会让代码又臭又长。

PC 发查卡命令时,数据区为空,整个帧只有 5 字节:

uint8_t request_frame[] = { 0xAA, 0x55, /* 帧头 */ 0x02, /* 长度:命令 1 字节 + 数据 0 字节 */ 0x01, /* 命令:查卡 */ 0x00 /* CRC8,预留 */ };

PSoC 收到这条命令后执行寻卡流程,读卡成功就把 UID 放上数据区回传。如果没读到卡,命令字段变 0x03,数据区放一个错误码,PC 侧不用猜原因。

4.2 CRC8 实现与异或校验的对比

串口传输里一个字节错了,粗校验根本发现不了。最简单的异或校验只能防随机变更,对“寄存器错位、字节丢失”这种系统性错误几乎无效。这里的帧很短,用 CRC8 就够了,多项式选 0x07,代码量小且查表实现简单。

资源包括完整的 CRC8 参考实现:

uint8_t crc8_update(uint8_t crc, uint8_t data) { crc ^= data; for (uint8_t i = 0; i < 8; i++) { if (crc & 0x80) { crc = (crc << 1) ^ 0x07; /* 多项式 x^8 + x^2 + x + 1 */ } else { crc <<= 1; } } return crc; }

逻辑说明:每次调入一个字节,从高位开始逐位处理。0x07 是 CRC-8/ATM 的常用多项式,在很多串口协议里都能见到。如果换多项式,发端和收端必须同时改,否则校验永远对不上。

实际发帧前,把从长度字段到最后一位数据逐字节带入 update,最终结果填进 CRC 字段。接收端同样算一遍,比对帧尾的 CRC。不一致就整帧丢弃,不做任何挽救,因为对读卡场景来说,重发一帧的成本远低于解析脏帧。

这个资源里我另外留了一个可选实现:CRC16。但实测下来对短帧收益不大,CPU 开销反而翻倍。如果你是做长数据帧(比如要传扇区数据),再考虑升级 CRC16。

4.3 半包、粘包与垃圾字节的处理

UART 没有天然的消息边界,上位机可能一次把两帧粘在一起发过来,也可能一帧被拆成两段。帧头 0xAA 0x55 的作用就是做边界对齐。

工程里 PC 侧接收用状态机,主循环每次从环形缓冲取一个字节,喂给下面这个逻辑:

typedef enum { ST_WAIT_HDR1, /* 等待 0xAA */ ST_WAIT_HDR2, /* 等待 0x55 */ ST_WAIT_LEN, /* 等待长度字段 */ ST_WAIT_CRC /* 等待整帧结束并校验 */ } rx_state_t; uint8_t parse_pc_frame(uint8_t ch) { static rx_state_t st = ST_WAIT_HDR1; static uint8_t frame_buf[16]; static uint8_t idx = 0; static uint8_t data_len = 0; switch (st) { case ST_WAIT_HDR1: if (ch == 0xAA) { st = ST_WAIT_HDR2; idx = 0; } break; case ST_WAIT_HDR2: st = (ch == 0x55) ? ST_WAIT_LEN : ST_WAIT_HDR1; break; case ST_WAIT_LEN: data_len = ch; frame_buf[idx++] = ch; st = ST_WAIT_CRC; break; case ST_WAIT_CRC: if (idx < sizeof(frame_buf)) { frame_buf[idx++] = ch; } if (idx >= (uint8_t)(data_len + 1)) { /* 帧收满,校验 */ st = ST_WAIT_HDR1; return validate_frame(frame_buf, data_len); } break; } return 0; }

逻辑说明:状态机不依赖定时超时,只依赖首字节匹配。乱字节只会让状态机停在等帧头的两态里,不会进到后续流程。半包的情况自然由状态机保持当前态继续等下一个字节;粘包则通过“收到完整一帧就回到初始态”来切割。

帧里没有显式的帧尾字段,而是用“长度字段 + 收满字节数”来判断结束。这样省掉两个字节的传输开销,也让状态机更简单。唯一代价是数据区一旦长度出错,整帧会晚一拍或早一拍结束,CRC 校验会在这一步拦住。

5. 避坑记录:RFID-UART 五个翻车现场

坑一:串口助手满屏乱码,打印和通信混用一套串口

现象:固件里 printf 打印调试信息,同时又通过同一路 UART 收发协议帧,串口助手看到的内容夹杂乱码,偶尔能收到正确帧,但时序一乱就完全不可用。

原因:调试打印走的 115200,协议帧也走 115200,两路数据混在同一个 FIFO 里,应用层无法区分哪段是日志、哪段是协议。

解决:把调试输出和协议帧彻底分离。正式运行时 PC 侧只收二进制帧,调试信息走另一路。如果硬件只有一路串口,就在固件里加一个“调试模式”,需要看日志时发一条特殊命令切换,平时静默。从那以后我每做串口工程都会先想清楚这条通道是给程序用的还是给人用的。

坑二:模块端 RX/TX 标注混乱,接线明明按网图却死在第一帧

现象:照着某教程把 PSoC TX 接模块 RX,模块 TX 接 PSoC RX,结果发命令后模块毫无响应,逻辑分析仪上连模块 TX 的波形都看不到。

原因:RC522 模块 UART 模式启用之后,原 SDA/SCL 引脚的 RX/TX 角色在不同卖家板子上是反的。部分模块把“TX”印成“SDA”的那根线,实际是芯片的 UART_RX。

解决:不要盲信丝印。第一次接线先把 RST 拉低复位模块,然后在模块 TX(标注 SDA 那个脚)上用示波器量静态电平,如果电压在 3.3V 左右,说明这是正常输出脚,接 PSoC RX 才对。反向接的话 PSoC 会收到一堆垃圾或什么都没收到。如果实在没有示波器,就把两根线对调测试,对调后能收到数据,说明原来才是接反的。

坑三:读卡距离只有 1 厘米,贴着模块才能识别

现象:卡片必须紧紧贴在天线区才能读到,隔一厘米就丢卡,上位机报超时。

原因:常见原因是模块供电不足。RC522 的天线驱动峰值电流可达几十毫安,如果直接从 PSoC 的 3.3V LDO 取电,电压跌落会让天线场强衰减。其次是天线匹配电容的批次偏差。

解决:模块的 VCC 和 GND 单独从稳压电源取电,PSoC 的 GPIO 只负责逻辑电平。匹配电容的调整需要对应模块的手感,我一般不改电容,先解决供电。手头没有独立电源时,在 VCC 和 GND 之间并一个 47uF 钽电容也有效果,比单纯加大输出电流更直接。PSoC 的 I/O 驱动器配置成强驱动模式,避免模块逻辑电平被拉低。

坑四:上电后第一次寻卡成功,第二次开始无响应

现象:按复位键后第一次读卡正常,再读第二张卡就一直超时,只有重新复位才能恢复。

原因:RFID 模块完成一次寻卡后,内部状态还停留在上次选卡的评估阶段。需要一条后续命令让它回到休眠态,否则对新的 REQA 无响应。

解决:读完 UID 之后发 HLTA 命令让卡进入休眠。工程里我在 rfid_read_uid 成功返回后追加了一帧0x50 0x00的 HLTA 命令,并顺手清空 UART_RFID 的接收缓冲。很多现成库里这一行是缺的,你会发现别人工程能用,自己抄过来就出问题。

坑五:两张卡叠在一起读时,UID 随机乱跳

现象:多张卡叠放时,读出来的 UID 一会儿是 A 卡、一会儿是 B 卡,上位机收到两次相同的 ID,但传感器物理上只放了一张卡。

原因:REQA 之后没有做防碰撞流程。模块返回的 UID 可能是多张卡信号叠加后的结果,低层 CRC 校验过了,但选出的卡号不稳定。

解决:严格按流程执行防碰撞命令。即使只预期一张卡,也不要跳过防碰撞步骤,因为卡片进场瞬间会有多个级联信号。工程里我在 REQA 成功后强制走 0x93 0x20 防碰撞,并用返回的 XOR 校验做一致性确认,两次都通过才上报 UID。这也是资源包固件里唯一一处刻意“绕远路”的逻辑,但每次读卡结果都稳定。

6. 验证手法与进阶:先搭一个可复盘的测试台

6.1 串口抓包与射频区调试

拿到工程后先不要急着接卡,我把整个系统拆成了三层验证:PC 侧用串口助手抓协议帧,PSoC 侧打印中断触发次数,模块侧用逻辑分析仪采 19200 波特率的波形。三层都通过后,读卡这个动作就变成一个白盒过程,每层状态都能对上。

比较快的验证方法是把 PC 的发送命令帧和示波器联动,先发 REQA 再看模块有没有返回波形。如果你手头有逻辑分析仪,直接把解码方式设成 UART 19200,会比用示波器来回核对电平轻松很多。

6.2 上位机模拟巡检脚本

下位机调通了,上位机侧也要有一个能反复发命令、自动判断超时的样本。我通常用 Python 写一个简洁脚本,配合 serial 库做循环巡检:

import serial import time PORT = "COM3" BAUD = 115200 ser = serial.Serial(PORT, BAUD, timeout=1) # 查卡命令:帧头 + 长度 + 命令 + CRC 占位 req = bytes([0xAA, 0x55, 0x02, 0x01, 0x00]) for i in range(20): ser.write(req) rsp = ser.read(10) # 读最多 10 字节 print(f"[{i:02d}] recv: {rsp.hex()}") if len(rsp) >= 8 and rsp[3] == 0x02: # 卡号在数据区前 4 字节里 uid = rsp[4:8] print("UID:", uid.hex().upper()) else: print("(no tag)") time.sleep(0.5)

脚本里的 req 帧是纯查卡命令,长度 0x02 表示命令 + 0 个数据字节,最后一个 CRC 占位符在没有完整计算之前先传 0。实际工程里我会用固件自动计算并填充,上位机只负责发完整帧。常见踩坑是 PC 发命令时把帧尾的 CRC 忘了,下位机每次都回错误帧,这种问题往往在上位机侧,和下位机一点关系都没有。

从那以后我每拿到一个 RFID-UART 模块,第一件事不是写业务逻辑,而是先跑一遍上面这个动作:量静态电平、抓 19200 波形、再跑一次寻卡脚本。链路通透了,后面的读卡、写卡、多卡防碰撞都只是锦上添花。这套方法也帮我避开了至少三次“模块看起来坏了,其实是波特率没对上”的假故障,希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

STM32 EC11旋转编码器驱动:硬件计数替代外部中断的稳定方案

STM32 EC11旋转编码器驱动:硬件计数替代外部中断的稳定方案

简介&#xff1a;STM32F407 EC11旋转编码器驱动函数&#xff0c;面向使用ARM Cortex-M4内核微控制器进行运动控制的嵌入式开发者&#xff0c;可广泛应用在工业控制、消费电子与物联网终端等场景。驱动代码围绕EC11编码器的A/B双相位脉冲检测、Z相零点定位及旋转方向判断展开&am…

2026/10/19 16:20:23 阅读更多 →
电力安全生产数智化落地指南:从感知闭环到实战经验

电力安全生产数智化落地指南:从感知闭环到实战经验

数智技术这几年在电力行业里被反复提及&#xff0c;我参与过多个安全生产相关的数智化改造项目&#xff0c;自己也在生产一线踩过不少坑。这个题目看着很大&#xff0c;实际上拆开来看&#xff0c;就是“怎么把人工智能、物联网、大数据这些技术真正用起来&#xff0c;让电力生…

2026/10/19 16:20:23 阅读更多 →
AI率检测原理与降重实战:千笔降AI率助手如何让论文更像人写的

AI率检测原理与降重实战:千笔降AI率助手如何让论文更像人写的

又到期末和毕业季&#xff0c;群里讨论最热闹的话题已经从“哪个查重网站更准”变成了“AI率怎么还这么高”。很多专科的朋友私信问我&#xff1a;明明是自己参考文献一点点写出来的&#xff0c;为什么系统一看就标了“疑似AI生成”&#xff1f;这里面有个认知误区——AI率查的…

2026/10/19 16:20:23 阅读更多 →

最新新闻

OpenClaw多智能体编排实践:销售线索挖掘、客户跟进与方案生成

OpenClaw多智能体编排实践:销售线索挖掘、客户跟进与方案生成

做销售智能化的同学大都遇到过这种尴尬&#xff1a;模型对话能力是够的&#xff0c;但落到真实业务里&#xff0c;要么连不上存量数据&#xff0c;要么不知道下一步该调用哪个系统&#xff0c;要么辛辛苦苦生成的方案客户一眼就看出是套模板。我前前后后折腾了大半年&#xff0…

2026/10/19 17:03:20 阅读更多 →
Git原生AI代码审查工具:CLI+Hook驱动的可审计代码质量实践

Git原生AI代码审查工具:CLI+Hook驱动的可审计代码质量实践

1. 这不是又一个“AI代码审查”玩具&#xff1a;open-code-review 的真实定位与设计哲学你肯定见过太多打着“AI Code Review”旗号的工具——点开网页&#xff0c;粘贴几行代码&#xff0c;等三秒&#xff0c;弹出几条泛泛而谈的“建议”&#xff0c;比如“变量名可读性有待提…

2026/10/19 17:03:20 阅读更多 →
城市地图集制作指南:数据清洗、坐标系与开源工具实战

城市地图集制作指南:数据清洗、坐标系与开源工具实战

Atlas这个词&#xff0c;在地图相关词汇里应该算得上最有故事感的一个。它既是古希腊神话里用肩膀撑起天空的泰坦神&#xff0c;也指把世界装订成册的地图集。第一次见到这个词是在一本旧地图册的书脊上&#xff0c;封面上只有一个单词&#xff0c;打开以后&#xff0c;一个城市…

2026/10/19 17:03:20 阅读更多 →
代码审查落地指南:用 open-code-review 打造高效的 Code Review 流程

代码审查落地指南:用 open-code-review 打造高效的 Code Review 流程

1. 先搞清楚&#xff1a;open-code-review 到底在解决什么问题我见过太多团队&#xff0c;GitHub 仓库开着&#xff0c;PR 也提了&#xff0c;但代码审查就是走个过场——Reviewer 打开页面&#xff0c;扫一眼 diff&#xff0c;看到没有明显的语法错误&#xff0c;直接点 Appro…

2026/10/19 17:03:20 阅读更多 →
open-code-review实战:把形式化代码评审变成团队资产

open-code-review实战:把形式化代码评审变成团队资产

说句实话&#xff0c;代码评审这件事&#xff0c;在多数团队里长期处于一种“谁都承认重要&#xff0c;但就是做不好”的尴尬状态。我做过几年一线开发&#xff0c;也带过小团队&#xff0c;见过太多把 Code Review 走成形式的例子——要么是合并前机械地点一下通过&#xff0c…

2026/10/19 17:03:20 阅读更多 →
《呆呆虫源代码阅读》前言:一份解释器学习者的源码阅读路线图

《呆呆虫源代码阅读》前言:一份解释器学习者的源码阅读路线图

有些学习项目&#xff0c;代码还没开始读&#xff0c;光是《前言》这一节就够你来回翻三遍。我说的这个项目&#xff0c;就是《呆呆虫源代码阅读》。先说清楚它是什么&#xff1a;呆呆虫是一套用Go实现的教学型脚本语言解释器&#xff0c;语法轻巧、结构清晰&#xff0c;代码库…

2026/10/19 17:02:18 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →