|
C++에 익숙하지 않아서 많이 헷갈리네요.
아래 코드좀 컨버팅 해주세요.
{=======================================================================================================================
설명 : 한 Char의 Position번째의 bit가 Set인지 Set이 아닌지 검사한다
매개 : Ch : 검사할 대상, Position : 검사할 위치
반환 : Set이면 True, Unset이면 False
주의 :
예제 : Ch = #$31 (0011 0001)
7654 3210번째
Position = 7 Position = 0
Result = False Result = True
=======================================================================================================================}
function TForm1.BitStatus(Ch:Char; Position:Byte):Boolean;
begin
if ((Byte(Ch) shr Position) and $01) = $01 then Result := True else Result := False;
end;
{=======================================================================================================================
설명 : 한 Char의 Position번째의 bit가 Set인지 Set이 아닌지 검사한다
매개 : Ch : 검사할 대상, Position : 검사할 위치
반환 : Set이면 True, Unset이면 False
주의 :
예제 : Ch = #$31 (0011 0001)
7654 3210번째
Position = 7 Position = 0
Result = False Result = True
=======================================================================================================================}
//function TForm1.BitStatus(Ch:Byte; Position:Byte):Boolean;
//begin
// if ((Ch shr Position) and $01) = $01 then Result := True else Result := False;
//end;
{=======================================================================================================================
설명 : 한 Char의 Index번째 비트를 Set시킨다.
매개 : Ch:Set시킬 Char , Index:Set시킬 위치
반환 : Set된 한 Char
주의 :
예제 : Ch = #$30 (0011 0000)
7654 3210번째
Index = 2
Result = #$34 (0011 0100)
=======================================================================================================================}
procedure TForm1.BitSet(var Ch:char; Index:Integer);
var
TmpCh : Byte;
begin
TmpCh := $01;
TmpCh := TmpCh shl Index;
Ch := Char(Byte(Ch) or TmpCh);
end;
{=======================================================================================================================
설명 : 한 Char의 Index번째 비트를 Set시킨다.
매개 : Ch:Set시킬 Char , Index:Set시킬 위치
반환 : Set된 한 Char
주의 :
예제 : Ch = #$30 (0011 0000)
7654 3210번째
Index = 2
Result = #$34 (0011 0100)
=======================================================================================================================}
procedure TForm1.BitUnSet(var Ch:char; Index:Integer);
var
tmpCh : Char;
begin
tmpCh := #$00;
BitSet(TmpCh,Index);
Ch := Char(Byte(ch) and (not Byte(TmpCh)));
end;
{=======================================================================================================================
설명 : 한 Char의 Index번째 비트를 Set시킨다.
매개 : Ch:Set시킬 Char , Index:Set시킬 위치
반환 : Set된 한 Char
주의 :
예제 : Ch = #$30 (0011 0000)
7654 3210번째
Index = 2
Result = #$34 (0011 0100)
=======================================================================================================================}
procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
begin
ComPort.Read(Com_Buff, Count);
ReadProc(Com_Buff, Count);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MakeCRC16Table($1021);
LoadIni;
if Line_Status = 0 then Line_Lbl.Caption := '상 행'
else Line_Lbl.Caption := '하 행';
ComPort.Open;
end;
{=======================================================================================================================
설명 : CRC16 값을 계산한다
매개 : CrcValue: CRC 값, CrcCh: CRC문자
반환 : 2바이트의 CRC 계산값
주의 :
=======================================================================================================================}
function TForm1.GetCRC16Each(crcValue: Word; crcCh : Char): Word;
var
crcPo : Byte;
begin
crcPo := (crcValue shr 8) xor Byte(crcCh);
Result := (crcValue shl 8) xor crc16Tbl[crcPo];
end;
{=======================================================================================================================
설명 : CRC16 Table 생성
매개 : 다항식
반환 : 없음
주의 :
=======================================================================================================================}
procedure TForm1.MakeCRC16Table(wPoly: Word);
var
i, j, crc_accum : DWord;
begin
for i := 0 to 255 do
begin
crc_accum := (i shl 8);
crc16Tbl[i] := 0;
for j := 8 downto 1 do
begin
if ((crc_accum xor crc16Tbl[i]) and $8000) <> 0 then crc16Tbl[i] := (crc16Tbl[i] shl 1) xor wPoly
else crc16Tbl[i] := crc16Tbl[i] shl 1;
crc_accum := crc_accum shl 1;
end;
end;
end;
{=======================================================================================================================
설명 : Start Code Check
매개 : Ch : 포트를 통해서 들어온 Char
반환 : 없음
주의 :
=======================================================================================================================}
procedure TForm1.StartCheck(Ch: Char);
begin
if (Ch = #$4E) then //$4E(N)-NextInfomation
begin
rsComBuff := rsComBuff + Ch;
Inc(rsComLen);
if rsComLen = 3 then
begin
RStartCode := #$4E+#$4E+#$4E;
rsComMode := 1;
rsComBuff := '';
rsComLen := 0;
end;
end else
begin
rsComMode := 0;
rsComBuff := '';
rsComLen := 0;
end;
end;
{=======================================================================================================================
설명 : Header Check
매개 : Ch : 포트를 통해서 들어온 Char
반환 : 없음
주의 :
=======================================================================================================================}
procedure TForm1.HeaderCheck(Ch: Char);
begin
Inc(rsComLen);
rsComBuff := rsComBuff + Ch;
if rsComLen = 3 then
begin
RID1 := Char(rsComBuff[1]);
//RID2 := Char(rsComBuff[2]);
RCmd := Char(rsComBuff[2]);
RDataLength := Byte(rsComBuff[3]);
RData := '';
if RDataLength = 0 then rsComMode := 3 else rsComMode := 2;
rsComBuff := '';
rsComLen := 0;
end;
end;
{=======================================================================================================================
설명 : Data Check
매개 : Ch : 포트를 통해서 들어온 Char
반환 : 없음
주의 : Header Check에서 저장한 길이만큼 데이터 입력
=======================================================================================================================}
procedure TForm1.DataCheck(Ch: Char);
begin
Inc(rsComLen);
rsComBuff := rsComBuff + Ch;
if rsComLen >= RDataLength then
begin
RData := rsComBuff;
RDataLength := Length(RData);
rsComMode := 3;
rsComBuff := '';
rsComLen := 0;
end;
end;
{=======================================================================================================================
설명 : CRC Check
매개 : Ch : 포트를 통해서 들어온 Char
반환 : 없음
주의 : 입력된 CRC 데이터와 자체적으로 계산한 CRC 비교 검사
=======================================================================================================================}
procedure TForm1.CRCCheck(Ch: Char);
var
test: Integer;
Test_Crc: Word;
TmpStr : string;
Loop: Integer;
begin
Inc(rsComLen);
rsComBuff := rsComBuff + Ch;
if rsComLen = 2 then
begin
//TmpStr := RID1 + RID2 + RCmd + Char(RDataLength) + RData;
TmpStr := RID1 + RCmd + Char(RDataLength) + RData;
for Loop := 1 to Length(TmpStr) do RCRC := GetCRC16Each(RCRC, TmpStr[Loop]);
if ( RCRC = MakeWord(Byte(rsComBuff[2]), Byte(rsComBuff[1])) ) then
begin
RxProcess;
end;
RStartCode := '';
RData := '';
RCRC := 0;
rsComMode := 0;
rsComBuff := '';
rsComLen := 0;
end;
end;
procedure TForm1.RxProcess;
var
i: Integer;
Str_Buf: String;
begin
if RID1 = #$09 then
begin
if RCmd = #$A0 then
begin
if Line_Status = 0 then Up_Line_Dis
else Down_Line_Dis;
end;
end;
end;
|