반응형

무언가 복잡한 연산을 할 때

값만 다르고 연산 순서가 같다면?


같은 코드를 여러번 복사하여 사용할 필요 없이

하나의 프로그램을 만들고 호출만 하면 된다!


예) D0에 D2+D4*D6/D8 값을 넣고 싶다. D10에도, D100에도 값을 넣고 싶다.


C언어의 함수로 표현을 한다면...

D0 = CallBack(D2, D4, D6, D8) {}

D10 = CallBack(D12, D14, D16, D18) {}

int CallBack(Pr1, Pr2, Pr3, Pr4, Pr5){

    연산...

    return 결과

}


멜섹PLC에서는 하나의 CALL 명령어에서 5개의 파라미터 변수를 사용할 수 있다.

|-[ ]-[CALL Pn Pr1 Pr2 Pr3 Pr4 Pr5]-|


예제 내려받기

CALL 2017-01-22.gxw (Ver.1.550Y에서 작성 됨)


화면 설명

위 그림은 조건이 맞으면 P0 프로그램을 호출하는 코드이다.

ADRSET 명령어는 첫번째 디바이스 주소값을 두번째 디바이스에 저장하는 포인터 명령어이다.

포인터주소를 참조하려면 @를 앞에 붙인다.

D12306에 "123456" 이라는 문자열 값을 넣었다면,

D11980에는 D12306 디바이스의 메모리 주소가 32비트 숫자형으로 들어있다.

@D11980에는 "12" 라는 문자열 값이 들어있다(16비트). 즉, D12306과 @D11980는 같은 값이다.

포인트 지정으로 리턴값을 넘겨 받을 수 있다!

C언어와 비슷하지 않은가?


CALL 명령어는 프로그램 번호, 파라미터 변수로 구성되어 있다.

프로그램 번호는 아래 그림에서 P0으로 표시된 부분이며 왼쪽의 빈 영역을 더블클릭하면 번호를 설정할 수 있다.

해당 스텝을 호출하거나 점프할 때 사용한다.


파라미터는 만들어 놓은 프로그램에 값을 전달하기 위해 사용하는 변수이다.


P0 프로그램은 상시 실행되서는 안 된다!

필요할 때만 호출해서 사용하는 코드이므로 아래 그림처럼 FEND을 상시 스텝 마지막에 삽입해야 한다.

그럼 1스캔 하면서 FEND를 만나면 RET가 있는 스텝으로 점프하게 된다. 그 중간에 있는 코드는 실행되지 않는다.

CALL 명령어에서 지정한 파라미터 값은 FD0 ~ 4 디바이스에 저장된다.

FD0에는 D12306의 메모리 주소값이 들어있고

FD1에는 7이라는 숫자

FD2에는 D12504의 메모리 주소값이 들어있다.

이것을 각각 D11910, D11914, D11918에 DMOV(32비트 복사)를 하였다.


D12306의 값을 일단 임시 디바이스에 복사하고 싶다면?

BMOV @D11910 D11800 D11914 코드를 보면

D11910에는 D12306의 메모리 주소값이 들어있는데 이것을 BMOV D11910 처럼 사용하면 주소값이 복사될 뿐 값이 복사되는 것이 아니다.

그래서 @를 붙여서 메모리 주소값을 참조하여 그 값을 사용할 수 있는 것이다.

그럼 "123456        "이라는 문자열이 D11800으로 K7 값만큼 복사된다.

이것은 아래처럼 일일이 BMOV 코드를 사용한 것과 같다.

BMOV "123456        " D11800 K7

BMOV "23456      " D11800 K6

...여러번 반복


하지만 단순한 반복 코드를 사용하려고 CALL 명령어를 사용하는 것은 아니다.


예제 프로그램을 열어보면 알겠지만 복잡한 연산이 P0 프로그램에 포함되어 있다.

문자열을 분해하고 각 문자열을 숫자형으로 바꿔 바이너리로 반환하는 프로그램이다.


FEND 명령어를 썼다면 RET는 꼭 사용하자.

CALL 명령어가 실행되지 않으면 FEND까지 스텝이 실행되고 RET까지는 무시하고 그 이후로 실행된다. 곧 END를 만나면서 종료.


조건별로 코드를 실행하거나 점프하고 싶다면 스텝 점프 명령어(CJ)를 알아보라.

반응형

관련글