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
一、代码错误排查
AmsNetID参数不一致
本地文件操作时,FB_FileOpen设为空字符串,但FB_FileWrite和FB_FileClose指定了远程AmsNetID,会导致文件访问路径无效,三个函数的sNetId应统一设为空。写入长度计算错误
使用SIZEOF(sDataToWrite)会写入STRING类型的全部内存空间(默认80字符),多余空字符会导致NotepadCE解析异常,应改用LEN(sDataToWrite) + 1(包含字符串终止符\0)。状态机逻辑缺陷
- Stage 0中直接跳转阶段,未等待
FB_FileOpen完成;Stage 4同理,未等待FB_FileClose操作结束,会导致资源未正确处理。 - 正确逻辑应在当前阶段等待
bBusy变为FALSE后,再判断结果并跳转。
- Stage 0中直接跳转阶段,未等待
文件打开模式缺失
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
相关产品推荐
相关产品推荐

