VC 6.0与Turbo C串口通信源码解析:从底层原理到工程实践

简介:这份资源是龚建伟、熊光明编著的《Visual C++/Turbo C串口通信编程实践(第2版)》配套源代码,面向具备一定C/C++基础、希望掌握串口通信开发的高校学生与嵌入式、工控方向程序员。内容围绕VC 6.0与Turbo C环境下的串口编程展开,涵盖通信控件封装、多线程收发、协议解析与调试等典型场景,可帮助读者对照书中实例动手实践,理解串口通信的底层机制与工程实现思路。压缩包共787个文件,约16.57MB,以h头文件、cpp源文件为主,辅以obj、exe、pdb等编译产物,以及ico、bmp、rc等界面资源,另有dsw、dsp、clw等工程与类向导文件,便于直接打开编译运行。目前已有362人学习下载,适合作为课程设计、毕业设计及串口工具开发的参考素材,读者可从中获取完整工程结构、可复用代码模块与调试排错经验。

1. 从一份老代码说起:为什么今天还要翻出 VC 6.0 的串口工程

前阵子帮一个做工业设备维护的朋友排查问题,他手里一台老工控机跑着 Windows XP,上位机软件是十几年前用 VC 6.0 写的,靠串口跟一块采集板通信。设备还在产线上转,源码却只剩一个压缩包,里面是《Visual C++/Turbo C串口通信编程实践(第2版)》配套的源代码。他问我:这东西现在还有用吗?我的回答是,如果你要维护存量设备、要理解串口通信最底层的收发逻辑,这份代码比很多新框架都直接。它不依赖任何第三方串口库,VC 6.0 部分用 Win32 API 直接操作 COM 口,Turbo C 部分则是在 DOS 环境下直接读写 UART 寄存器。适合两类人:一是需要接手老工控项目的维护开发者,二是想搞懂串口到底怎么收发的学习者。下面我按实际拆包和编译的过程,把这份资源讲清楚。

2. 工程结构拆解:VC 6.0 与 Turbo C 两套代码怎么组织

2.1 目录布局与文件类型

这份源代码包解压后,通常按编译器分成两个大目录,一个对应 Visual C++ 6.0 的 Windows 工程,一个对应 Turbo C 2.0/3.0 的 DOS 工程。VC 目录下是典型的.dsw工作区文件加.dsp工程文件,源码以.cpp和.h为主,资源文件是.rc。Turbo C 目录下则是.prj工程文件和.c源文件,没有资源脚本,因为 DOS 下没有窗口系统。

我拿到包后第一件事是看目录名和文件后缀,判断哪些能直接在 IDE 里打开。VC 6.0 的.dsw双击就能启动 IDE,Turbo C 的.prj需要在 DOSBox 里挂载后打开。两个目录的公共部分是一些串口配置的宏定义和校验算法,作者把它们抽成了独立的头文件,两边都引用。

文件/目录作用对应编译器
*.dsw/*.dspVC 工作区与工程文件Visual C++ 6.0
*.cpp/*.hWindows 串口通信源码Visual C++ 6.0
*.rc对话框与控件资源Visual C++ 6.0
*.prjTurbo C 工程文件Turbo C 2.0/3.0
*.cDOS 串口通信源码Turbo C 2.0/3.0

2.2 VC 6.0 工程的入口与消息循环

VC 6.0 的 Windows 串口程序,入口是WinMain,但真正干活的是主对话框的DialogProc。串口数据到达时,系统会向窗口发送WM_COMMNOTIFY消息,代码在消息处理里读取缓冲区。下面这段是典型的串口初始化与消息注册逻辑,我按原工程的结构还原出来:

// 打开串口并配置参数 HANDLE hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hCom == INVALID_HANDLE_VALUE) { AfxMessageBox("打开串口失败"); return FALSE; } // 配置波特率、数据位、停止位、校验位 DCB dcb; memset(&dcb, 0, sizeof(dcb)); dcb.DCBlength = sizeof(dcb); GetCommState(hCom, &dcb); dcb.BaudRate = CBR_9600; // 波特率 9600 dcb.ByteSize = 8; // 数据位 8 dcb.Parity = NOPARITY; // 无校验 dcb.StopBits = ONESTOPBIT; // 1 位停止位 SetCommState(hCom, &dcb); // 设置缓冲区大小并注册事件通知 SetupComm(hCom, 1024, 1024); SetCommMask(hCom, EV_RXCHAR); // 只关心接收字符事件

这段代码的关键参数是DCB结构体,波特率、数据位、校验位、停止位必须和硬件端完全一致,否则收到的就是乱码。FILE_FLAG_OVERLAPPED表示异步方式,配合WaitCommEvent使用,不会阻塞界面线程。原工程里还封装了一个CSerialPort类,把CreateFile、SetCommState、ReadFile这些 API 包了一层,调用起来更顺手。

2.3 Turbo C 工程的寄存器级操作

Turbo C 那套代码更底层,直接操作 8250/16550 UART 的寄存器。DOS 下没有驱动层,串口就是几个 I/O 端口。下面这段是初始化 COM1 的典型写法:

/* COM1 基地址为 0x3F8 */ #define COM1_BASE 0x3F8 void init_serial(void) { outportb(COM1_BASE + 1, 0x00); /* 关闭中断 */ outportb(COM1_BASE + 3, 0x80); /* 使能 DLAB,准备设置波特率 */ outportb(COM1_BASE + 0, 0x0C); /* 除数低字节,9600 波特率 */ outportb(COM1_BASE + 1, 0x00); /* 除数高字节 */ outportb(COM1_BASE + 3, 0x03); /* 8 位数据,无校验,1 位停止位 */ outportb(COM1_BASE + 2, 0xC7); /* 使能 FIFO,清空缓冲区 */ outportb(COM1_BASE + 4, 0x0B); /* 设置 RTS/DSR 等握手信号 */ }

这里每个outportb对应一个寄存器偏移:+0是发送/接收缓冲,+1是中断使能,+2是 FIFO 控制,+3是线路控制,+4是调制解调器控制。DLAB 位(线路控制寄存器最高位)置 1 时,+0和+1才用来写波特率除数。9600 波特率对应的除数是 12,所以低字节写0x0C。这套代码在 DOSBox 里模拟串口时不一定能直接跑通,因为 DOSBox 的串口模拟只支持有限的几种模式,但作为学习寄存器操作的参考非常清晰。

3. 跑起来:VC 6.0 与 Turbo C 的编译环境搭建

3.1 VC 6.0 工程的编译与串口调试

VC 6.0 在 Win7 及以上系统安装时会有兼容性问题,常见做法是装一个虚拟机跑 XP,或者用兼容模式加管理员权限运行。我一般会在虚拟机里装好 VC 6.0 和 SP6 补丁,然后把工程目录挂载进去。打开.dsw后,直接按 F7 编译,如果报afxwin.h找不到,说明 MFC 库没装全,需要勾选安装选项里的 MFC 组件。

编译通过后,运行程序会弹出一个对话框,上面有串口选择、波特率设置、发送区和接收区。要验证收发是否正常,可以用一根 USB 转串口线把电脑的两个 COM 口短接,或者用虚拟串口软件建一对互联的端口。我通常用com0com这类工具建一对虚拟串口,一个给程序用,一个给串口助手用,发什么收什么一目了然。

提示:如果打开串口时提示“拒绝访问”,先检查是不是被其他程序占用了,比如串口助手没关。另外 USB 转串口线的驱动要装好,设备管理器里能看到 COM 口号才行。

3.2 Turbo C 工程的 DOSBox 运行

Turbo C 的代码需要在 DOS 环境下编译运行。现在没人真去装 DOS,用 DOSBox 挂载目录就行。把 Turbo C 的安装目录和源码目录都挂载到 DOSBox 里,进入 Turbo C 的BIN目录,运行TC.EXE,打开.prj工程文件,按F9编译,Ctrl+F9运行。

这里有个坑:DOSBox 默认的串口模拟只支持serial1=null或serial1=file这种模式,没法直接和物理串口通信。如果只是想看代码逻辑,编译运行看输出就够了;如果要实际收发,得用带串口直通功能的 DOSBox 分支,或者干脆在真实 DOS 机器上跑。我一般建议先在 DOSBox 里把编译跑通,确认代码没有语法错误,再考虑硬件对接。

3.3 串口参数配置的对应关系

两套代码虽然平台不同,但串口参数的含义是一致的。下面这张表把 VC 里的DCB字段和 Turbo C 里的寄存器值对应起来,改代码时对着看不容易错:

参数VC 6.0 DCB 字段Turbo C 寄存器操作常用值
波特率BaudRate+0/+1写除数9600 / 115200
数据位ByteSize+3低两位8
校验位Parity+3第 3 位无校验
停止位StopBits+3第 2 位1 位
流控fRtsControl+4握手信号无 / RTS/CTS

改波特率时,VC 里直接改CBR_9600为CBR_115200就行;Turbo C 里要重新算除数,115200 对应的除数是 1,低字节写0x01,高字节写0x00。除数算错,收发的就是乱码,这是最常见的翻车点。

4. 核心代码逐段拆解:收发线程与数据校验

4.1 VC 6.0 的接收线程与事件驱动

VC 6.0 工程里,串口接收通常放在一个独立线程里,用WaitCommEvent等待EV_RXCHAR事件,然后ReadFile把数据读出来。下面这段是线程函数的骨架:

UINT CSerialPort::ReceiveThread(LPVOID pParam) { CSerialPort* pPort = (CSerialPort*)pParam; DWORD dwEventMask = 0; DWORD dwBytesRead = 0; char buffer[1024]; while (pPort->m_bThreadRunning) { // 等待接收字符事件,超时 100ms 便于检查线程退出标志 if (!WaitCommEvent(pPort->m_hCom, &dwEventMask, NULL)) { continue; } if (dwEventMask & EV_RXCHAR) { // 读取串口缓冲区中的数据 if (ReadFile(pPort->m_hCom, buffer, sizeof(buffer), &dwBytesRead, NULL)) { if (dwBytesRead > 0) { // 把数据投递到主窗口,由界面线程更新显示 pPort->PostDataToUI(buffer, dwBytesRead); } } } } return 0; }

WaitCommEvent是阻塞的,所以放在线程里不会卡界面。EV_RXCHAR表示接收缓冲区里有新字符。ReadFile读到的字节数放在dwBytesRead里,可能小于缓冲区大小,这是正常的,串口数据是流式的,一次读多少取决于当前缓冲区里有多少。PostDataToUI是自定义函数,用PostMessage把数据指针传给主窗口,避免跨线程直接操作控件。

4.2 Turbo C 的查询式接收

DOS 下没有线程,Turbo C 的代码用查询方式接收:不断读线路状态寄存器的“数据就绪”位,有数据就取走。下面这段是典型的查询接收循环:

int receive_char(void) { /* 等待数据就绪,超时返回 -1 */ unsigned long timeout = 0; while (!(inportb(COM1_BASE + 5) & 0x01)) { if (++timeout > 1000000) { return -1; /* 超时,没有收到数据 */ } } /* 读取接收缓冲寄存器 */ return inportb(COM1_BASE + 0); }

inportb(COM1_BASE + 5)读的是线路状态寄存器,最低位0x01表示接收数据就绪。这个循环会一直占着 CPU,所以实际工程里通常会配合中断或者定时器来用,不会死等。原书代码里也有中断方式的版本,用setvect挂接 IRQ4 的中断服务程序,收到数据后置一个标志位,主循环检查标志位再处理。

4.3 数据校验与帧解析

串口通信最怕数据错位,所以两套代码里都有校验逻辑。常见的是累加和校验或者 CRC16。下面这段是累加和校验的实现,VC 和 Turbo C 里逻辑一样,只是语法略有差别:

// 计算从 pData 开始的 len 个字节的累加和,取低 8 位 unsigned char CalcChecksum(const unsigned char* pData, int len) { unsigned int sum = 0; for (int i = 0; i < len; i++) { sum += pData[i]; } return (unsigned char)(sum & 0xFF); }

发送时把校验和附在帧尾,接收时重新算一遍对比。如果对不上,说明传输过程中有干扰,这一帧就丢弃。原工程里还定义了帧头帧尾,比如0xAA开头、0x55结尾,中间是数据区和校验和。解析时先找帧头,再按固定长度取数据,最后验校验和。这套逻辑虽然简单,但在工业现场足够用。

5. 避坑与排查:串口调试中最容易翻车的几个点

5.1 打开串口失败,提示“拒绝访问”

现象是CreateFile返回INVALID_HANDLE_VALUE,GetLastError得到 5。原因通常是串口已经被别的程序打开,比如串口助手、调试工具没关干净。解决方法是先在设备管理器里确认串口存在,然后用任务管理器结束可能占用串口的进程,或者换一个 COM 口测试。我习惯在代码里加一个重试机制,打开失败后延时 500ms 再试两次。

5.2 收到的数据全是乱码

现象是接收区显示一堆问号或方块。原因几乎都是串口参数不匹配:波特率、数据位、校验位、停止位有一项对不上。解决方法是把两端参数打印出来逐项核对,尤其是波特率,9600 和 115200 搞混是最常见的。另外晶振频率不准也会导致波特率偏差,偏差超过 2% 就可能出错,这种情况只能换晶振或者降低波特率。

5.3 数据收一半就断了

现象是长帧数据收到一半就没了,或者偶尔丢几个字节。原因是接收缓冲区溢出,或者读取不及时。VC 里要把SetupComm的缓冲区设大一点,比如 4096 字节,并且接收线程的优先级适当提高。Turbo C 里查询方式更容易丢数据,建议改用中断方式,或者在查询循环里加inportb读多次,把 FIFO 里的数据都取出来。

5.4 编译报错“无法打开预编译头文件”

VC 6.0 工程里常见这个报错,原因是stdafx.cpp没有先编译,或者stdafx.h被改动过。解决方法是先单独编译stdafx.cpp生成.pch文件,再编译整个工程。如果还不行,在工程设置里把“使用预编译头”改成“不使用”,虽然编译慢一点,但能绕过这个问题。

5.5 DOSBox 里串口中断不触发

Turbo C 的中断方式代码在 DOSBox 里跑,中断服务程序可能永远不被调用。原因是 DOSBox 对硬件中断的模拟不完整,IRQ4 的中断向量挂接后不一定能收到。解决方法是先用查询方式验证逻辑,确认代码没问题后再上真实硬件。如果必须在 DOSBox 里测中断,可以改用轮询定时器中断的方式模拟。

6. 二次开发:把老串口代码接进现代工程

6.1 从 VC 6.0 迁移到 VS 的注意事项

如果要把 VC 6.0 的串口代码迁到 Visual Studio 2019/2022,最大的障碍是 MFC 版本差异和字符集。VC 6.0 默认用多字节字符集,新版本默认 Unicode。迁移时要么把工程属性改成“使用多字节字符集”,要么把char改成TCHAR,字符串常量用_T()包起来。串口 API 本身没变,CreateFile、ReadFile、WriteFile在新系统上照样能用。

我一般会先把串口操作部分抽成一个独立的.cpp和.h,不依赖 MFC 的CString和CWnd,改成纯 Win32 API 加回调函数。这样这个模块可以同时用在 MFC 工程、Qt 工程甚至控制台程序里。下面是一个简化的接口定义:

// 串口回调接口,收到数据时由串口线程调用 class ISerialCallback { public: virtual void OnDataReceived(const unsigned char* data, int len) = 0; }; // 串口类,封装打开、关闭、发送、接收线程 class SerialPort { public: bool Open(const char* portName, int baudRate); void Close(); bool Send(const unsigned char* data, int len); void SetCallback(ISerialCallback* cb); private: HANDLE m_hCom; ISerialCallback* m_pCallback; // ... 线程相关成员 };

这样改造后,界面层只负责显示,串口层只负责收发,职责清晰,也方便单元测试。

6.2 用现代工具验证串口逻辑

老代码没有单元测试,改起来心里没底。我的习惯是先用虚拟串口工具建一对端口,然后写一个简单的 Python 脚本模拟设备端,按协议收发数据。Python 的pyserial库几行代码就能建一个串口服务端:

import serial import time # 打开虚拟串口的另一端 ser = serial.Serial('COM2', 9600, timeout=1) while True: # 模拟设备主动上报一帧数据 frame = bytes([0xAA, 0x01, 0x02, 0x03, 0x55]) ser.write(frame) time.sleep(1)

用这个脚本配合改造后的串口模块,可以反复验证帧解析、校验和计算是否正确,不用每次都接真实硬件。等逻辑跑通了,再上真实设备联调,效率高很多。

6.3 一个具体的改造技巧:把阻塞读改成异步回调

VC 6.0 原工程里,接收线程用WaitCommEvent阻塞等待,然后ReadFile同步读。这种模式在数据量不大时没问题,但如果串口数据很密集,线程可能来不及处理。我的做法是把ReadFile也改成异步,用OVERLAPPED结构体加GetOverlappedResult,或者用 I/O 完成端口。这样接收线程只负责投递读请求,数据到了由系统通知,吞吐量能提高不少。

具体改法是:在Open时用FILE_FLAG_OVERLAPPED打开串口,然后为每次ReadFile准备一个OVERLAPPED结构体和缓冲区,调用ReadFile后立即返回,用WaitForSingleObject等待OVERLAPPED.hEvent或者用GetQueuedCompletionStatus统一处理。这个改动稍微复杂,但值得做,尤其是波特率上到 115200 以上时,同步读很容易丢数据。

从那以后我每次接手老串口代码,都强制先跑一遍虚拟串口回环测试,确认收发和校验逻辑没问题,再动业务代码。这份源代码包虽然老,但把串口通信的底层逻辑讲得很透,VC 和 Turbo C 两套实现对照着看,能少走很多弯路。希望帮到你。

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

相关新闻

从Java到Native:Frida手动Hook的完整实战流程

从Java到Native:Frida手动Hook的完整实战流程

Frida 这个系列的第一篇讲的是自动化批量 hook&#xff1a;遍历类、遍历方法、统一打点&#xff0c;能快速知道目标进程里有哪些方法在跑、参数长什么样。这种思路在做初步信息收集时效率很高&#xff0c;但真到了实战阶段&#xff0c;你会发现自动化脚本往往在几个关键点处失灵…

2026/10/19 16:30:24 阅读更多 →
OpenCV轮廓查找与绘制:从二值化到层级分析的实战攻略

OpenCV轮廓查找与绘制:从二值化到层级分析的实战攻略

做图像处理的时候&#xff0c;我经常跟朋友说一句话&#xff1a;如果你只会看像素值&#xff0c;那你看到的就是一堆数字&#xff1b;但如果你会看轮廓&#xff0c;你看到的才是一个个物体。OpenCV里最常被问到的功能之一&#xff0c;就是用Python做查找并绘制轮廓。今天不整虚…

2026/10/19 16:29:11 阅读更多 →
FineReport前端JS分类汇总:5步实现动态分组合计

FineReport前端JS分类汇总:5步实现动态分组合计

1. 为什么分类汇总这个老需求&#xff0c;会在FR里逼我写JS&#xff1f;先说个场景。你负责一张员工费用明细报表&#xff0c;数据集已经把每一笔费用都查出来了&#xff1a;部门、姓名、费用类别、金额&#xff0c;一共几千行。用户的要求听上去很简单——“在上面加一个合计&…

2026/10/19 16:29:11 阅读更多 →

最新新闻

JESD204B串行接收模块FPGA实现:从同步到仿真的完整指南

JESD204B串行接收模块FPGA实现:从同步到仿真的完整指南

简介&#xff1a;面向FPGA开发者的JESD204B高速串行接口接收模块实现代码&#xff0c;配套Vivado仿真工程&#xff0c;适合需要掌握链路同步、多通道对齐、8b/10b解码与错误检测机制的工程师学习或直接移植。压缩包共593个文件&#xff0c;约26.68MB&#xff0c;以272个txt说明…

2026/10/19 17:13:38 阅读更多 →
LangChain Tool Calling实战:从手动解析到LangGraph Agent落地

LangChain Tool Calling实战:从手动解析到LangGraph Agent落地

第一次在LangChain里跑通工具调用&#xff08;Tool Calling&#xff09;时&#xff0c;我的第一反应是&#xff1a;这不就是让模型学会"填一张调用单"吗&#xff1f;等真正把它接到业务里我才意识到&#xff0c;Tool Calling的本质是把"模型说了什么"和&qu…

2026/10/19 17:13:38 阅读更多 →
数字公关AI中台架构设计与落地实践

数字公关AI中台架构设计与落地实践

有人问我&#xff0c;数字公关是不是就是“用AI写新闻稿”&#xff1f;我说你要是这么理解&#xff0c;那这个活三个月就能干完&#xff0c;根本不需要中台。真正难的不是让模型写出一篇稿子&#xff0c;而是让舆情监测、内容生产、媒介分发、效果归因这几个环节在一套系统里持…

2026/10/19 17:13:38 阅读更多 →
专科论文写作太难?实测10款AI工具,从开题到降重全攻略

专科论文写作太难?实测10款AI工具,从开题到降重全攻略

1. 专科生论文写作的真实困境与AI工具的正确打开方式每年到了三四月份&#xff0c;我后台收到最多的私信不是“怎么找工作”&#xff0c;而是“毕业论文怎么办”。尤其是专科生群体&#xff0c;三年制也好、五年一贯制也好&#xff0c;总被毕业论文压得喘不过气。很多同学第一反…

2026/10/19 17:13:38 阅读更多 →
open-code-review:代码评审的范式迁移与CLI实践

open-code-review:代码评审的范式迁移与CLI实践

1. “open-code-review”不是工具名&#xff0c;而是正在发生的协作范式迁移你最近在 GitHub 提交 PR 后&#xff0c;是不是发现评论区里多了一行带 &#x1f916; 图标的自动回复&#xff1f;或者团队 Slack 里突然弹出一条消息&#xff1a;“feat/auth: 检测到 3 处潜在空指针…

2026/10/19 17:13:38 阅读更多 →
Kafka server.properties核心参数配置指南:生产环境生死线与性能调优

Kafka server.properties核心参数配置指南:生产环境生死线与性能调优

1. 为什么这份 server.properties 配置清单值得你逐行抄写一遍Kafka 集群不是装上就能跑稳的玩具&#xff0c;它更像一台精密调校过的工业级涡轮发动机——参数设错一个&#xff0c;轻则吞吐掉半&#xff0c;重则整个集群在凌晨三点集体“喘不上气”。我见过太多团队把 Kafka 当…

2026/10/19 17:12:37 阅读更多 →

日新闻

频率跟踪型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 阅读更多 →