본문 바로가기
PLC 전기제어 기술자료/PLC를 함수화 해보자!

[MELSEC] PLC 프로그램을 함수화 해보자 -7- (모든 CRC-16 코드 생성)

by 위치결정 2023. 5. 9.
반응형

< XCALL 을 활용한 CRC-16 MSB 우선 코드 생성 함수 예제 >

 

< XCALL 을 활용한 CRC-16 LSB 우선 코드 생성 함수 예제 >

 

지난 글에서 CRC-16/MODBUS 를 생성하는 함수를 만들었었습니다. 이를 통해서 시리얼통신을 이용하여 MODBUS RTU 프로토콜로 교신시 CRC-16 체크섬 코드를 생성하여 송수신 할수 있죠.

 

하지만 CRC-16 코드는 MODBUS만 있는게 아닙니다.

MODBUS 프로토콜에서 사용하는 다항식 0x8005 를 사용하는 CRC-16 알고리즘만 살펴봐도 USB, BUYPASS, ARC, MAXIM 등 다양하게 있고

CCITT 로 대표되는 다항식 0x1021 을 사용하는 CRC-16 알고리즘도 CCITT-FALSE, AUG-CCITT, XMODEM, GENIBUS 등등 다양하게 있습니다.

 

그럼 이 CRC-16 알고리즘들은 어떤 구분점을 갖고 어떤 차이를 가지고 있는가?

그것은 이전에 MODBUS용 CRC-16을 만들어보면서도 잠깐 스터디 했지만 나름 깊게 공부하지 않으면 생성 원리가 복잡해서 머리가 어질어질할 지경이더군요. 사실은 지금도 100% 이해는 하지못했기 때문에 좀더 시간을 내서 스터디를 해야합니다.

 

하지만 중요한것은 결과죠. PLC에서도 더이상 CRC-16 코드 때문에 고생할 이유가 없습니다.

C나 C++, C# 처럼 공개된 CRC-16 알고리즘을 사용하듯, PLC에서도 그렇게 하면 됩니다.

 

구체적인것은 생략하고 오늘은 샘플 프로그램에 대한 설명으로 글을 마치려고 합니다.

crc_lsbmsb_230509.gxw
1.46MB

< 프로그램의 구성 >

다항식(poly) 0x8005를 사용하는 CRC-16 코드의 생성 샘플

다항식(poly) 0x1021을 사용하는 CRC-16 코드의 생성 샘플

P4003 : CRC-16 MSB 형식을 생성하는 펑션

P4004 : CRC-16 LSB 형식을 생성하는 펑션

각각 생성하려는 CRC-16 코드의 규칙에 맞추어 XCALL 명령어등을 이용하여 호출하면 됩니다.

 

ZR0900 : 원본 문자열 (입력값)

D0910 : 문자열을 바이트 캐릭터 단위로 분리 저장영역 (WTOB 버퍼)

D0990 : CRC-16 코드 생성 결과값

 

함수의 첫번째 파라미터 FD0 : CRC-16 코드 생성시 문자열 참조 시작포인트

함수의 두번째 파라미터 FD1 : CRC-16 코드 생성시 문자열 참조 종료포인트

함수의 두번째 파라미터 FD2 : CRC-16 코드 생성시 XOR 연산에 사용할 다항식

함수의 두번째 파라미터 FD3 : CRC-16 코드 생성시 초기값

함수의 세번째 파라미터 FD2 : CRC-16 코드 생성 결과 리턴값

 

 

< 프로그램 함수 사용 방법 >

함수를 호출하여 CRC-16을 생성시 참조할 원본데이터는 ZR900 영역에 씁니다.

이번 샘플로직에는 문자열 "ABCD" 를 넣어보겠습니다.

 

CRC-16/MODBUS 를 생성하기위해 XCALL 을 이용하여 MSB 용 CRC-16 함수를 호출합니다.

시작포인트는 1번 문자부터

종료포인트는 4번 문자 까지를 참조하고,

이때 XOR연산의 다항식은 0x8005

초기값은 0xFFFF 이므로 이를 입력해줍니다.

결과값은 D4로 받아보도록 하죠.

 

다항식은 뭐고 초기값은 뭔데 이런것들을 어떻게 알수 있냐고 물으신다면

그것은 CRC 코드 계산기 웹페이지를 이용하면 금방 알수있습니다.

 

https://crccalc.com/

 

Online CRC-8 CRC-16 CRC-32 Calculator

Input: ASCII HEX

crccalc.com

 

CRC 계산 웹페이지에서 CRC-16/MODBUS 의 규칙을 보면 많은것을 알수있습니다.

 

다항식(Poly) 는 0x8005 임을 알수있고, 초기값(Init)은 0xFFFF 임을 알수있죠.

그리고 RefIn과 RefOut이 true 인 경우가 MSB 형식입니다.

반대로 RefIn과 RefOut이 false 인 경우는 LSB 형식이 됩니다.

마지막으로 XorOut 항목의 경우 마지막 결과값의 CRC코드를 반전할것이냐에 대한 규칙입니다.

 

이 알고리즘 규칙을 좀더 자세히 알고싶다면 다음 페이지에서 스터디가 가능합니다.

https://pidlaboratory.com/9-rozne-algorytmy-crc/

 

9. Different CRC algorithms – How does it work? Automatics, computers, etc…

How does CRC work? Chapter  9 Different CRC algorithms Chapter. 9.1 Introduction The chapter 4 CRC arithmetic is a all CRC algorithms base. 1 bit shifts algorithm is realised on registers–>chapter 5 CRC Calculations. Programers use bytes mostly, not b

pidlaboratory.com

 

잠시후 CRC계산기 웹페이지에 있는 모든 CRC-16 코드를 생성해보면서 좀더 알아보도록 합니다.

 

아무튼 다시 돌아와서 "ABCD" 의 모드버스용 CRC-16코드를 생성해보니 0x0F85 가 생성되었네요.

계산기 웹페이지의 Result 에도 동일하게 0x0F85 가 맞는지 확인하여 일치되는지 체크되었으면 정상적으로 생성되었는지 확인이 가능합니다.

 

잘 생성된것 같네요.

 

모드버스와 같은 다항식 0x8005 를 사용하는 다른 CRC-16도 생성해볼까요?

위에서 스터디한것처럼 계산기 페이지에서 "ABCD" 를 이용하여 CRC-16 코드를 생성해보니 아래와 같네요.

그럼 다항식(Poly), 초기값(Init), RefIn, RefOut 을 체크하여 각각 함수를 호출해보겠습니다.

 

다항식(Poly)은 모두 0x8005 이므로 똑같이 작성후, 초기값(Init) 값을 입력해주고

RefIn, RefOut이 True 인 경우는 MSB용 펑션인 P4003을 호출하고

RefIn, RefOut이 False 인 경우는 LSB용 펑션인 P4004를 호출합니다.

결과는 한번 직접 비교해보셔도 좋을것 같네요.

그럼 CRC-16 코드로 인해서 스트레스 받으실 분들이 한분이라도 줄기를 바랍니다. :)

반응형

댓글