You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Beckhoff CX8190上TwinCAT 3文件写入问题:生成的TXT无法用NotepadCE打开

Beckhoff CX8190 TwinCAT 3 ST 文件写入问题排查与完善教程

问题描述

我在Beckhoff CX8190设备上使用TwinCAT 3 ST语言进行数据记录,发现倍福官方文档存在部分缺失。保存TXT文件后,用Windows CE 7.0预装的NotepadCE打开时弹出“无法打开文档”的错误。请帮我排查以下代码中的错误,或者提供比Beckhoff Information System更完善的文件处理教程?

原始代码

//declarations of variables
PROGRAM MAIN
VAR
    nStage          :   INT :=0;
    fbFileOpen      :   FB_FileOpen;    // open or create file
    fbFileWrite     :   FB_FileWrite;    // write to file
    fbFileClose     :   FB_FileClose;   // Close file

    sPath           :   STRING  :=  '\temp\foobar01.txt';    // target path
    sAmsNetID       :   STRING  := '5.109.203.84.1.1';
    
    nVariable       :   INT := 0;
    
    bWriteError     :   BOOL;
    bOpenError      :   BOOL;
    
    sDataToWrite    :   STRING:='All work and no play makes Jack a dull boy';
    
    nErrId          :   UDINT   :=  0;
    bError          :   BOOL    :=  FALSE;
    hDataFileRefnum :   UINT    :=  0;
END_VAR

//-----end of declaration, main code-----

CASE nStage OF
    0:  fbFileOpen(bExecute := FALSE);
        fbFileOpen  (
                    sNetId := '',
                    sPathName := sPath,
                    nMode := FOPEN_MODEWRITE OR FOPEN_MODETEXT,
                    ePath := PATH_GENERIC,
                    bExecute := TRUE
                    );
        nInc(nStage);
    
    1:  fbFileOpen(bExecute := FALSE);
        IF fbFileOpen.bBusy = FALSE AND fbFileOpen.bError = TRUE THEN
            nErrId  :=  fbFileOpen.nErrId;
            bError  :=  TRUE;
            nStage  :=  10;
        END_IF;
        IF fbFileOpen.bBusy = FALSE AND fbFileOpen.bError = FALSE THEN
            hDataFileRefnum := fbFileOpen.hFile;
            nInc(nStage);
        END_IF;
    2:  fbFileWrite( bExecute := FALSE);
        fbFileWrite (
                        sNetId      :=  sAmsNetId,
                        hFile       :=  hDataFileRefnum,
                        pWriteBuff  :=  ADR(sDataToWrite),
                        cbWriteLen  :=  SIZEOF(sDataToWrite),
                        bExecute    :=  TRUE
                    );
        nInc(nStage);
 
    3:  fbFileWrite(bExecute := FALSE); 
        IF fbFileWrite.bBusy = FALSE AND fbFileWrite.bError = TRUE THEN
            nErrId  :=  fbFileWrite.nErrId;
            bError  :=  TRUE;
            nStage  :=  10;
        END_IF
        IF fbFileWrite.bBusy = FALSE AND fbFileWrite.bError = FALSE THEN
            nInc(nStage);
        END_IF
    4:  fbFileClose( bExecute := FALSE);
        fbFileClose( sNetId := sAmsNetID, hFile := hDataFileRefnum, bExecute:=TRUE);
        IF fbFileClose.bBusy = FALSE AND fbFileClose.bError = TRUE THEN
            nErrid  :=  fbFileClose.nErrId;
            bError  :=  TRUE;
            nStage  :=  10;
        END_IF
        IF fbFileClose.bBusy = FALSE AND fbFileClose.bError = FALSE THEN
            fbFileClose.hFile   :=  0;
            nStage  :=  9;
        END_IF
    9:  (*Normal ending*)   
        nStage := nStage;
    10: nErrId;
        bError; 
END_CASE

一、代码错误排查

  1. AmsNetID参数不一致
    本地文件操作时,FB_FileOpen设为空字符串,但FB_FileWrite和FB_FileClose指定了远程AmsNetID,会导致文件访问路径无效,三个函数的sNetId应统一设为空。

  2. 写入长度计算错误
    使用SIZEOF(sDataToWrite)会写入STRING类型的全部内存空间(默认80字符),多余空字符会导致NotepadCE解析异常,应改用LEN(sDataToWrite) + 1(包含字符串终止符\0)。

  3. 状态机逻辑缺陷

    • Stage 0中直接跳转阶段,未等待FB_FileOpen完成;Stage 4同理,未等待FB_FileClose操作结束,会导致资源未正确处理。
    • 正确逻辑应在当前阶段等待bBusy变为FALSE后,再判断结果并跳转。
  4. 文件打开模式缺失
    FOPEN_MODEWRITE仅覆盖已有文件,若文件不存在则无法创建,需添加FOPEN_MODECREATE确保文件不存在时自动生成。


二、修复后的代码示例

//declarations of variables
PROGRAM MAIN
VAR
    nStage          :   INT :=0;
    fbFileOpen      :   FB_FileOpen;    // open or create file
    fbFileWrite     :   FB_FileWrite;    // write to file
    fbFileClose     :   FB_FileClose;   // Close file

    sPath           :   STRING  :=  '\temp\foobar01.txt';    // target path
    sAmsNetID       :   STRING  := ''; // 本地操作留空
    
    nVariable       :   INT := 0;
    
    bWriteError     :   BOOL;
    bOpenError      :   BOOL;
    
    sDataToWrite    :   STRING:='All work and no play makes Jack a dull boy';
    
    nErrId          :   UDINT   :=  0;
    bError          :   BOOL    :=  FALSE;
    hDataFileRefnum :   UINT    :=  0;
END_VAR

//-----end of declaration, main code-----

CASE nStage OF
    0:  fbFileOpen(
                sNetId := sAmsNetID,
                sPathName := sPath,
                nMode := FOPEN_MODECREATE OR FOPEN_MODEWRITE OR FOPEN_MODETEXT,
                ePath := PATH_GENERIC,
                bExecute := TRUE
            );
        // 等待打开操作完成
        IF fbFileOpen.bBusy = FALSE THEN
            IF fbFileOpen.bError THEN
                nErrId  :=  fbFileOpen.nErrId;
                bError  :=  TRUE;
                nStage  :=  10;
            ELSE
                hDataFileRefnum := fbFileOpen.hFile;
                nInc(nStage);
            END_IF;
            fbFileOpen(bExecute := FALSE); // 重置执行信号
        END_IF;
    
    1:  fbFileWrite (
                sNetId      :=  sAmsNetID,
                hFile       :=  hDataFileRefnum,
                pWriteBuff  :=  ADR(sDataToWrite),
                cbWriteLen  :=  LEN(sDataToWrite) + 1, // 包含终止符
                bExecute    :=  TRUE
            );
        // 等待写入操作完成
        IF fbFileWrite.bBusy = FALSE THEN
            IF fbFileWrite.bError THEN
                nErrId  :=  fbFileWrite.nErrId;
                bError  :=  TRUE;
                nStage  :=  10;
            ELSE
                nInc(nStage);
            END_IF;
            fbFileWrite(bExecute := FALSE); // 重置执行信号
        END_IF;
 
    2:  fbFileClose( sNetId := sAmsNetID, hFile := hDataFileRefnum, bExecute:=TRUE);
        // 等待关闭操作完成
        IF fbFileClose.bBusy = FALSE THEN
            IF fbFileClose.bError THEN
                nErrid  :=  fbFileClose.nErrId;
                bError  :=  TRUE;
                nStage  :=  10;
            ELSE
                fbFileClose.hFile   :=  0;
                nStage  :=  9;
            END_IF;
            fbFileClose(bExecute := FALSE); // 重置执行信号
        END_IF;
    9:  (*Normal ending*)   
        nStage := nStage;
    10: // 可添加错误日志、报警等处理逻辑
END_CASE

三、完善的TwinCAT 3 ST文件处理教程

1. 本地文件操作核心规则

  • AmsNetID设置:本地操作时所有文件函数sNetId必须为空,否则会访问远程设备文件。
  • 打开模式组合:
    • 新建/覆盖文件:FOPEN_MODECREATE OR FOPEN_MODEWRITE OR FOPEN_MODETEXT
    • 追加日志:FOPEN_MODECREATE OR FOPEN_MODEAPPEND OR FOPEN_MODETEXT
  • 写入长度:STRING类型用LEN(str) + 1,避免写入多余空字符;字节数组直接用数组长度。
  • 状态机规范:每个文件操作必须等待bBusy为FALSE后再进行下一步,禁止直接跳转阶段。

2. Windows CE文件兼容性注意事项

  • 换行符要求:NotepadCE仅识别\r\n作为换行符,写入多行文本时需手动添加,例如:sData := '第一行' + '\r\n' + '第二行';
  • 编码限制:确保写入ASCII或UTF-8编码文本,避免使用非标准编码导致解析失败。
  • 目录验证:提前确认目标目录存在(如\temp),可通过远程桌面查看设备文件系统。

3. 错误排查技巧

  • 查看TwinCAT日志:在System Manager中查看实时日志,通过nErrId查询详细错误原因。
  • 权限检查:CX8190默认\temp目录可写,其他目录需确认权限配置。
  • 文件验证:通过远程桌面下载文件到PC,用记事本打开确认内容是否正常,排除设备端编辑器问题。

内容的提问来源于stack exchange,提问作者Mirek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:05:32