记得论坛有人问,字节值如何转换成ASCII码,周末写了个小东西,主要实现转换字节值为基本ASCII码。
基本ASCII码见下图
![](/club/bbs/upload/image/20240513/6385122022836894425765875.png)
可以划分为两大类,蓝色框内的可称为“控制符号”,余下的可称为“可打印符号”。
最方便的实现,便是查表法。
首先,新建对应的PLC 数据类型,typeControl,typePrintable,typeAscii。
![](/club/bbs/upload/image/20240513/6385122395584281727524023.png)
其次,使用PLC数据类型在DB中构建ASCII表
![](/club/bbs/upload/image/20240513/6385122411510230642213216.png)
最后,编写功能FC"ByteToAscii",并调用。
![](/club/bbs/upload/image/20240513/6385122430523066051197474.png)
![](/club/bbs/upload/image/20240513/6385122633261947671005287.png)
注意事项:
在使用元素类型为string的数组时,如果能指定string长度时则尽量指定其长度,避免如下图中的错误
![](/club/bbs/upload/image/20240513/6385122602987762144852706.png)
结语:
程序仓促而就,有不妥之处,欢迎指正。
源代码:
TYPE "typeControl"
VERSION : 0.1
STRUCT
"Char" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String[3] := ' ';
END_STRUCT;
END_TYPE
TYPE "typePrintable"
VERSION : 0.1
STRUCT
"Char" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Char := ' ';
END_STRUCT;
END_TYPE
TYPE "typeAscii"
VERSION : 0.1
STRUCT
ControlChar1 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..31] of "typeControl" := [('NUL'), ('SOH'), ('STH'), ('ETX'), ('EOT'), ('END'), ('ACK'), ('BEL'), ('BS'), ('HT'), ('LF'), ('VT'), ('FF'), ('CR'), ('SO'), ('SI'), ('DLE'), ('DC1'), ('DC2'), ('DC3'), ('DC4'), ('NAK'), ('SYN'), ('ETB'), ('CAN'), ('EM'), ('SUB'), ('ESC'), ('FS'), ('GS'), ('RS'), ('US')];
PrintableChar { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[32..126] of "typePrintable" := [(' '), ('!'), ('"'), ('#'), ('$$'), ('%'), ('&'), ('$''), ('('), (')'), ('*'), ('+'), (','), ('-'), ('.'), ('/'), ('0'), ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9'), (':'), (';'), ('<'), ('='), ('>'), ('?'), ('@'), ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'), ('O'), ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'), ('V'), ('W'), ('X'), ('Y'), ('Z'), ('['), ('\'), (']'), ('^'), ('_'), ('`'), ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'), ('o'), ('p'), ('q'), ('r'), ('s'), ('t'), ('u'), ('v'), ('w'), ('r'), ('s'), ('t'), ('{'), ('|'), ('}'), ('~')];
ControlChar2 { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[127..127] of "typeControl" := [('DEL')];
END_STRUCT;
END_TYPE
FUNCTION "ByteToAscii" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
original : Byte; // range from 0~255; legel range 0~127
asciiTable : "typeAscii";
END_VAR
VAR_OUTPUT
Error : Word;
conversion : String;
END_VAR
VAR_TEMP
tempIndex : DInt;
tempAsciiTable : "typeAscii";
tempError : Word;
tempConversion : String;
END_VAR
VAR CONSTANT
UPPER_OVERFLOW : Word := 16#8F01;
LOWER_OVERFLOW : Word := 16#8F02;
NO_ERROR : Word := 16#0;
MIN_CONTROL : DInt := 16#0;
MAX_CONTROL : DInt := 16#7F;
MIN_PRINTABLE : DInt := 16#20;
MAX_PRINTABLE : DInt := 16#7E;
US_CONTROL_CHAR : DInt := 16#1F;
EMPTY_STRING : String;
END_VAR
BEGIN
REGION BLOCK INFO HEADER
//===============================================================================
// Razor / (c)Copyright (2024)
//-------------------------------------------------------------------------------
// Title: (ByteToAsciiString)
// Comment/Function: (convert Byte value to ASCII code string)
// Library/Family: (Razorlib)
// Author: (A&D / Razor / 646644315@qq.com)
// Tested with: (test system with FW version)
// Engineering: TIA Portal (V17 Upd7)
// Restrictions: (OB types, etc.)
// Requirements: (hardware, technological package, memory needed, etc.)
//-------------------------------------------------------------------------------
// Change log table:
// Version | Date | Expert in charge | Changes applied
//----------|------------|------------------------|------------------------------
// 01.00.00 | 2024-05-13 | (Razor) | First released version
//===============================================================================
END_REGION BLOCK INFO HEADER
REGION DESCRIPTION
(/*
this block convert the value of a byte to ASCII code String
*/)
END_REGION DESCRIPTION
REGION INITIALISATION
#tempAsciiTable := #asciiTable;
#tempIndex := BYTE_TO_DINT(#original); //get index
#tempError := #NO_ERROR;
#tempConversion := #EMPTY_STRING;
END_REGION INITIALISATION
REGION PROGRAM LOGIC
IF #tempIndex >= #MIN_CONTROL AND #tempIndex <= #MAX_CONTROL THEN //check illegal
#tempError := #NO_ERROR;
END_IF;
IF #tempIndex > #MAX_CONTROL THEN //check upper limit
#tempError := #UPPER_OVERFLOW;
END_IF;
IF #tempIndex < #MIN_CONTROL THEN //check lower limit
#tempError := #LOWER_OVERFLOW;
END_IF;
IF #tempIndex >= #MIN_CONTROL AND #tempIndex <= #US_CONTROL_CHAR THEN //control chars
#tempConversion := #tempAsciiTable.ControlChar1[#tempIndex]."Char";
END_IF;
IF #tempIndex = #MAX_CONTROL THEN
#tempConversion := #tempAsciiTable.ControlChar2[#tempIndex]."Char";
END_IF;
IF #tempIndex >= #MIN_PRINTABLE AND #tempIndex <= #MAX_PRINTABLE THEN //printalble chars
#tempConversion := #EMPTY_STRING; //first clear,then transfer
#tempConversion := #tempAsciiTable.PrintableChar[#tempIndex]."Char";
END_IF;
END_REGION
REGION OUTPUTS
#Error := #tempError;
#conversion := #tempConversion;
END_REGION
END_FUNCTION