蓝色港湾 发表于 2026-3-18 10:30:53

CoDeSys入门实战一起学习(二十一):联合体、长时间、宽字符串、引用、指针5种标准扩展类型,解决复杂编程问题

CoDeSys高级数据类型!
前言
在上一篇中,我们掌握了CoDeSys的5大类标准数据类型,能满足大部分基础编程需求。但在实际项目中,总会遇到一些复杂场景:

[*]如何将2个字节整合成1个字?


[*]如何实现高精度纳秒级计时?


[*]如何间接访问变量的内存地址?


[*]如何给变量起“别名”,简化复杂变量的引用?
这些问题,标准数据类型无法解决,而CoDeSys为IEC61131-3标准做的扩展数据类型,就是专门的解决方案。本文将详解5种标准扩展类型:联合体、长时间、宽字符串、引用、指针,讲透概念、用法、实战案例,让你的程序更灵活、更高效。
一、联合体(UNION):同一段内存,存储不同类型数据
核心概念
联合体是一种特殊的数据结构,允许几种不同类型的变量共用同一段内存单元——所有成员的起始内存地址相同,修改其中一个成员,其他成员的值会同步改变。简单说:一块内存,多种解读方式。
核心用途

[*]字节/字/双字的快速整合与拆分(如2个BYTE整合成1个WORD);


[*]同一份数据,按不同类型解析(如将DWORD分别解析为INT和两个BYTE);


[*]节省内存(避免为不同类型变量分配独立内存)。
声明与使用步骤

[*]新建DUT:右键Application→添加对象→DUT,选择联合体;

[*]定义联合体成员:成员可为不同类型,建议内存长度一致,避免数据错乱;
[*]程序中声明联合体变量,赋值并访问成员。
实战案例1:2个字节整合成1个字(经典用法)
第一步:新建联合体DUT,命名为Union_ByteToWord

                        TYPE Union_ByteToWord :


                        第二步:程序中声明并使用


                        // 赋值:高字节给nByte,低字节给nByte
                        // 访问整合后的字:stByteToWord.nWord = 16#1234


✅ 内存映射:nByte对应nWord的高8位,nByte对应低8位。
实战案例2:同内存不同类型解析
// 联合体DUT:DWORD分别解析为INT和两个WORD
                        TYPE Union_DwordParse :
                        UNION
                          dwData:DWORD;
                          nInt:ARRAY OF INT;
                          wWord:ARRAY OF WORD;
                        END_UNION
                        END_TYPE

                        // 赋值后,dwData、nInt、wWord共享同一段内存,修改其一,其余同步变化
二、长时间类型(LTIME):纳秒级高精度计时
核心概念
LTIME是TIME类型的高精度扩展,解决了TIME(32位,毫秒级)计时精度低、范围小的问题。

[*]TIME:32位,精度毫秒,最大71582分钟;


[*]LTIME:64位,精度纳秒,支持天、小时、分钟、秒、毫秒、微秒、纳秒,满足高精度计时需求。
核心用途

[*]高速设备的精准计时(如伺服运动、高速传感器触发);


[*]长时间高精度累计(如设备运行时长、生产节拍精准统计)。
赋值格式
以LTIME#开头,单位按d→h→m→s→ms→us→ns排序,示例:
   ltimeHighPrecision:LTIME;


三、宽字符串(WSTRING):Unicode字符处理
核心概念
WSTRING是STRING的Unicode扩展,STRING仅支持ASCII字符(单字节),而WSTRING支持全球多语言字符(如中文、日文、特殊符号),以Unicode编码存储。
核心参数

[*]存储规则:实际占用内存 = 2*定义长度+2 个字节(每个Unicode字符占2字节,额外2字节存结束符);


[*]用法:与STRING基本一致,常量仍用单引号包裹,支持中文等特殊字符。
实战案例
VAR
                          wstrCN:WSTRING := 'CoDeSys教程:数据类型详解';// 支持中文
                          wstrEN:WSTRING := 'Hello CoDeSys';
                        END_VAR
✅ 适用场景:需要显示中文故障信息、多语言设备名称的项目。
四、引用(REFERENCE TO):变量的“别名”,简化复杂引用
核心概念
引用是变量的别名,相当于给变量起了一个新名字,操作引用就等同于操作原变量——引用与原变量共享同一块内存,修改引用的值,原变量的值会同步改变。
与指针的区别(核心)

[*]引用:直接操作原变量,无需解引用,语法简单,更安全;


[*]指针:存储变量的内存地址,需解引用才能操作原变量,语法复杂,灵活性更高。
声明与使用

[*]声明格式:引用名:REFERENCE TO 数据类型;
[*]绑定原变量:引用名 := REF(原变量);(必须绑定,否则无效);
[*]校验有效性:用__ISVALIDREF(引用名)判断引用是否绑定有效变量(返回TRUE/FALSE)。
实战案例:引用的使用与有效性校验



✅ 适用场景:简化复杂变量的引用(如结构体数组的成员、深层嵌套结构体的变量)。
五、指针(POINTER TO):内存地址的“导航仪”,间接访问内存
核心概念
指针是一种特殊的变量,不存储数据本身,只存储变量的内存地址——通过指针,可间接访问任意变量的内存,实现灵活的内存操作,是CoDeSys中最灵活也最危险的扩展类型(使用不当会导致内存错误)。
核心用途

[*]动态访问变量(如根据地址动态读取/写入数据);


[*]数组的快速遍历(比下标访问更高效);


[*]共享内存访问(如PLC与第三方设备的内存交互);


[*]复杂数据结构的灵活操作(如结构体、联合体)。
核心语法

[*]声明指针:指针名:POINTER TO 数据类型;(如pInt:POINTER TO INT;);

[*]获取地址:ADR(变量名)(返回变量的内存地址,赋值给指针);

[*]解引用:指针名^(通过地址访问原变量,读/写均可);

[*]地址偏移:指针名 + 偏移量(如pByte + 1,指向内存地址的下一个字节)。
实战案例1:指针的基本使用(间接访问变量)
VAR


                        END_VAR



实战案例2:指针拆分INT为两个BYTE(经典用法)
VAR


                        END_VAR


指针的安全使用(避坑重点)
指针使用不当会导致内存越界、程序崩溃,务必做好安全校验:

[*]添加指针校验函数:右键Application→添加对象→用于隐含检查的POU,选择CheckPointer;
[*]访问指针前,先校验有效性(自定义CheckPointer函数,判断地址是否在有效范围);
[*]避免指针指向已释放的内存(如临时变量);
[*]地址偏移时,确保偏移后仍指向有效数据类型(如BYTE指针偏移1,INT指针偏移2)。
总结
标准扩展数据类型是CoDeSys解决复杂编程问题的利器,核心使用原则:

[*]内存共享/数据拆分整合:用联合体,简单高效还省内存;


[*]高精度计时:用LTIME,纳秒级精度满足高速场景;


[*]多语言字符处理:用WSTRING,支持中文等Unicode字符;


[*]简化复杂变量引用:用引用,语法简单更安全;


[*]灵活的内存间接访问:用指针,配合校验函数确保安全。
下一篇我们将进入CoDeSys数据类型的核心灵活部分——自定义数据类型,详解数组、结构体、结构体数组、枚举、子范围,这些类型能让你根据项目需求“定制”数据类型,让程序结构更清晰、更易维护,比如用结构体封装一台电机的所有参数,用枚举定义设备的运行状态,敬请期待!
页: [1]
查看完整版本: CoDeSys入门实战一起学习(二十一):联合体、长时间、宽字符串、引用、指针5种标准扩展类型,解决复杂编程问题