Cx-Programmer中ST语言编程实战:从梯形图到结构化文本

在Cx-Programmer里用ST语言写PLC程序,这事我做了好几年了。刚开始从梯形图转过来时,我也觉得那一片文本没有梯形图直白,可真到了数据处理密集、逻辑分支多的场合,梯形图的线圈和触点堆在一起,改一行要翻好几页,ST的优势一下就出来了。这篇文章不打算讲那种通篇堆砌概念的教材内容,就把我在Cx-Programmer里实际创建ST程序、写逻辑、编译调试的经验拆开讲:哪些语法必须注意、功能块怎么和梯形图配合、编译报错怎么快速定位。无论你是刚接触结构化文本的新手,还是长期用梯形图想拓展技能的老工程师,都可以参考。

1. 为什么在Cx-Programmer里我会推荐用ST语言

1.1 Cx-Programmer的编程语言生态里,ST排在什么位置

Cx-Programmer支持IEC 61131-3标准下的多种编程语言:梯形图、指令表、结构化文本(ST)、顺序功能图(SFC)。实际项目里用得最多的是梯形图,这是事实,因为梯形图直观,现场维护的时候电工师傅也看得懂。但IEC标准里定义ST语言,本来就不是为了取代梯形图,而是为了补上梯形图不擅长的短板。

梯形图的本质是图形化表达开关逻辑,触点串联并联、线圈输出,一眼看过去很清楚。但遇到复杂计算、数组处理、循环遍历、协议解析这类任务,图形化的表达方式就显得特别笨重。比如要算一组数据的平均值,梯形图可能得拉好几行比较和运算指令,可读性很差;换成ST,一个FOR循环加上几行赋值语句就写完了,别人看代码时也能很快理解。

ST在Cx-Programmer里的定位,就是“高级语言工具”。它允许你用类似Pascal或C语言的结构化写法组织逻辑,支持变量声明、条件分支、循环、功能块调用。它不是万金油,但确实是很锋利的一把刀。我现在遇到稍微复杂的项目,基本上都是梯形图和ST混合着用,什么时候用哪个,后面专门展开说。

1.2 ST真正擅长的典型任务

结合我自己的项目经验,下面几类场景在Cx-Programmer里用ST写会舒服很多。

第一类,批量模拟量处理。设备上有十几路甚至几十路温度、压力、流量信号,每路都要做工程量换算、滤波、超限报警判断。用梯形图的话,每一路的处理逻辑都要复制一遍,改滤波系数得改十几处;用ST的话,把传感器数据放到数组里,一个循环就处理完了,想改参数就改一处。

第二类,配方与参数管理。多品种设备的配方参数往往几十上百个,需要按产品号切换,把一组配方数据从数据块搬到工作区。这种批量数据搬移和结构体赋值,梯形图写起来非常痛苦,ST里一个FOR循环或者一条结构体赋值就搞定。

第三类,通信协议解析。和变频器、仪表、扫码枪做串口或总线通信时,收到的报文是一串字节,要解析帧头、命令字、数据段、校验和。这种按字节处理的逻辑,梯形图很难下手,ST可以像写高级语言一样把缓冲区拆开处理。

第四类,状态机逻辑。设备有一个动作流程,比如上料、定位、夹紧、加工、松开、退回,每一步有进入条件、执行动作、超时保护。ST里的CASE语句,天生就是写状态机的好工具,每个状态一目了然,比梯形图的步进继电器方案清晰得多。

1.3 梯形图与ST的配合边界

我现在的习惯是,安全逻辑和操作逻辑用梯形图,计算和数据处理用ST。比如急停回路、门锁联锁、手动自动切换,这些必须让现场维护人员一眼能看懂的地方,用梯形图;故障原因判断、模拟量换算、参数匹配这类藏在背后的逻辑,用ST。

举个例子。一台设备的手动模式,按钮按下就启动电机,梯形图里就是触点串线圈,清清楚楚;但按下启动按钮之后,设备要判断当前温度是否在允许范围、气压是否足够、前一个工位是否已经让出位置,这三个条件还要经过滤波和迟滞处理,再决定电机能不能转。这部分判断逻辑放梯形图里会很乱,放ST里只需要一个IF条件判断,或者一个功能块的输入输出计算。

这样搭配的好处是,现场看梯形图时看到的是“按下启动按钮,满足综合条件后启动电机”,背后的综合条件哪里算出来的,在ST里查;改计算逻辑时,不用去梯形图里翻继电器,直接在ST里改算法,两边都不折腾。

2. 从零创建一个可运行的ST程序

2.1 新建ST程序单元的最小操作路径

在Cx-Programmer里新建ST程序,操作不算复杂,但有几个地方容易踩坑。

打开工程树,找到目标PLC节点下的“程序”目录,右键选择插入程序。弹出的对话框里会让你选语言类型,这里选择“结构化文本(ST)”,然后给程序起个名字。程序名不要跟PLC里的全局符号、I/O注释重名,这个我吃过亏,编译的时候一堆人查不出来为什么符号冲突,最后发现是名字撞了。

新建完之后,编辑器窗口会变成一个文本编辑区。ST程序和梯形图程序不一样,梯形图是图形化拖拽的,ST就是纯文本输入。代码从变量声明开始写,写完逻辑之后,点编译按钮检查语法。

还有一点要注意,Cx-Programmer的不同版本、不同CPU机型,对ST的支持程度有差别。老一点的软件版本或者入门级CPU,可能只在程序类型里允许梯形图,选不了ST。新建之前先确认一下目标机型支持不支持ST,别辛辛苦苦写完了,下载时才发现机型不支持。

2.2 变量声明:分清VAR、VAR_INPUT和VAR_OUTPUT

ST代码的第一部分,是变量声明。在Cx-Programmer的ST程序里,最常用的声明区是VAR和END_VAR之间的内容。这样写:

VAR nCount : INT; fValue : REAL; bDone : BOOL; tDuration : TIME; END_VAR

这里的nCount、fValue这些变量,是这个ST程序内部的局部变量,只在当前程序里有效。每个变量后面是冒号加数据类型,整行以分号结束。

如果你在写功能块,这时候变量的分类更讲究。功能块的输入接口用VAR_INPUT声明,输出接口用VAR_OUTPUT声明,内部中间量用VAR声明。普通程序里一般不强制分输入输出,但功能块必须分清楚,因为梯形图调用功能块时,看的就是这几个接口。

还有一个很重要的概念:全局变量。在Cx-Programmer的符号表里定义的全局变量,ST代码里可以直接用,不用再在VAR里声明。比如你在符号表里定义了一个全局BOOL变量叫StartSignal,ST里直接写IF StartSignal THEN就行。但是,如果ST里声明了一个和全局变量同名的局部变量,局部变量会覆盖全局变量,这个优先级容易把人搞晕,建议尽量避免同名。

2.3 数组、结构体与数据类型转换

ST处理批量数据的核心能力,来自数组和结构体。

数组声明的基本格式是:

VAR arrTemp : ARRAY[0..15] OF REAL; END_VAR

这样声明了一个下标从0到15、共16个元素的REAL数组。使用时直接赋值:arrTemp[0] := 25.5;。在ST循环里遍历数组,比梯形图逐个复制不知道高到哪里去了。

结构体在Cx-Programmer里,需要在工程的数据类型管理器里先建好类型,然后在ST里引用。比如定义一个表示三维坐标的结构体类型PositionType,包含X、Y、Z三个REAL字段,然后在ST里声明变量:

VAR currentPos : PositionType; END_VAR

使用时写currentPos.X := 100.0;。结构体很适合管理一组相关数据,比如一个轴的位置、速度、加速度、跟随误差,打包成一个结构体变量,整个功能块传参都方便。

数据类型转换这块,ST里经常踩坑。INT和REAL不能直接随便混用,比如把一个INT变量赋给REAL变量,或者INT除以INT想得到小数,编译时会报类型不匹配。这时候需要显式转换:

nInt := REAL_TO_INT(fValue); fValue := INT_TO_REAL(nInt);

把REAL转INT的时候,要注意精度问题。不同版本对取整规则处理有细微差别,涉及关键控制量时,先拿几个边界值实测一下,再决定用不用这种方式。

3. ST核心语法逐个过

3.1 赋值、比较与运算符:别把=和:=搞混

ST里赋值操作符是:=,比较操作符是=。这跟C语言完全不一样,新手最容易在这里翻车。写赋值时少写一个冒号,编译直接报错;更隐蔽的是,你可能本来想写比较,结果写了赋值,逻辑上不对还编译能过。

正确的用法是这样:

fOutput := fInput * 2.0; (* 赋值 *) IF nMode = 1 THEN (* 比较 *) bFlag := TRUE; END_IF;

ST的逻辑运算符是AND、OR、NOT、XOR,不是C语言里的&&、||、!。多条件判断时,可以这样写:

IF bEnable AND NOT bFault THEN runMotor := TRUE; END_IF;

数学函数可以直接调用,比如ABS、SQRT、SIN、COS。计算平方根直接写SQRT(x),绝对值写ABS(x)。这些函数在Cx-Programmer的ST里是内置的,不用额外导入。

实数比较有一个经典坑:两个浮点数直接判等,很可能因为精度问题永远不成立。比如计算结果是1.0,但实际存储可能是0.99999999。安全做法是比较差值:

IF ABS(fValue - 1.0) < 0.001 THEN bValid := TRUE; END_IF;

这种做法在做模拟量阈值判断时非常实用,相当于加了一个死区。

3.2 条件分支:IF与CASE怎么选

IF语句处理的是“条件是否成立”的分支,适合条件不多、每个条件优先级不同的场景:

IF bEnable AND nMode <> 0 THEN nResult := 10; ELSIF bSecond THEN nResult := 20; ELSE nResult := 0; END_IF;

注意ELSIF的拼写,不是ELSEIF,这个拼错也是常见报错原因。

CASE语句则适合对同一个变量的不同取值做分发,尤其是状态机。写法是这样:

CASE nStep OF 0: bIdle := TRUE; 1: bRun := TRUE; 2, 3: bReady := TRUE; ELSE bAlarm := TRUE; END_CASE;

CASE后面的表达式只能是整数类型或枚举类型,不能是REAL。分支值可以用逗号并列多个,比如上例里的2, 3。我强烈建议每个CASE都写上ELSE兜底,否则万一跑到没定义的分支,输出状态会保持上一个周期的值,容易出问题。

什么时候用IF,什么时候用CASE?我的经验是:条件超过两三个、而且都是针对同一个变量的取值,优先CASE;条件是不同变量的组合判断,用IF。比如“温度过高或压力不足且不在手动模式”这种复合条件,只能IF。

3.3 循环结构:FOR与WHILE的正确用法

FOR循环适合次数确定的遍历:

FOR i := 0 TO 15 DO arrFilter[i] := arrRaw[i] * 0.9 + arrFilter[i] * 0.1; END_FOR;

这条代码就是对一个16元素的数组做一阶低通滤波,梯形图写这样的逻辑起码要几十条指令。

FOR循环还支持步长。比如把一个数组的每个元素往后移一位,方便做历史数据记录:

FOR i := 15 TO 1 BY -1 DO arrData[i] := arrData[i - 1]; END_FOR;

这里的BY -1表示每次减1,是IEC标准ST的写法。

WHILE循环用于次数未知、靠条件退出的场景:

WHILE nPos < 32 DO bBuffer[nPos] := pattern; nPos := nPos + 1; END_WHILE;

说一个极其重要的坑:ST里的循环是在PLC扫描周期内执行的,不像电脑上跑程序那样有独立的时间片。如果在Cx-Programmer里写了一个没有退出条件的死循环,整个扫描周期会被卡住,PLC的看门狗超时,CPU直接报警停机。这个后果很严重,现场生产会被打断。

所以写WHILE循环,一定要确保退出条件在有限步骤内必然满足,最好再加上安全上限:

nGuard := 0; WHILE nPos < 32 AND nGuard < 100 DO bBuffer[nPos] := pattern; nPos := nPos + 1; nGuard := nGuard + 1; END_WHILE;

这样即使逻辑有意外,循环也不会无限执行下去。

3.4 在ST中调用定时器TON和计数器CTUD

定时器在ST里的用法,跟梯形图差别很大。梯形图里TON是一个指令块,用触点驱动;ST里它变成了一个功能块实例,你要先声明实例,再按函数调用的方式调它。

声明定时器实例:

VAR fbDelay : TON; bDelayDone : BOOL; etDelay : TIME; END_VAR

调用方式:

fbDelay(In := bInput, Pt := T#2s, Q => bDelayDone, ET => etDelay);

这里In是触发条件,Pt是预设时间,T#2s表示2秒。Q是定时器的输出,ET是当前计时值。用=>把功能块的输出接到变量上。引脚名的大小写,不同版本显示可能有细微差别,以你工程里实际显示的为准,常见写法是In、Pt、Q、ET。

有一个我踩过的坑:定时器在ST里不能像梯形图那样看到定时器触点,你必须用Q输出的BOOL变量去写后续逻辑。还有,如果In一直为TRUE,定时器计时到之后不会自动复位,它会保持Q为TRUE,直到In变成FALSE。用定时器做报警延时、启动延时,一定要想清楚复位条件。

计数器也是同样思路。声明一个CTUD实例,然后调用:

fbCount(CU := bUp, CD := bDown, R := bReset, PV := 100, Q => bOver, CV => nCurrent);

CU是加计数触发,CD是减计数触发,R是复位,PV是预设值,Q是到达预设值输出,CV是当前值。功能块实例名在整个PLC里要唯一,不同程序段不能共用同一个实例名。

举个比较完整的综合例子,一个带超时保护的两步启动流程:

CASE nStep OF 0: IF bStart THEN nStep := 1; fbDelay(In := FALSE, Pt := T#5s, Q => bTimeUp, ET => etTime); END_IF; 1: fbDelay(In := TRUE, Pt := T#5s, Q => bTimeUp, ET => etTime); IF bTimeUp THEN nStep := 2; END_IF; 2: bFinish := TRUE; END_CASE;

注意在步骤0里面已经把定时器的In置为FALSE,所以当进入步骤1时,定时器是从零开始计时的。如果不在步骤切换时复位定时器,超时输出可能直接就为TRUE,状态机会瞬间跳变,这是ST写状态机最常见的隐形BUG。

4. 功能块封装与梯形图协作

4.1 用ST写一个功能块:声明接口是第一步

功能块是ST语言里复用性最强的组件。在Cx-Programmer里,右键工程树下的“功能块”节点,选择插入功能块,名称比如FB_MotorCtrl,语言选ST。

功能块编辑器里,通常分接口声明区、变量声明区和逻辑代码区。接口区的VAR_INPUT是外部输入,VAR_OUTPUT是外部输出,VAR是内部变量。比如写一个电机控制功能块:

VAR_INPUT bRunCmd : BOOL; bFault : BOOL; END_VAR VAR_OUTPUT bRunning : BOOL; bError : BOOL; END_VAR VAR fbDelay : TON; bDelayDone : BOOL; END_VAR

逻辑部分可以这样写:

IF bRunCmd AND NOT bFault THEN bRunning := TRUE; bError := FALSE; ELSE bRunning := FALSE; bError := bFault; END_IF;

接口声明为什么重要?因为功能块封装的就是对外契约。别人调用这个功能块时,只看到输入引脚和输出引脚,内部怎么写完全不影响外面的逻辑。这样写出来的代码,可以像搭积木一样复用到多个设备上。

4.2 在梯形图里挂接ST功能块

ST功能块写好了,不一定全部逻辑都在ST里写。很多时候,你需要在梯形图里调用这个ST功能块,把按钮、传感器信号接进去,把输出接给接触器、指示灯。

操作方式不复杂:从功能块列表里把FB_MotorCtrl拖到梯形图的某一条回路上,然后给它起一个实例名,比如Motor1。实例名是这个功能块在项目里的具体身份,同一个功能块类型可以创建多个实例,每个实例的内部变量互相独立。就像同一张图纸,造了多台机器,每台机器都有自己的状态。

拖进梯形图之后,功能块会显示成带引脚的一个方块。把输入引脚bRunCmd连接到启动按钮的常开触点,bFault连接到故障信号,输出引脚bRunning连接电机接触器线圈,bError连接故障指示灯。连接时要注意引脚类型,BOOL引脚接BOOL量,如果接错类型,编译会报错。

功能块内部如果用了定时器,定时器的实例要声明在功能块的VAR区,而不是放在全局。这样可以保证每个电机实例有自己独立的定时器,互不影响。

4.3 内置函数与自建函数的使用

Cx-Programmer的ST内置了一批常用函数,可以直接调用:类型转换的INT_TO_REAL、REAL_TO_INT,数学计算的ABS、SQRT、MIN、MAX,还有比较和限幅的LIMIT函数。这些函数返回单一值,不需要声明实例,随用随调,非常方便。

比如要把一个模拟量从0到10V的原始值转换成0到100的百分比,可以直接写:

fPercent := LIMIT(0, (fVoltage - 0.0) / 10.0 * 100.0, 100);

LIMIT函数接收三个参数,下限、原值、上限,返回值会被限制在这两个界限之间。做模拟量处理时防止数值越界,很好用。

如果你用的Cx-Programmer版本支持自定义函数,也可以自己写。函数和功能块的区别是,函数没有内部记忆,同样输入永远得到同样输出,适合做纯计算。结构大致是这样:

FUNCTION FC_Scale VAR_INPUT fRaw : REAL; fMin : REAL; fMax : REAL; END_VAR VAR END_VAR FC_Scale := (fRaw - fMin) / (fMax - fMin) * 100.0; END_FUNCTION

调用的时候直接函数名加名字参数:

fPercent := FC_Scale(fRaw := 1.5, fMin := 0.0, fMax := 5.0);

自定义函数在版本兼容性上不如功能块稳,如果你只需要封装一段计算逻辑,而且不想折腾函数模板的格式,直接用功能块也行。功能块还允许你保留内部状态,做滤波、累计这类需要记忆的计算反而更灵活。

5. 编译错误与调试实战

5.1 我工作中常见的四类编译错误

ST编译报错,看多了之后会发现就那么几类。我整理成了一张速查表:

错误原因典型表现解决办法
赋值写成=编译报赋值语法错误赋值一律用:=
变量未声明或拼写不一致报未定义符号,代码里找不到对应声明检查变量名、大小写、全局符号是否一致
类型不匹配报表达式类型错误,比如INT赋给REAL用INT_TO_REAL或REAL_TO_INT显式转换
语句结尾没写分号/括号不匹配报语法错误,定位到某一行附近补分号、核对括号配对
CASE分支值类型不符编译直接提示CASE类型错误确保CASE表达式和分支值都是整数类型

还遇到过一种情况,报错行号跟实际问题对不上。比如嵌套了好几层IF和CASE,编译器只把错误定位到某个END_IF附近,实际上真正写错的地方在几十行前面。这时候不要死盯着报错行,往上一段一段看,尤其是检查每个赋值语句有没有漏写分号、每个END_IF是不是配对。

5.2 在线监视与强制变量的调试思路

Cx-Programmer对ST的在线调试,没有高级语言那种断点单步的功能,但基础的在线监视是有的。程序下载后进入监视模式,ST编辑器里能看到每个变量的当前值。不过一次看很多变量不太方便,我一般把关键输出变量添加到监视窗口,或者直接在程序里建立一个调试用的临时变量,把它们收到一个数组里,方便一起观察。

更实用的方法是强制变量。找到问题后,给某个输入条件强制成TRUE或FALSE,或者给某个数值强制成特定值,然后观察后续逻辑的输出变化。比如怀疑温度报警阈值判断有问题,就直接把温度变量强制到阈值附近,看报警输出是不是正确翻转。

还有一个土办法,我管它叫探针变量。在ST里临时加一个INT变量,每扫描周期加1,下载运行后观察它是否在持续增长。如果探针变量增长正常,说明程序在正常扫描循环,问题出在逻辑本身;如果探针变量不动了,说明某个分支或者循环可能把扫描卡住了。排查ST程序卡死问题,这个办法特别有效。查完记得把探针变量删掉。

5.3 扫描周期、任务类型与ST代码的性能原则

ST代码是在PLC的周期任务里执行的,一个扫描周期内,代码从第一行执行到最后一行,然后又开始下一轮。这就带来几个需要注意的点。

第一,循环次数一定要控制。ST里写个FOR循环遍历一千个元素,如果每个周期都从头到尾跑一遍,扫描周期会被明显拉长,影响整体响应。处理大规模数据时,我习惯分批做。比如128个数据分8批,每周期处理16个,用一个批次计数器记录当前处理到哪一组,这样一个周期里ST只跑一小部分,扫描周期波动小很多。

第二,中断任务里的ST要特别精简。Cx-Programmer支持把程序挂到中断任务下,中断程序里的代码执行频率高,不适合做数组循环、大批量计算,更不能调用耗时长的功能块。中断里最好只做输入捕捉、输出置位复位这类短小操作,其他繁重计算放到周期任务里做。

第三,ST里不能有动态内存分配、不能有无限等待,所有逻辑必须在一个扫描周期内有明确的进出口。写代码的时候要时刻记住,这个程序每几十毫秒就要从头到尾跑一遍,跟PC上跑一次就结束的控制台程序完全不同。

我之前遇到过一次CPU看门狗超时,最后定位到就是WHILE循环里的退出条件因为一个变量被误修改,导致循环退不出来,整个PLC扫描周期被拖死。从那以后,我写ST循环一律加保护上限,宁可在逻辑上多写两行,也不想再让现场冒一次停机的风险。

功能块里的状态变量、定时器实例,也都消耗CPU内部资源,数量不是越多越好。项目里如果需要上百个功能块实例,要考虑CPU的内存容量和扫描周期要求,别把资源用满。

另外说一个在线修改的习惯。Cx-Programmer支持在线修改程序,但ST代码的在线修改限制比梯形图严格,改动量大时可能会要求重新下载整个程序。重新下载意味着PLC停机,现场如果有生产任务,一定要提前确认停机窗口。我在现场都是先在离线工程里把ST代码改好、编译通过、模拟验证过,再挑设备空闲时段下载。

关于ST语言和Cx-Programmer的配合,我最后再分享一个个人习惯:拿到一个新的ST程序段,我会先搭一个能编译的空骨架,包括变量声明和一条最简赋值语句,编译通过后再一点一点往里面填逻辑。每填一小段就编译一次,让错误暴露得越早、越小,后面排查越省力。这种习惯看起来慢,实际效率比憋一个大块头再编译高得多。Cx-Programmer的ST编辑器有语法高亮,但行号提示偶尔会偏差,真出错时宁可手动对照源代码,也别完全依赖错误跳转。

ST在Cx-Programmer里,说到底是为了解决梯形图不擅长的那些问题。我的原则很明确:安全回路和操作习惯相关的逻辑留在梯形图里,计算、数组、状态机、协议解析这些交给ST。用熟了之后你会发现,复杂逻辑写起来舒服,维护起来也清楚。希望这些经验能帮你少走点弯路。

相关新闻

自动驾驶黄埔军校:4500人培养体系与行业技术扩散

自动驾驶黄埔军校:4500人培养体系与行业技术扩散

在自动驾驶这行混久了&#xff0c;你会发现一个很有意思的现象&#xff1a;圈子里提到“黄埔军校”四个字&#xff0c;大家不用解释就知道说的是哪家。前阵子跟几个老朋友闲聊&#xff0c;有人随口说了句“现在从那儿出来的&#xff0c;加起来得有4500人了”&#xff0c;在场的…

2026/10/21 2:00:38 阅读更多 →
十分钟看懂 RuoYi-Vue-Plus:这套分布式多租户后台管理系统值不值得选型?

十分钟看懂 RuoYi-Vue-Plus:这套分布式多租户后台管理系统值不值得选型?

十分钟看懂 RuoYi-Vue-Plus&#xff1a;这套分布式多租户后台管理系统值不值得选型&#xff1f; 【免费下载链接】RuoYi-Vue-Plus 多租户后台管理系统 重写RuoYi-Vue所有功能 集成 Sa-Token、Mybatis-Plus、WarmFlow、SpringDoc、Hutool、OSS 定期同步 项目地址: https://git…

2026/10/21 2:00:38 阅读更多 →
大厂AI超节点硬件形态与HBD电互联设计实战解析

大厂AI超节点硬件形态与HBD电互联设计实战解析

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

2026/10/21 2:00:38 阅读更多 →

最新新闻

Quartz动态设置并发数量

Quartz动态设置并发数量

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

2026/10/21 2:48:00 阅读更多 →
AI Agent ROI评估指南:从成本结构到收益测算全解析

AI Agent ROI评估指南:从成本结构到收益测算全解析

1. 先别急着算账&#xff0c;想清楚AI Agent的ROI和传统IT项目有什么不同这两年不少公司都开始折腾AI Agent&#xff0c;有的把它接到客服系统&#xff0c;有的让它帮着写代码&#xff0c;还有的用它处理合同和报表。但当你真坐下来算这笔账时&#xff0c;会发现一个尴尬的问题…

2026/10/21 2:48:00 阅读更多 →
基于卷积神经网络的食物图像识别实战:从ResNet迁移学习到部署

基于卷积神经网络的食物图像识别实战:从ResNet迁移学习到部署

简介&#xff1a;基于卷积神经网络的食物图像识别项目完整代码与数据包&#xff0c;面向具备Python基础并希望实践CNN图像分类的开发者与学习者。资源围绕TensorFlow与tf.keras构建食物识别模型&#xff0c;涵盖数据预处理、网络定义、训练评估与预测全流程&#xff0c;并引入迁…

2026/10/21 2:48:00 阅读更多 →
SECS-II/HSMS调试工具实战:从协议原理到模拟器应用

SECS-II/HSMS调试工具实战:从协议原理到模拟器应用

简介&#xff1a;面向半导体制造与MES系统集成场景&#xff0c;这份SECS-II HSMS调试工具模拟器适合设备工程师、上位机开发人员使用。它可模拟客户端与服务端&#xff0c;用于验证自定义程序是否符合SECS-II通信标准&#xff0c;减少现场联调时的错误与返工。压缩包为rar格式&…

2026/10/21 2:48:00 阅读更多 →
eNSP校园网拓扑设计实战:VLAN划分、DHCP配置与静态路由全解析

eNSP校园网拓扑设计实战:VLAN划分、DHCP配置与静态路由全解析

简介&#xff1a;面向计算机网络期末设计、课程设计及eNSP仿真练习的完整项目资料包&#xff0c;围绕某中学校园网络拓扑设计展开。方案包含网络拓扑选型、综合布线系统规划、教学楼/行政楼/宿舍接入设计&#xff0c;以及VLAN划分、IP地址分配、路由协议配置等模拟配置要点&…

2026/10/21 2:48:00 阅读更多 →
思科模拟器6.2:从安装到避坑的完整实战指南

思科模拟器6.2:从安装到避坑的完整实战指南

简介&#xff1a;这是一份思科模拟器6.2安装包&#xff0c;官方名称为Packet Tracer&#xff0c;面向网络技术学习者、思科认证考生以及开展网络实验教学的教师。软件以图形化方式搭建虚拟网络环境&#xff0c;可模拟路由器、交换机、无线接入点、防火墙等设备&#xff0c;支持…

2026/10/21 2:47:00 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →