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

PLC 범용 CRC-16 함수화 : 다항식 가변으로 CCITT·XMODEM·ARC까지 (함수화 7편)

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

이전 글 — 함수화 6편: CRC-16/MODBUS 코드 생성

미쓰비시 PLC에서 다항식(Poly)·초기값(Init)을 파라미터로 받아 어떤 CRC-16 알고리즘이든 생성하는 범용 함수를 다룹니다.
MODBUS 전용에 묶이지 않고 CCITT·XMODEM·ARC 등 공개된 CRC-16 규칙을 그대로 PLC에서 계산할 수 있습니다.

지난 6편에서 CRC-16/MODBUS 생성 함수를 만들어, 시리얼 통신으로 MODBUS RTU 교신 시 CRC-16 체크섬을 송수신할 수 있었습니다.
하지만 CRC-16 코드는 MODBUS 만 있는 것이 아닙니다.

 

 

1. CRC-16 은 MODBUS 만 있는 것이 아니다

MODBUS 프로토콜이 사용하는 다항식 0x8005 계열만 봐도 USB, BUYPASS, ARC, MAXIM 등 다양합니다.

CCITT 로 대표되는 다항식 0x1021 계열도 CCITT-FALSE, AUG-CCITT, XMODEM, GENIBUS 등 종류가 많습니다.

이 CRC-16 알고리즘들이 어떤 구분점과 차이를 가지는지는 생성 원리가 복잡해 깊게 파고들면 머리가 어질어질할 정도입니다.

하지만 중요한 것은 결과입니다.
C·C++·C# 처럼 공개된 CRC-16 알고리즘을 가져다 쓰듯, PLC에서도 다항식·초기값만 파라미터로 넣어 주면 됩니다.
더 이상 CRC-16 코드 때문에 고생할 이유가 없습니다.

이 시리즈는 역할을 나눠 둡니다. CRC 가 왜 그렇게 계산되는가(자리올림 없는 나눗셈 = XOR·시프트 생성 원리)Modbus 입문 가이드 2편 에서 손계산까지, MSB/LSB 시프트와 SM700 캐리 래더 구현 세부함수화 6편의 "함수 내부 동작" 섹션 에서 다룹니다. 이 글(7편)은 그 위에서 다항식·초기값만 바꿔 어떤 규칙이든 뽑아내는 범용화에 집중합니다.

 

crc_lsbmsb_230509.gxw
1.46MB

2. 프로그램 구성: MSB / LSB 두 펑션

이 샘플은 다항식 0x80050x1021 을 쓰는 CRC-16 코드를 생성하며, 두 개의 펑션으로 구성됩니다.

 

  • P4003 : CRC-16 MSB 우선 형식을 생성하는 펑션
  • P4004 : CRC-16 LSB 우선 형식을 생성하는 펑션

 

생성하려는 CRC-16 코드의 규칙(RefIn·RefOut)에 맞춰 XCALL 명령으로 둘 중 하나를 호출하면 됩니다.

 

 

함수의 인수와 작업 영역은 다음과 같습니다.
6편 MODBUS 전용 함수에 다항식·초기값 두 인수가 추가되어 범용으로 확장된 형태입니다.

구분 디바이스 역할
1번째 파라미터 FD0 CRC-16 생성 시 문자열 참조 시작 포인트
2번째 파라미터 FD1 CRC-16 생성 시 문자열 참조 종료 포인트
3번째 파라미터 FD2 XOR 연산에 사용할 다항식(Poly)
4번째 파라미터 FD3 CRC-16 생성 초기값(Init)
5번째 파라미터 FD4 CRC-16 생성 결과 리턴값
입력 영역 ZR0900 원본 문자열 (입력값)
작업 버퍼 D0910 문자열을 바이트 캐릭터 단위로 분리 저장 (WTOB 버퍼)
결과 영역 D0990 CRC-16 코드 생성 결과값

3. 사용 방법: 문자열 "ABCD" 예제

함수 호출 시 참조할 원본 데이터는 ZR0900 영역에 씁니다.
이번 샘플 로직에는 문자열 "ABCD" 를 넣어 보겠습니다.

 

 

CRC-16/MODBUS 를 생성하기 위해 XCALL 로 MSB 용 펑션을 호출합니다.

 

  • 시작 포인트 : 1번 문자부터
  • 종료 포인트 : 4번 문자까지 참조
  • XOR 다항식 : 0x8005
  • 초기값 : 0xFFFF

 

결과값은 D4 로 받아 보겠습니다.

 

4. CRC 계산기로 알고리즘 규칙 파악

다항식과 초기값을 어떻게 알 수 있냐면, CRC 코드 계산기 웹페이지를 이용하면 금방 확인됩니다.

Online CRC-8 CRC-16 CRC-32 Calculator (crccalc.com)

 

 

계산기에서 CRC-16/MODBUS 규칙을 보면 다음을 알 수 있습니다.

 

  • 다항식(Poly) : 0x8005
  • 초기값(Init) : 0xFFFF
  • RefIn·RefOut 이 true → MSB 형식 (펑션 P4003)
  • RefIn·RefOut 이 false → LSB 형식 (펑션 P4004)
  • XorOut : 마지막 결과 CRC 코드를 반전할지에 대한 규칙
💡 TIP

RefIn·RefOut 이 MSB/LSB 펑션(P4003/P4004)을 가르는 이유 — 비트를 어느 쪽부터 밀어 넣느냐에 따라 우시프트(SFR, bit0 캡처)와 좌시프트(SFL, bit15 캡처)로 갈립니다. 그 래더 동작은 함수화 6편의 "함수 내부 동작" 섹션 에서 SM700 캐리 분기로 설명합니다.

알고리즘 규칙을 더 자세히 알고 싶다면 다음 페이지에서 학습할 수 있습니다.

9. Different CRC algorithms – How does it work? (pidlaboratory.com)

 

 

"ABCD" 의 MODBUS 용 CRC-16 을 생성해 보니 0x0F85 가 나왔습니다.
계산기 웹페이지의 Result 값과 일치하는지 확인하면 정상 생성 여부를 검증할 수 있습니다.

5. 다른 다항식의 CRC-16 도 생성하기

MODBUS 와 같은 다항식 0x8005 를 쓰는 다른 CRC-16 도 생성해 봅니다.
계산기 페이지에서 "ABCD" 로 각 알고리즘의 결과를 확인할 수 있습니다.

 

 

다항식(Poly)은 모두 0x8005 이므로 똑같이 작성한 뒤, 각 알고리즘의 초기값(Init)을 입력해 줍니다.

 

  • RefIn·RefOut 이 true 인 경우 → MSB 용 펑션 P4003 호출
  • RefIn·RefOut 이 false 인 경우 → LSB 용 펑션 P4004 호출

 

 

결과는 계산기 값과 직접 비교해 보면 좋습니다.

마무리

다항식과 초기값을 파라미터로 받도록 함수를 만들어 두면, MODBUS 뿐 아니라 CCITT·XMODEM·ARC 등 어떤 CRC-16 규칙이든 PLC에서 생성할 수 있습니다.
이제 CRC-16 코드 때문에 스트레스받는 분이 한 분이라도 줄기를 바랍니다.

💡 TIP

MODBUS 전용(0xA001 고정) 함수, 그리고 SFR·SM700·FOR~NEXT 래더 내부 동작 해설은 함수화 6편: CRC-16/MODBUS 코드 생성 에서 다룹니다.
CRC-16 의 생성 원리(나눗셈·XOR·시프트)는 Modbus 입문 가이드 2편: CRC-16 생성 원리와 수신 데이터 파싱 에서 다룹니다.

728x90
반응형