crc计算 delphi
Delphi与仪表之间的MODBUS通讯
Delphi与仪表之间的MODBUS通讯【摘要】在工控领域,经常会遇到各式各样的现场仪表,这些仪表分散在现场的各个位置,这样的话对管理人员和现场操作人员来说都非常不方便,那如何解决这个问题呢?此时就会用到一种方案,那就是配置上位机,用来集中控制这些仪表,这就是所谓的集散系统。
那么如何通过上位机与现场仪表通讯来获取仪表的数据,同时又能对仪表进行远程操作呢?这也就是今天要论述的课题。
在进行通信程序编写之前,我们首先得对现场仪表有一定的了解,最起码地是应该知道现场仪表支持什么通讯协议,需要设置哪些参数,然后才能展开下一步的工作。
【关键词】Delphi;ModBus;集散系统;多线程一、MODBUS通讯协议MODBUS是由莫迪康(现为施耐德公司的一个品牌)在1979年发明的,是全球第一个真正用于工业现场的总线协议。
MODBUS协议是应用于电子控制器上的一种通用语言,通过它,控制器之间或其他设备之间可以通信,它已经成为一通用工业标准。
有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。
它定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。
它描述了一控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。
它制定了消息域格局和内容的公共格式。
当在一Modbus网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。
如果需要回应,控制器将生成反馈信息并用Modbus协议发出。
在其它网络上,包含了Modbus协议的消息转换为在此网络上使用的帧或包结构。
这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。
二、VSD-6仪表简介VSD-6仪表是某厂家自己制作的一款仪表,它具有一个标准的MODBUS端口(二线制的RS485接囗),在一条RS485总线上可接入接出1至16台VSD-6控制仪表,可方便地同各种组态软件(如:组态王、WINCC、昆仑通态)直接连接通讯,也可以按照标准MODBUS(RTU)通讯协议自编程。
delphi 获取MAC地址
DT := DT-((TZ.Bias+TZ.StandardBias) / (24*60));
Result := DateTimeToStr(DT)+' '+WideCharToString(TZ.StandardName);
mymaclength:=length(mymac);
r:=sendarp(myip,0,@mymac,@mymaclength);
label1.caption:='errorcode:'+inttostr(r);
label2.caption:=format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',[mymac[0],mymac[1],mymac[2],mymac[3],mymac[4],mymac[5]]);
Var
AI,Work : PIPAdapterInfo;
Size : Integer;
Res : Integer;
I : Integer;
Function MACToStr(ByteArr : PByte; Len : Integer) : String;
Begin
Result := '';
End;
Function GetAddrString(Addr : PIPAddrString) : String;
Begin
Result := '';
While (Addr <> nil) do Begin
DELPHI获取硬盘、CPU、网卡序列号
DELPHI获取硬盘、CPU、⽹卡序列号 //引⽤及TYPE变量申明usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls,nb30; {重要引⽤}typePASTAT = ^TASTAT;TASTAT = recordadapter : TAdapterStatus;name_buf : TNameBuffer;end;TForm1 = class(TForm)Button1: TButton;Edit1: TEdit;Label1: TLabel;Label2: TLabel;Label3: TLabel;Edit2: TEdit;Edit3: TEdit;Button2: TButton;Edit4: TEdit;Label4: TLabel;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}typeTCPUID = array[1..4] of Longint;//取硬盘系列号:function GetIdeSerialNumber: pchar; //获取硬盘的出⼚系列号;const IDENTIFY_BUFFER_SIZE = 512;typeTIDERegs = packed recordbFeaturesReg: BYTE;bSectorCountReg: BYTE;bSectorNumberReg: BYTE;bCylLowReg: BYTE;bCylHighReg: BYTE;bDriveHeadReg: BYTE;bCommandReg: BYTE;bReserved: BYTE;end;TSendCmdInParams = packed recordcBufferSize: DWORD;irDriveRegs: TIDERegs;bDriveNumber: BYTE;bReserved: array[0..2] of Byte;dwReserved: array[0..3] of DWORD;bBuffer: array[0..0] of Byte;end;TIdSector = packed recordwGenConfig: Word;wNumCyls: Word;wReserved: Word;wNumHeads: Word;wBytesPerTrack: Word;wBytesPerSector: Word;wSectorsPerTrack: Word;wVendorUnique: array[0..2] of Word;sSerialNumber: array[0..19] of CHAR;wBufferType: Word;wBufferSize: Word;wECCSize: Word;sFirmwareRev: array[0..7] of Char;sModelNumber: array[0..39] of Char;wMoreVendorUnique: Word;wDoubleWordIO: Word;wCapabilities: Word;wReserved1: Word;wPIOTiming: Word;wDMATiming: Word;wBS: Word;wNumCurrentCyls: Word;wNumCurrentHeads: Word;wNumCurrentSectorsPerTrack: Word;ulCurrentSectorCapacity: DWORD;wMultSectorStuff: Word;ulTotalAddressableSectors: DWORD;wSingleWordDMA: Word;wMultiWordDMA: Word;bReserved: array[0..127] of BYTE;end;PIdSector = ^TIdSector;TDriverStatus = packed recordbDriverError: Byte;bIDEStatus: Byte;bReserved: array[0..1] of Byte;dwReserved: array[0..1] of DWORD;end;TSendCmdOutParams = packed recordcBufferSize: DWORD;DriverStatus: TDriverStatus;bBuffer: array[0..0] of BYTE;end;varhDevice: Thandle;cbBytesReturned: DWORD;SCIP: TSendCmdInParams;aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE-1)-1] of Byte; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;procedure ChangeByteOrder(var Data; Size: Integer);//函数中的过程varptr: Pchar;i: Integer;c: Char;beginptr := @Data;for I := 0 to (Size shr 1) - 1 do beginc := ptr^;ptr^ := (ptr + 1)^;(ptr + 1)^ := c;Inc(ptr, 2);end;end;begin //函数主体Result := '';if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT thenbegin // Windows NT, Windows 2000hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);endelse // Version Windows 95 OSR2, Windows 98hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);if hDevice = INVALID_HANDLE_VALUE then Exit;tryFillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);cbBytesReturned := 0;with SCIP dobegincBufferSize := IDENTIFY_BUFFER_SIZE;with irDriveRegs dobeginbSectorCountReg := 1;bSectorNumberReg := 1;bDriveHeadReg := $A0;bCommandReg := $EC;end;end;if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;finallyCloseHandle(hDevice);end;with PIdSector(@IdOutCmd.bBuffer)^ dobeginChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));(Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^:= #0;Result := Pchar(@sSerialNumber);end;end;//=================================================================//CPU系列号:FUNCTION GetCPUID : TCPUID; assembler; register;asmPUSH EBX {Save affected register}PUSH EDIMOV EDI,EAX {@Resukt}MOV EAX,1DW $A20F {CPUID Command}STOSD {CPUID[1]}MOV EAX,EBXSTOSD {CPUID[2]}MOV EAX,ECXSTOSD {CPUID[3]}MOV EAX,EDXSTOSD {CPUID[4]}POP EDI {Restore registers}POP EBXEND;function GetCPUIDStr:String;varCPUID:TCPUID;beginCPUID:=GetCPUID;Result:=IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8); end;///================================================================================== ///取MAC(⾮集成⽹卡):function NBGetAdapterAddress(a: Integer): string;varNCB: TNCB; // Netbios control block //NetBios控制块ADAPTER: TADAPTERSTATUS; // Netbios adapter status//取⽹卡状态LANAENUM: TLANAENUM; // Netbios lanaintIdx: Integer; // Temporary work value//临时变量cRC: Char; // Netbios return code//NetBios返回值strTemp: string; // Temporary string//临时变量begin// InitializeResult := '';try// Zero control bloclZeroMemory(@NCB, SizeOf(NCB));// Issue enum commandNCB.ncb_command := Chr(NCBENUM);cRC := NetBios(@NCB);// Reissue enum commandNCB.ncb_buffer := @LANAENUM;NCB.ncb_length := SizeOf(LANAENUM);cRC := NetBios(@NCB);if Ord(cRC) <> 0 thenexit;// Reset adapterZeroMemory(@NCB, SizeOf(NCB));NCB.ncb_command := Chr(NCBRESET);NCB.ncb_lana_num := na[a];cRC := NetBios(@NCB);if Ord(cRC) <> 0 thenexit;// Get adapter addressZeroMemory(@NCB, SizeOf(NCB));NCB.ncb_command := Chr(NCBASTAT);NCB.ncb_lana_num := na[a];StrPCopy(NCB.ncb_callname, '*');NCB.ncb_buffer := @ADAPTER;NCB.ncb_length := SizeOf(ADAPTER);cRC := NetBios(@NCB);// Convert it to stringstrTemp := '';for intIdx := 0 to 5 dostrTemp := strTemp + InttoHex(Integer(ADAPTER.adapter_address[intIdx]), 2);Result := strTemp;finallyend;end;//========================================================================== //取MAC地址(集成⽹卡和⾮集成⽹卡):function Getmac:string;varncb : TNCB;s:string;adapt : TASTAT;lanaEnum : TLanaEnum;i, j, m : integer;strPart, strMac : string;beginFillChar(ncb, SizeOf(TNCB), 0);ncb.ncb_command := Char(NCBEnum);ncb.ncb_buffer := PChar(@lanaEnum);ncb.ncb_length := SizeOf(TLanaEnum);s:=Netbios(@ncb);for i := 0 to integer(lanaEnum.length)-1 dobeginFillChar(ncb, SizeOf(TNCB), 0);ncb.ncb_command := Char(NCBReset);ncb.ncb_lana_num := na[i];Netbios(@ncb);Netbios(@ncb);FillChar(ncb, SizeOf(TNCB), 0);ncb.ncb_command := Chr(NCBAstat);ncb.ncb_lana_num := na[i];ncb.ncb_callname := '* ';ncb.ncb_buffer := PChar(@adapt);ncb.ncb_length := SizeOf(TASTAT);m:=0;if (Win32Platform = VER_PLATFORM_WIN32_NT) thenm:=1;if m=1 thenbeginif Netbios(@ncb) = Chr(0) thenstrMac := '';for j := 0 to 5 dobeginstrPart := IntToHex(integer(adapt.adapter.adapter_address[j]), 2);strMac := strMac + strPart + '-';end;SetLength(strMac, Length(strMac)-1);end;if m=0 thenif Netbios(@ncb) <> Chr(0) thenbeginstrMac := '';for j := 0 to 5 dobeginstrPart := IntToHex(integer(adapt.adapter.adapter_address[j]), 2);strMac := strMac + strPart + '-';end;SetLength(strMac, Length(strMac)-1);end;end;result:=strmac;end;function PartitionString(StrV,PrtSymbol: string): TStringList;variTemp: integer;beginresult := TStringList.Create;iTemp := pos(PrtSymbol,StrV);while iTemp>0 do beginif iTemp>1 then result.Append(copy(StrV,1,iTemp-1));delete(StrV,1,iTemp+length(PrtSymbol)-1);iTemp := pos(PrtSymbol,StrV);end;if Strv<>'' then result.Append(StrV);end;function MacStr():String;varStr:TStrings;i:Integer;MacStr:String;beginMacStr:='';Str:=TStringList.Create;Str:=PartitionString(Getmac,'-');for i:=0 to Str.Count-1 doMacStr:=MacStr+Str[i];Result:=MacStr;end;//============================================== //调⽤⽰例procedure TForm1.Button1Click(Sender: TObject);beginEdit3.Text:=strpas(GetIdeSerialNumber);//取硬盘号Edit2.text:=GetCPUIDStr;//CPU系列号edit4.Text:=NBGetAdapterAddress(12);//⾮集成⽹卡Edit1.text:=MacStr;//集成和⾮集成⽹卡end;。
Delphi运算符
delphi、c++与vb中的运算符2008-11-21 15:10Delphi_C++_VB 基本运算符号2007-02-25 11:55运算符赋值运算符Pascal :=C/C++ =BASIC =比较运算符运算符等于不等于小于(等于) 大于(等于)Pascal = <> <(=) >(=)C/C++ == != <(=) >(=)BASIC =或者Is <> <(=) >(=)逻辑运算符运算符逻辑与逻辑或逻辑非Pascal and or notC/C++ && || !BASIC And Or Not算术运算符运算符加减乘除(浮点数)除(整数)取模指数Pascal + - * / div mod 无C/C++ + - * / / % 无BASIC + - * / / Mod ^运算符与取反或异或左移右移Pascal and not or xor shl shrC/C++ & ~ | ^ << >>BASIC And Not Or Xor 无无Delphi运算符(2)2007-12-01 12:072.1.4 算术运算符算术运算符是执行算术运算如加、减、乘、除等的符号。
和其他大多数语言不同,在Pascal 中,进行乘、除时,整数和浮点数使用的符号不同。
例如:I := J div C;整数J和C作除法运算,并将结果赋值给I。
几种语言的算术运算符比较见表2-4。
表2-4 算术运算符2.1.5 按位运算符我们知道,变量在内存中是使用一些位(Bit)存储0或者1来保存的。
按位运算符就是对位进行运算的符号。
例如:varI: Byte; {Byte类型的取值范围在0~255,用8比特保存}beginI := 0; {此时I在内存中状态:00000000}I := not I; {对各位取反,因此变为"11111111",即255}end;几种语言的按位运算符比较见表2-5。
各种位运算经验(源码用delphi示例)
二进制中的1有奇数个还是偶数个我们可以用下面的代码来计算一个32位整数的二进制中1的个数的奇偶性,当输入数据的二进制表示里有偶数个数字1时程序输出0,有奇数个则输出1。
例如,1314520的二进制101000000111011011000中有9个1,则x=1314520时程序输出1。
vari,x,c:longint;beginreadln(x);c:=0;for i:=1 to 32 dobeginc:=c + x and 1;x:=x shr 1;end;writeln( c and 1 );end.但这样的效率并不高,位运算的神奇之处还没有体现出来。
同样是判断二进制中1的个数的奇偶性,下面这段代码就强了。
你能看出这个代码的原理吗?varx:longint;beginreadln(x);x:=x xor (x shr 1);x:=x xor (x shr 2);x:=x xor (x shr 4);x:=x xor (x shr 8);x:=x xor (x shr 16);writeln(x and 1);end.为了说明上面这段代码的原理,我们还是拿1314520出来说事。
1314520的二进制为101000000111011011000,第一次异或操作的结果如下:00000000000101000000111011011000XOR 0000000000010100000011101101100---------------------------------------00000000000111100000100110110100得到的结果是一个新的二进制数,其中右起第i位上的数表示原数中第i和i+1位上有奇数个1还是偶数个1。
比如,最右边那个0表示原数末两位有偶数个1,右起第3位上的1就表示原数的这个位置和前一个位置中有奇数个1。
对这个数进行第二次异或的结果如下:00000000000111100000100110110100XOR 000000000001111000001001101101---------------------------------------00000000000110011000101111011001结果里的每个1表示原数的该位置及其前面三个位置中共有奇数个1,每个0就表示原数对应的四个位置上共偶数个1。
Delphi下用SPCOMM对Modbus编程
Delphi下用SPCOMM对Modbus编程一、流程主体流程与普通的串口编程一样。
二、ModbusModbus普通串口不致的地方就是发送与返回的数据除遵循串口本身要求外,还有格式要求。
这里以读多位bit为例,其它的读者可查询Modbu功能码文档。
01功能码,读取多个线圈(位,bit),命令为16进制发送命令:01 01 48 00 00 10 2A 66返回命令: 01 01 02 FF 03 B8 0D三、例程例:串口SPCOMM控件名为:SPCOMM1;发送时钟名为:TimerCom;(1)控件属性设置mName := 'COM1'; //串中号表示 COM1、COM2等串口的名字SPCOMM1.BaudRate := 9600; //波特率根据实际需要设定的波特率,在串口打开后也可更改此值,实际波特率随之更改SPCOMM1.ParityCheck := False;//表示是否需要奇偶校验;SPCOMM1.Parity := None; //没有奇偶校验位; 奇偶校验位;SPCOMM1.ReadIntervalTimeOut:= 40; //信息发送后,40毫秒内返回的数据都算作一次返回。
注意要比发送间隔小。
TimerCom.Interval := 50 //时钟刷新间隔 TimerCom.Interval >SPCOMM1.ReadIntervalTimeOut(2)打开串口SPCOMM1.StopComm; //先关闭串口SPCOMM1.StartComm; //打开串口(3)形成发送命令CRCParityCheck16为对发送命令进行CRC校验,这里就不写了。
varbufByte:array[0..50000] of Byte;bufComReadChar :array[0..50000] of chari,nComReadLength:Integer;nCRC:Word;strSend:string;FnCRCFunt,FnCRCStart:Cardinal;//校验多项式,校验初始值 ]begin//先将数据形成16进制字符组成的字符串,然后再来校验发送strSend := '';strSend := IntToHex(1,2); //第1字节机组号strSend := strSend + '01'; //modbus 功能码01 读多个位操作strSend := strSend + IntToHex(StrToInt('$4800',4); //起始地址3、4字节strSend := strSend + IntToHex(16,4); //位总数, 5、6字节for i := 0 to 5 dobeginbufByte[i] := StrToInt('$' + copy(strSend,i*2+1,2));end;nCRC:=CRCParityCheck16(FnCRCStart ,FnCRCFunt,bufByte,6);strSend := strSend + IntToHex(nCRC,4);for i:=0 to 7 dobufComReadChar:=char(strtoint('$'+copy(strSend,i*2+1,2)));nComReadLength := 8;SPCOMM1.WriteCommData(bufComReadChar,nComReadLe ngth); //发送命令,参数:命令,命令长度end;(4)接受返回命令并解析SPCOMM1ReceiveData(Sender: TObject;Buffer: Pointer; BufferLength: Word);vari:integer;rbuf:array [1..1000] of byte ;begin//接收到数据,进行解析move(Buffer^,(pchar(@rbuf))^,BufferLength);for i := 1 to BufferLength dobeginstrTemp := strTemp + IntToHex(rbuf[i],2) + ' ';end;end;。
delphi 位运算简介及实用技巧
位运算简介及实用技巧去年年底写的关于位运算的日志是这个Blog里少数大受欢迎的文章之一,很多人都希望我能不断完善那篇文章。
后来我看到了不少其它的资料,学习到了更多关于位运算的知识,有了重新整理位运算技巧的想法。
从今天起我就开始写这一系列位运算讲解文章,与其说是原来那篇文章的follow-up,不如说是一个remake。
当然首先我还是从最基础的东西说起。
什么是位运算?程序中的所有数在计算机内存中都是以二进制的形式储存的。
位运算说穿了,就是直接对整数在内存中的二进制位进行操作。
比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。
举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理):110AND 1011----------0010 --> 2由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。
当然有人会说,这个快了有什么用,计算6 and 11没有什么实际意义啊。
这一系列的文章就将告诉你,位运算到底可以干什么,有些什么经典应用,以及如何用位运算优化你的程序。
Pascal和C中的位运算符号,下面的a和b都是整数类型,则:C语言 Pascal语言按位与 a & b a and b按位或 a | b a or b异或 a ^ b a xor ba取反 ~a not左移位 a << b a shl b右移位 a >> b a shr b注意C中的逻辑运算和位运算符号是不同的。
520|1314=1834,但520||1314=1,因为逻辑运算时520和1314都相当于True。
同样的,!a和~a也是有区别的。
各种位运算的使用:=== 1. and运算 ===and运算通常用于二进制取位操作,例如一个数 and 1的结果就是取二进制的最末位。
DELPHIXE11.1的几个数学取整
DELPHIXE11.1的几个数学取整Delphi下的四舍五入和取整,除了截取整数Trunc()之外,都是四舍六入五留双,即银行家算法。
但是好像又不全是这么回事儿。
要以实测为准。
例如3.15和3.25,修约时应分别得到3.2和3.2,而不是3.2和3.3。
这个算法在大学物理实验里也是这样。
但是也偶有争议,说是不同的Delphi版本编译器怎样怎样。
我比较了Delphi7和Delphi XE11.1,结果是一样的。
Round()在四舍六入,而SimpleRoundTo()仍然在四舍五入。
unit Unit1;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System .Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;typeTForm1 = class(TForm)Button1: TButton;procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementationuses math;{$R *.dfm}function RoundClassic(R: Real): Int64;beginResult:= Trunc(R);if Frac(R) >= 0.5 thenResult:= Result + 1;end;function RoundThief(R: Real): Int64;beginR:=R+0.0000000000001;Result:= Trunc(R);if Frac(R) >= 0.5 thenResult:= Result + 1;end;procedure TForm1.Button1Click(Sender: TObject); vara: integer;b: real;begina := Trunc(0.35 * 10);showmessage('3.5取整数部分' + inttostr(a));a := round(2.5);showmessage('Round(2.5)四舍六入五留双,得到2而不是3:' + inttostr(a));b := simpleroundto(2.5, 0);showmessage('2.5取整,SimpleRounTo又开始传统四舍五入3:' + floattostr(b));b := simpleroundto(2.55, -1);showmessage('2.55留1位小数,SimpleRounT o又开始传统四舍五入2.6:' + floattostr(b));b := simpleroundto(2.45, -1);showmessage('2.45留1位小数,SimpleRounT o又开始传统四舍五入2.5:' + floattostr(b));a := ceil(123.4);showmessage('123.4向上取整:' + inttostr(a));a := ceil(-123.4);showmessage('-123.4向上取整:' + inttostr(a));a := floor(123.4);showmessage('123.4向下取整:' + inttostr(a));a := floor(-123.4);showmessage('-123.4向下取整:' + inttostr(a));a := RoundClassic(124.5);showmessage('124.5经典四舍五入:' + inttostr(a));a := RoundThief(124.5);showmessage('124.5取巧四舍五入:' + inttostr(a));//showmessage('33.025四舍五入:' + floattostr(RoundTo(33.025,-2)));end;end.。
Delphi SSE优化算法应用之三(CRC-32C (Castagnoli) 校验算法优化)
Delphi SSE优化算法应用之三(CRC-32C (Castagnoli) 校验算法优化)作者:CodeGame.CRC-32C (Castagnoli) 算法是iSCSI 和SCTP 数据校验的算法,和常用CRC-32-IEEE 802.3算法所不同的是多项式常数CRC32C是0x1EDC6F41 ,CRC32是0x04C11DB7 ,也就是说由此生成的CRC表不同外算法是一模一样.CRC32 常规算法如下:1.function _CRC32CX86(Data: PByte; aLength: Integer): DWORD;2.const3._CRC32CTable: array[0..255] of DWORD = (4.$00000000, $F26B8303, $E13B70F7, $1350F3F4, //CRC32C Table5.$C79A971F, $35F1141C, $26A1E7E8, $D4CA64EB,6.$8AD958CF, $78B2DBCC, $6BE22838, $9989AB3B,7.$4D43CFD0, $BF284CD3, $AC78BF27, $5E133C24,8.$105EC76F, $E235446C, $F165B798, $030E349B,9.$D7C45070, $25AFD373, $36FF2087, $C494A384,10.$9A879FA0, $68EC1CA3, $7BBCEF57, $89D76C54,11.$5D1D08BF, $AF768BBC, $BC267848, $4E4DFB4B,12.$20BD8EDE, $D2D60DDD, $C186FE29, $33ED7D2A,13.$E72719C1, $154C9AC2, $061C6936, $F477EA35,14.$AA64D611, $580F5512, $4B5FA6E6, $B93425E5,15.$6DFE410E, $9F95C20D, $8CC531F9, $7EAEB2FA,16.$30E349B1, $C288CAB2, $D1D83946, $23B3BA45,17.$F779DEAE, $05125DAD, $1642AE59, $E4292D5A,18.$BA3A117E, $4851927D, $5B016189, $A96AE28A,19.$7DA08661, $8FCB0562, $9C9BF696, $6EF07595,20.$417B1DBC, $B3109EBF, $A0406D4B, $522BEE48,21.$86E18AA3, $748A09A0, $67DAFA54, $95B17957,22.$CBA24573, $39C9C670, $2A993584, $D8F2B687,23.$0C38D26C, $FE53516F, $ED03A29B, $1F682198,24.$5125DAD3, $A34E59D0, $B01EAA24, $42752927,25.$96BF4DCC, $64D4CECF, $77843D3B, $85EFBE38,26.$DBFC821C, $2997011F, $3AC7F2EB, $C8AC71E8,27.$1C661503, $EE0D9600, $FD5D65F4, $0F36E6F7,28.$61C69362, $93AD1061, $80FDE395, $72966096,29.$A65C047D, $5437877E, $4767748A, $B50CF789,30.$EB1FCBAD, $197448AE, $0A24BB5A, $F84F3859,31.$2C855CB2, $DEEEDFB1, $CDBE2C45, $3FD5AF46,32.$7198540D, $83F3D70E, $90A324FA, $62C8A7F9,33.$B602C312, $44694011, $5739B3E5, $A55230E6,34.$FB410CC2, $092A8FC1, $1A7A7C35, $E811FF36,35.$3CDB9BDD, $CEB018DE, $DDE0EB2A, $2F8B6829,36.$82F63B78, $709DB87B, $63CD4B8F, $91A6C88C,37.$456CAC67, $B7072F64, $A457DC90, $563C5F93,38.$082F63B7, $FA44E0B4, $E9141340, $1B7F9043,39.$CFB5F4A8, $3DDE77AB, $2E8E845F, $DCE5075C,40.$92A8FC17, $60C37F14, $73938CE0, $81F80FE3,41.$55326B08, $A759E80B, $B4091BFF, $466298FC,42.$1871A4D8, $EA1A27DB, $F94AD42F, $0B21572C,43.$DFEB33C7, $2D80B0C4, $3ED04330, $CCBBC033,44.$A24BB5A6, $502036A5, $4370C551, $B11B4652,45.$65D122B9, $97BAA1BA, $84EA524E, $7681D14D,46.$2892ED69, $DAF96E6A, $C9A99D9E, $3BC21E9D,47.$EF087A76, $1D63F975, $0E330A81, $FC588982,48.$B21572C9, $407EF1CA, $532E023E, $A145813D,49.$758FE5D6, $87E466D5, $94B49521, $66DF1622,50.$38CC2A06, $CAA7A905, $D9F75AF1, $2B9CD9F2,51.$FF56BD19, $0D3D3E1A, $1E6DCDEE, $EC064EED,52.$C38D26C4, $31E6A5C7, $22B65633, $D0DDD530,53.$0417B1DB, $F67C32D8, $E52CC12C, $1747422F,54.$49547E0B, $BB3FFD08, $A86F0EFC, $5A048DFF,55.$8ECEE914, $7CA56A17, $6FF599E3, $9D9E1AE0,56.$D3D3E1AB, $21B862A8, $32E8915C, $C083125F,57.$144976B4, $E622F5B7, $F5720643, $07198540,58.$590AB964, $AB613A67, $B831C993, $4A5A4A90,59.$9E902E7B, $6CFBAD78, $7FAB5E8C, $8DC0DD8F,60.$E330A81A, $115B2B19, $020BD8ED, $F0605BEE,61.$24AA3F05, $D6C1BC06, $C5914FF2, $37FACCF1,62.$69E9F0D5, $9B8273D6, $88D28022, $7AB90321,63.$AE7367CA, $5C18E4C9, $4F48173D, $BD23943E,64.$F36E6F75, $0105EC76, $12551F82, $E03E9C81,65.$34F4F86A, $C69F7B69, $D5CF889D, $27A40B9E,66.$79B737BA, $8BDCB4B9, $988C474D, $6AE7C44E,67.$BE2DA0A5, $4C4623A6, $5F16D052, $AD7D5351);68.var69.i: Integer;71.Result := $FFFFFFFF;72.for I := 0 to aLength - 1 do73.begin74.Result := (Result shr 8) xor _CRC32CTable[(Result and $FF) xor Data^];75.Inc(Data);76.end;77.Result := not Result;78.end;CRC32C使用SSE4.2硬件指令优化算法部分代码如下:1.function _CRC32CSSE(Data: PByte; aLength: Integer): DWORD;2.asm3.push esi4.push edx5.push ecx6.mov esi,eax7.mov eax,$FFFFFFFF8.test edx,edx9.jz @Exit10.test esi,esi11.jz @Exit12.mov ecx,edx13.shr ecx, 214.test ecx,ecx15.jz @Exit16.xor edx,edx17.@Alignment:18.crc32 eax,[edx*4+esi]19.inc edx20.cmp edx,ecx21.jb @Alignment22.@Exit:23.not eax24.pop ecx25.pop edx26.pop esi以上2个不同实现方式在Intel Core i7 720QM 1.60GHz CPU上测试成绩如下:(数据采用随机算法生成,1M*100表示使用1M数据进行100次重复计算,数据量相当于100M)--------------------------------------------------------------------------------------| 数据量| 常规算法时间| 优化算法时间| 快出百分比|--------------------------------------------------------------------------------------| 1M *100 | X86 Time:390ms | SSE Time:32ms | 1218% |--------------------------------------------------------------------------------------| 4M *100 | X86 Time:1575ms | SSE Time:156ms | 1009% |--------------------------------------------------------------------------------------| 8M *100 | X86 Time:3136ms | SSE Time:280ms | 1120% |--------------------------------------------------------------------------------------| 32M *100 | X86 Time:12542ms | SSE Time:1092ms | 1148% |--------------------------------------------------------------------------------------通过对比可以清楚的看到使用SSE4.2中的新指令crc32可以比常规CRC32C算法要快出最少10倍的效率,Intel 新增的指令确实对常规某些算法提供了高效的解决方案,使用好它们将对我们在以后的开发中得到质的提升。
delphi 随机生成四则运算题目
delphi 随机生成四则运算题目在 Delphi 中,你可以使用随机数生成器来生成四则运算题目。
以下是一个简单的示例,演示如何生成两个随机数和一个随机运算符,然后计算结果:```delphiprogram RandomArithmeticQuestion;{$APPTYPE CONSOLE}usesSysUtils, Classes;vara, b, operatorChar, result: Integer;beginWriteLn('随机四则运算题目:');// 生成两个随机数a := RandomRange(1, 100);b := RandomRange(1, 100);// 生成一个随机运算符operatorChar := RandomRange(Ord('+'), Ord('-'));// 根据运算符计算结果case operatorChar ofOrd('+'): result := a + b;Ord('-'): result := a - b;Ord(''): result := a b;Ord('/'): result := a div b; // 注意:这里使用 div,因为 Delphi 没有直接支持整数除法操作符 '/'end;// 输出题目和答案WriteLn(Format('题目: %d %c %d = ?', [a, Chr(operatorChar), b])); WriteLn('答案: ' + IntToStr(result));end.```这个程序首先生成两个介于 1 和 100 之间的随机整数(`a` 和 `b`),然后选择一个随机的运算符(`+`、`-`、`` 或 `/`)。
根据运算符,程序计算结果并将题目和答案输出到控制台。
Delphi的运算符列表
X <> Y
<
小于
简单类型、串、压缩串、PChar
Boolean
X < Y
&g、PChar
Boolean
Len > 0
<=
小于或等于
简单类型、串、压缩串、PChar
Boolean
Cnt <= 1
>=
大于或等于
简单类型、串、压缩串、PChar
Boolean
I >= 1
@类中方法
当 @ 适用于定
Q <= MySet
>=
超集
集合
Boolean
S1 >= S2
=
相等
集合
Boolean
S2 = MySet
<>
不等
集合
Boolean
MySet <> S1
in
成员
序数,集合
Boolean
A in Set1
关系运算符
=
相等
简单类型、类、类引用、接口、串、压缩串
Boolean
I = Max
<>
不等
简单类型、类、类引用、接口、串、压缩串
类运算符
as
转换
类和类的实例
is
判断
=
关系运算符 = 和 <> 也作用于类
<>
地址(@)运算符
@X
如果X是一个变量,那么@X返回X的地址。当编译指示 {$T-} 有效时,@X是Pointer类型; 而在编译指示 {$T+} 状态下时,@X是 ^T 类型,这里的T是X的类型。
@F
基于Delphi的计算机与可编程控制器通信过程及实现
基于Delphi的计算机与可编程控制器通信过程及实现发布时间:2021-04-21T01:46:33.077Z 来源:《中国科技人才》2021年第6期作者:臧永娜1 袁宏杰吴淑梅2 韩瀚2 秦家瑞2 [导读] PLC控制器采用Modbus协议,Modbus是一种串行通信协议,由 Modicon公司(施耐德电气公司)于1979年设计。
Modbus为工业领域通信协议标准,是工业电子设备之间常采用的连接方式。
Modbus实现多个 (大约240个) 设备互联在同一个网络上进行通信, Modbus常用来连接监控服务器和远程终端控制系统(RTU)。
1.石家庄祥龙泰超市信息中心河北石家庄 050051,2.石家庄邮电职业技术学院河北石家庄 050022摘要:本文首先概要介绍了基于Modbus协议的PLC(可编程控制器)的通信方式及用途,详细说明了PLC与PC机(计算机)之间的通信原理。
其次给出了PLC通信CRC16校验的流程及实现方法。
同时给出了PLC与PC机通信设置方法以及PC机与PLC通信实现过程及实现源码。
最后说明了计算机与控制器通信的应用场景。
关键词:通信;可编程控制器;CRC校验;Modbus1.引言PLC为可编程控制器,广泛应用于工业生产和自动化控制领域,PLC是将用户存储的控制程序,通过逻辑运算、定时、计数或算数运算指令,完成对各类生产设备的智能控制。
是自动化控制的关键部件。
PLC可编程控制器进行控制功能的两个基本要素是信息进出的交换和物理的可靠实现[1]。
2.PLC485串口通信协议2.1通信概述PLC控制器采用Modbus协议,Modbus是一种串行通信协议,由 Modicon公司(施耐德电气公司)于1979年设计。
Modbus为工业领域通信协议标准,是工业电子设备之间常采用的连接方式。
Modbus实现多个 (大约240个) 设备互联在同一个网络上进行通信, Modbus常用来连接监控服务器和远程终端控制系统(RTU)。
Delphi中ComPort通信中的数据处理
Delphi中ComPort通信中的数据处理
在Delphi中使用ComPort进行通信时,数据处理的方式取决于你的需求和通信协议。
以下是一些常见的数据处理方法:
1. 字符串处理:如果你的通信数据是以字符串形式传输的,你可以使用字符串处理函数(如Pos、Copy、Trim等)来提取和处理数据。
2. 数据类型转换:如果你的通信数据是以字节或二进制形式传输的,你可以使用类型转换函数(如ByteToInteger、IntegerToByte等)将数据转换为相应的数据类型。
3. 数据解析:如果你的通信数据是结构化的,例如XML或JSON格式,你可以使用相应的解析库(如Delphi自带的XmlDoc、SuperObject等)来解析数据。
4. 数据校验:在通信中,经常需要对数据进行校验,以确保数据的完整性和正确性。
常见的校验方法包括校验和、CRC校验等。
5. 数据存储:如果你需要将通信数据保存到本地或数据库中,你可以使用相应的存储方法(如写入文件、执行SQL语句等)来实现。
6. 数据显示:如果你需要将通信数据显示在界面上,你可以使用相应的控件(如Memo、ListView等)来显示数据,并根据需要进行格式化和美化。
需要注意的是,数据处理的具体方法和实现可能会因具体的通信协议和需求而有所不同。
因此,在进行数据处理时,建议根据具体情况选择合适的方法和工具。
可变情报标志
可变信息标志通信协议v4.202003-02-25一、协议简介本协议用于上海三思科技发展有限公司生产的可变信息标志(包括全点阵的可变限速标志)与监控计算机之间的通信。
可变信息标志操作系统(signaler) 的版本应为第版。
可变信息标志的通信接口为RS232 串行口。
本协议与《播放表格式》、《可变信息标志操作系统安装手册》、《预置播放表一览表》、《预置位图一览表》构成完整的协议文档。
二、通信参数波特率- 9600数据位- 8奇偶校验- 无校验停止位- 1流控制- 无三、帧结构与可变信息标志的每次通信过程应包括完整的一个来回:●监控计算机向可变信息标志发送命令帧;●可变信息标志向监控计算机发送应答帧。
建议监控计算机在等待应答帧时,超时时间不少于3 秒。
1. 说明在本文的以下部分,全部为数字的、形如123 的为十进制数;以0x 开头的、形如0xABC 的为十六进制数;以单引号括起来的、形如'A' 的为ASCII 码字符;以双引号括起来的、形如"ABCDE" 的为ASCII 码字符串。
2. 监控计算机至可变信息标志的帧结构命令帧结构:+--------+--------+------------------------------------------+| 字段| 字节数| 描述|+--------+--------+------------------------------------------+| 帧头| 1 | 0x02,表明一帧的开始,为接收方提供同步|| 地址| 2 | 可变信息标志地址,由可变信息标志厂家设定|| 帧类型| 2 | 表明此帧的功能|| 帧数据|不定长| || 帧校验| 2 | 供接收方判断所收帧的正确性|| 帧尾| 1 | 0x03,表明一帧的结束,为接收方提供同步|+--------+--------+------------------------------------------+《表一》2.1 地址可变信息标志地址范围为1-99,组帧时转换为两个ASCII 码。
Delphi-CRC32校验
Delphi-CRC32校验⽹上Down的⼀个单元.⾃⼰改了下.unit utCRC32;interfaceusesWindows,SysUtils,Classes;const //Crc32表Crc32Tab: Array[0..$FF] of LongInt =($00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f,$e963a535, $9e6495a3, $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,$09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91, $1db71064, $6ab020f2,$f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,$136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9,$fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, $a2677172,$3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, $35b5a8fa, $42b2986c,$dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,$26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423,$cfba9599, $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924,$2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, $01db7106,$98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,$7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d,$91646c97, $e6635c01, $6b6b51f4, $1c6c6162, $856530d8, $f262004e,$6c0695ed, $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950,$8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,$4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7,$a4d1c46d, $d3d6f4fb, $4369e96a, $346ed9fc, $ad678846, $da60b8d0,$44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa,$be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f,$5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81,$b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a,$ead54739, $9dd277af, $04db2615, $73dc1683, $e3630b12, $94643b84,$0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,$f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb,$196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, $67dd4acc,$f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, $d6d6a3e8, $a1d1937e,$38d8c2c4, $4fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,$d80d2bda, $af0a1b4c, $36034af6, $41047a60, $df60efc3, $a867df55,$316e8eef, $4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236,$cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, $b2bd0b28,$2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,$9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f,$72076785, $05005713, $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38,$92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242,$68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777,$88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69,$616bffd3, $166ccf45, $a00ae278, $d70dd2ee, $4e048354, $3903b3c2,$a7672661, $d06016f7, $4969474d, $3e6e77db, $aed16a4a, $d9d65adc,$40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,$bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693,$54de5729, $23d967bf, $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94,$b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d);procedure GetCRC32Stream(aStream:TStream;var CRC32:Cardinal);implementationfunction UpdateCRC32(InitCRC: LongInt; var Buffer;{$IFDEF Win32} Length: LongInt {$ELSE} Length: Word {$ENDIF}): LongInt;beginasm{$IFDEF Win32}push esipush edipush eaxpush ebxpush ecxpush edxlea edi, Crc32Tabmov esi, Buffermov ax, word ptr InitCRCmov dx, word ptr InitCRC + 2mov ecx, Lengthor ecx, ecxjz @@done@@loop:xor ebx, ebxmov bl, allodsbxor bl, almov al, ahmov ah, dlmov dl, dhxor dh, dhshl bx, 1shl bx, 1add ebx, edixor ax, [ebx]xor dx, [ebx + 2]loop @@loop@@done:mov word ptr Result, axmov word ptr Result + 2, dxpop edxpop ecxpop ebxpop eaxpop edipop esi{$ELSE}push dspop espush dslea di, CRC32Tablds si, Buffermov ax, word ptr InitCRCmov dx, word ptr InitCRC + 2mov cx, Lengthor cx, cxjz @@done@@loop:xor bh, bhmov bl, allodsbxor bl, almov al, ahmov ah, dlmov dl, dhxor dh, dhshl bx, 1shl bx, 1xor ax, es:[di + bx]xor dx, es:[di + bx + 2]loop @@loop@@done:pop dsmov word ptr Result, axmov word ptr Result + 2, dx{$ENDIF}end;end;procedure GetCRC32Stream(aStream:TStream;var CRC32:Cardinal); varBuffer:PByte;N:Int64;beginN:=aStream.Size;GetMem(Buffer,N);tryCRC32:=UpdateCRC32($FFFFFFFF,Buffer^,N)finallyFreeMem(Buffer,N);end;CRC32 := not CRC32;end;end.。
Delphi下实现数据校验
声明本论文题目:Delphi下实现数据校验,作者:叶叶,于2012年11月5日在网易博客上发表。
页面地址:/blog/static/1972410212012105398312/ 。
本论文全文及相关配套程序可以在上述页面中下载。
请尊重他人劳动成果,转载或引用时请注明出处。
目录1 技术简介 (3)2 Adler-32算法 (4)2.1 简介 (4)2.2 实现 (4)2.3 优化 (6)2.4 分析 (7)3 CRC-32算法 (7)3.1 简介 (7)3.2 实现 (8)3.3 优化 (10)3.4 反转CRC (14)3.5 分析 (16)4 MD5算法 (16)4.1 简介 (16)4.2 实现 (16)4.3 优化 (23)4.4 分析 (23)5 SHA算法族 (25)5.1 简介 (25)5.2 SHA-1算法实现 (26)5.3 SHA-256算法实现 (32)5.4 SHA-224算法实现 (39)5.5 SHA-512算法实现 (39)5.6 SHA-384算法实现 (47)5.7 SHA-512/224算法实现 (48)5.8 SHA-512/256算法实现 (49)5.9 优化 (49)5.10 分析 (51)6 结束语 (52)参考文献 (52)附录A 项目说明 (53)A.1 程序项目 (53)A.2 算法实现文件 (54)A.3 算法测试 (55)Delphi下实现数据校验作者:叶叶(网名:yeye55)摘要:介绍了数据校验的基本知识。
对Adler-32算法、CRC-32算法、MD5算法、SHA-1算法、SHA-224算法、SHA-256算法、SHA-384算法、SHA-512算法、SHA-512/224算法和SHA-512/256算法进行了逐一的介绍,并对这些算法的优化和安全性进行了讨论。
同时给出一个在Delphi 7.0下开发,可以对文件进行数据校验的应用程序。
关键词:数据校验;Adler-32;CRC-32;反转CRC;MD5;SHA;Delphi中图分类号:TP301.61 技术简介数据校验(Data Check)最早被用在数据传输领域中。