연습해답 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.1 Information and Knowledge for Automation 목차 패이지 교재구성... 2 S7-300 실제프로그램가능논리제어기.... 3 S7-400 실제프로그램가능논리제어기..... 4 시뮬레이터구성... 5 컨베이어모델구성... 6 Solution to 연습 1.1 해답 : 뺄셈연산후점프... 7 Solution to 연습 1.2 해답 : 곱셈연산후점프..... 8 연습 1.3 해답 : 라벨로점프... 9 연습 2.1 해답 : 지수계산.... 10 연습 2.2 해답 : ACCU1에서의데이터교환.... 11 연습 2.3 해답 : 1의보수만들기..... 12 연습 3.1 해답 : 거리계산.... 13 연습 4.1 해답 : 메모리간접어드레스지정을이용한루프프로그래밍... 14 연습 4.2 해답 : 레지스터간접어드레스지정을이용한루프프로그래밍... 15 연습 4.3 해답 : 합계와평균값계산... 16 연습 5.1 해답 : SFC1을이용한시스템클럭읽기 (READ_CLK)... 17 연습 6.1 해답 : 작업장용 FB1 만들기... 18 연습 6.2 해답 : 전송용 FB2 만들기......21 연습 6.3 해답 : FB10 만들기... 24 연습 6.4 해답 : 고유카운터블록만들기.....26 연습 7.2 해답 : 데이터블록검사 (SFC 24: S7 400 전용 )... 27 연습 7.3 해답 : DB 만들기 (SFC 22).....28 연습 7.4 해답 : 로드메모리에서작업메모리로 DB 복사 (SFC 20).... 29 연습 7.5 해답 : 0 으로 DB 초기화 (SFC 21: FILL)..... 30 연습 7.6 해답 : 진단버퍼에메시지기록 (SFC 52)... 31 연습 8.1 해답 : FC43에서의오류처리... 32 연습 9.2 해답 : 완성된부품개수세기..... 34 연습 10.1해답 : SFB의 START/STOP을이용한통신... 42 연습 10.2 해답 : SFB의 GET/PUT을이용한통신... 45 Page 1
교재구성 후부에있는전원연결부와온 / 오프스위치 PCU 상에서의 MPI 연결 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.2 Information and Knowledge for Automation 교재내용물교재는다음요소들로구성됩니다 : - CPU 314 를장착한 S7-300 PLC 시스템 - 디지털입력및출력모듈, 아날로그모듈 - 디지털및아날로그부품으로된시뮬레이터 - 컨베이어모델 참고이교재는 S7-400 PLC 시스템에서도사용할수있습니다. Page 2
S7-300 실제프로그램가능한논리제어기 슬롯번호 : 1 2 4 5 6 7 8 9 10 버전 A (16 채널모듈 ) 블록유형 : PS CPU DI DI DQ DQ DI DQ 4AI/4AQ 입 / 출력어드레스 : 0 4 8 12 16 20 352 버전 B (32 채널모듈 ) 블록유형 : PS CPU DI DQ 8DI 2AI /8DQ 입 / 출력어드레스 : 0 4 8 304 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.3 Information and Knowledge for Automation 구성교육모델은다음모듈로구성됩니다 : 버전 A 슬롯 1: 전원공급장치 24V/5A 슬롯 2: CPU 314 슬롯 4: 디지털입력 16x24V 시뮬레이터스위치 슬롯 5: 디지털입력 16x24V 작은휠스위치 슬롯 6: 디지털출력 16x24V 0.5A 시뮬레이터의출력 LED 슬롯 7: 디지털출력 16x24V 0.5A 디지털디스플레이 슬롯 8: 디지털입력 16x24V 컨베이어모델입력 슬롯 9: 디지털출력 16x24V 0.5A 컨베이어모델출력 슬롯 10: 아날로그모듈 4 AI/4 AO 시뮬레이터에서조정가능 버전 B 슬롯 1: 전원공급장치 24V/5A 슬롯 2: CPU 314 슬롯 4: 디지털입력 32x24V 시뮬레이터스위치와작은휠스위치 Slot 5: 디지털출력 32x24V/0,5A 시뮬레이터의출력 LED와디지털디스플레이 Slot 6: 디지털모듈 8X24V/ 컨베이어모델 8x24V 0.5A Slot 7: 아날로그입력 시뮬레이터에서조정가능 어드레스 S7-300(CPU 312-314) 은고정슬롯어드레스지정방법을사용합니다. 따라서, Y 슬라이드에서모듈의어드레스를볼수있습니다. CPU 315-2 와 S7-400 을사용하는경우모듈의시작어드레스를매개변수로지정할수있습니다. Page 3
643-1QA11-0AX0 3 230 V 1 2 3 4 643-1QA11-0AX0 643-1QA11-0AX0 1 2 1 3 4 3 3 4 3 ATB 386SX INTFDI32xDC24V EXTF 421-1BL0 0-0A RUN CRST STOP RUN STOP S7-400 실제프로그램가능논리제어기 슬롯번호 : 1 4 8 9 10 11 12 IN TF X 3 BAT T1F BAT T2F BAF INTF EXTF DC 5V DC 24 V FRCE CRST 0 FMR 1 0 RUN STOP CRST WRST RUN-P RUN STOP CMRES BA T IND OFF O 블록유형 : PS CPU DI DI DQ DQ AI 기본입 / 출력어드레스 : 28 32 36 40 1216 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.4 Information and Knowledge for Automation 구성 이제어기는다음모듈로구성됩니다 : 슬롯 1,2, 3: 전원공급장치 220V/20A 슬롯 4: CPU 412, 414 또는 CPU 416 슬롯 5, 6, 7: 비어있음 (M7에서만사용됨 ) 슬롯 8: 디지털입력 32x24V 시뮬레이터의입력 슬롯 9: 디지털입력 32x24V 컨베이어모델의입력 슬롯 10: 디지털출력 32x24V 0.5A 시뮬레이터로전송되는출력 슬롯 11: 디지털출력 16x24V 0.5A 컨베이어모델로전송되는출력 슬롯 12: 아날로그입력모듈 8AI 시뮬레이터에서어드레스지정가능 어드레스 S7-400 의경우위의기본어드레스는기본어드레싱, 즉 CPU 에있는모듈에대한파라미터데이터 (SDB) 가로드되지않았을때만유효합니다. S7-400 의중앙랙에있는모듈의기본어드레스는다음공식에따라계산합니다. 디지털모듈 : ( 슬롯번호 -1) x 4 아날로그모듈 : ( 슬롯번호 - 1) x 64 + 512 모듈의초기어드레스는 S7400 시스템의 CPU 에맞춰자유롭게파라미터로지정할수있습니다. Page 4
시뮬레이터구성 DI DO.0.1.2.3.4.5.6.7.0.1.2.3.4.5.6.7.0.1.2.3.4.5.6.7.0.1.2.3.4.5.6.7 V -15V...+15V AI2 AO1-15V...+15V AI1 AO2 AI1 AI2 V 0 8 1 5 AI1 AI2 AO1 AO2 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.5 Information and Knowledge for Automation 구성 어드레스 시뮬레이터는두개의커넥터케이블을통해 S7-300 또는 S7-400 교육장치에연결됩니다. 시뮬레이터는세개의부품으로구성됩니다 : 16 개의스위치 / 푸시버튼이장착된이진부품과 4 곳의작은휠스위치및디지털디스플레이가장착된디지털부품. 제어는 BCD 값을통해발생합니다. 아날로그채널 0 과 1 또는아날로그출력 0 과 1 을표시하는전압계가장착된또하나의부품. 감시할전압값을선택스위치로선택할수있습니다. 아날로그입력을조정하는두개의분리된포텐셔미터도있습니다. 사용자프로그램에서다음과같은어드레스로 S7-300/400 용입력과출력의주소를지정합니다. 센서 / 작동기 S7-300 A S7-300 B S7-400 스위치 / 푸시버튼 IW 0 IW 0 IW 2 8 L E D s Q W 8 Q W 4 Q W 3 6 작은휠스위치 IW 4 IW 2 IW 3 0 디지털디스플레이 Q W 1 2 Q W 6 Q W 3 8 아날로그채널 PIW 352/354 PIW 304/306 PIW 1216/1218 Page 5
컨베이어모델구성 INI 1 ~ INI 3 인접스위치 LS 1 광전자개찰구 M 1 모터 H 1, H 2, H 3 LED S 1, S 2, S 3, S 4 인식스위치 SIMATIC S7 Siemens AG 1998. All rights reserved. Date: 10/18/99 File: PRO2_14e.6 Information and Knowledge for Automation 구성위의슬라이드는센서와작동기로구성된컨베이어모델의구성도입니다. S7-400 의경우어드레스는기본어드레스를사용하는 S7-400 모델의어드레싱을말합니다. 이들설정에대한변경사항은 HW Config 를통해입력이나출력모듈의어드레스를변경할때나타납니다. 모듈어드레스에대한변경사항의경우컨베이어모델의입력신호는두번째입력모듈 ( 슬롯 9) 상에서의입력이며컨베이어모델로전달되는출력신호는두번째출력모듈 ( 슬롯 11) 의출력입니다. 각경우에있어시뮬레이터의신호는첫번째입력과첫번째출력모듈에연결됩니다.. 어드레스 S7-300 A S7-300 B S7-4000 센서 / 작동기신호 I 16.0 I 8.0 I 32.0 광개찰구 LS 1 LS1 I 16.1 I 8.1 I 32.1 Ackn. 스위치위치 1 S1 I 16.2 I 8.2 I 32.2 Ackn. 스위치위치 2 S2 I 16.3 I 8.3 I 32.3 Ackn. 스위치위치 3 S3 I 16.4 I 8.4 I 32.4 Ackn. 스위치위치 4( 마지막 ) S4 I 16.5 I 8.5 I 32.5 기폭장치 1 INI1 I 16.6 I 8.6 I 32.6 기폭장치 2 INI2 I 16.7 I 8.7 I 32.7 기폭장치 3 INI3 Q 20.1 Q 8.1 Q 40.1 LED 위치 1 H1 Q 20.2 Q 8.2 Q 40.2 LED 위치 2 H2 Q 20.3 Q 8.3 Q 40.3 LED 위치 3 H3 Q 20.4 Q 8.4 Q 40.4 LED 위치 4 ( 마지막 ) H4 Q 20.5 Q 8.5 Q 40.5 컨베이어드라이브 ( 오른쪽 ) K1_LAUF Q20.6 Q 8.6 Q 40.6 컨베이어드라이브 ( 왼쪽 ) K2_LAUF Q 20.7 Q 8.7 Q 40.7 호른 ( 나팔 ) TUT1 Page 6
연습 1.1 해답 : FUNCTION FC 11 : VOID 연습 1.1 : 빼기연산후점프 //16Bit-SM 의버전 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 L IW 4; // 작은휠스위치 BTD ; //BCD를정수로포맷변환 L IW 0; // 입력워드 0 BTD; -D; JN NEG; // 결과가음수인경우점프 L IW 0; JU END; NEG: L 0; END: T QW 12; //7-세그먼트디스플레이 END_FUNCTION Page 7
연습 1.2 해답 : FUNCTION FC 12 : VOID 연습 1.2 : 곱하기연산후점프 //16Bit-SM 버전 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 L IW 4; // 썸휠스위치 BTD; //BCD에서정수로변환 L IW 0; // 시뮬레이터의토글스위치 BTD; *I; JO OVL; // 과잉이면점프 DTB; // 정수에서 BCD로변환 JU END; OVL: L 0; END: T QW 12; //7-세그먼트디스플레이 END_FUNCTION Page 8
연습 1.3 해답 : OB1 FUNCTION FC 13: VOID VAR_INPUT Select: INT; L #Select; OW W#16#FF00; // 255보다큰지또는 JCN Err; // 음수인지확인 JL GT5; // Accu1-L-L이 5보다크면대상으로점프 JU Err; // select = 0 ( 여기서는일어나지않음 ) JU Dr_1; // 오른쪽컨베이어 (select=1) JU Dr_2; // 왼쪽컨베이어 (select=2) JU Dr_3; // 컨베이어오프 (select=3) JU Ho_1; // 경적 (Horn) 온 JU Ho_2; // 경적오프 GT5: JU Err; Dr_1: S Q 4.5; // 오른쪽컨베이어 R Q 4.6; JU End; Dr_2: S Q 4.6; // 왼쪽컨베이어 R Q 4.5; JU End; Dr_3: R Q 4.5; // 컨베이어오프 R Q 4.6; JU End; Ho_1: S Q 4.7; // 경적 (Horn) 온 JU End; Ho_2: R Q 4.7; // 경적오프 JU End; Err: CLR; SAVE; End: BE; END_FUNCTION Page 9
연습 2.1 해답 : FUNCTION FC 21 : VOID 연습 2.1: AKKU 교환함수 // 연습 2.6: ACCU 교환함수 //16Bit-SM 용버전 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 L IB 4; //BCD 번호로드 BTI; //BCD를정수로변환 -> 입력값 PUSH; //ACCU1을 ACCU2에복사 *D; //ACCU1에 InVal의제곱값만들기 PUSH; //ACCU1에서 ACCU2로 InVal의제곱값복사 PUSH; //S7-400에필요함: 제곱값 -> ACCU3 *D; //ACCU1에최대4번째까지 InVal 만들기 *D; //ACCU1에최대6번째까지 InVal 만들기 DTB; // 가능할경우 BCD로변환 ( 선택사항 ) T QW 12; //7_ 세그먼트디스플레이 //LOW-Word 디스플레이 ( 선택사항 ) END_FUNCTION Page 10
연습 2.2 해답 : FUNCTION FC 22 : VOID 연습 2.2: ACCU1 에서의데이터교환 // 연습 2.2: ACCU1 에서의데이터교환 //16Bit-SM 용버전 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 L IW 4; //BCD 코드로된썸휠스위치 CAW; //ACCU1-L에서 2 바이트교환 T QW 12; // 결과표시 END_FUNCTION Page 11
연습 2.3 해답 : FUNCTION FC 23 : VOID 연습 1.6: 1 의보수만들기 // 연습 2.3: 보수만들기 //16Bit-SM 용버전 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 STL 의 1 의보수 L IW 0; // 입력워드 BCD 코드로드 INVI; //1의보수만들기 T QW 0; // 출력워드로결과표시 END_FUNCTION Page 12
연습 3.1 해답 : FUNCTION FC 31 : REAL 연습 3.1: 거리계산 // 연습 3.1: 산술함수 AUTHOR : PT41 FAMILY : A4_0 NAME : ST7PRO2 VERSION : 0.0 VAR_INPUT X1: REAL; Y1: REAL; X2: REAL; Y2: REAL ; VAR_TEMP XSquare : REAL; L X1; // P1의 X 좌표로드 L X2; // P2의 X 좌표로드 -R; // (X1-X2) 만들기 SQR; // (X1-X2) 의제곱값만들기 T XSquare; // TEMP-Var 안에임시저장 L Y1; // P1의 Y 좌표로드 L Y2; // P2의 Y 좌표로드 -R; // (Y1-Y2) 만들기 SQR; // ACCU1에 (Y1-Y2) 의제곱값만들기 L XSquare; // (X1-X2) 에서제곱값불러오기 +R; // 합계계산 SQRT; // 제곱근 ( 최종결과값 ) 만들기 T RET_VAL; // 결과값반환 END_FUNCTION Page 13
연습 4.1 해답 : 간접어드레싱을이용한루프프로그래밍 FUNCTION FC 41 : VOID 연습 4.1: 메모리간접어드레싱을이용한루프프로그래밍 // 연습 4.1: 메모리간접어드레싱을이용한루프프로그래밍 VAR_TEMP Tank : ARRAY [1.. 100 ] OF INT ; Counter : INT ; Ini_Value : INT ; Pointer : DWORD ; 루프프로그래밍 L P#0.0; // tank의첫번째구성요소의어드레스를로드하고 T #Pointer; // 포인트로전송 L 1; // 1을로드하고 T #Ini_Value; // Ini_Value로전송 L 100; // 100으로루프카운터를미리설정하고 BEGN: T #Counter; // 카운트에로드 L #Ini_Value; T LW [#Pointer]; // Ini_Value를 Tank[i] 로전송 L 1; // ACCU1 (Ini_Value) 을 1만큼 +I ; // 증가시키고 T #Ini_Value; // Ini_Value로전송 L #Pointer; // 포인터를 Accu1으로전송 L P#2.0; // Pointer의바이트어드레스를 2만큼증가시키고 +D ; // 포인터에 T #Pointer; // 로드 L #Counter; // 루프카운터로드 LOOP BEGN; // 값을감소시키고필요하다면점프 로컬데이터 (Local Data) 의상태표시를위한네트워크 L #Tank[1]; // 테스트전용 L #Tank[2]; L #Tank[3]; // " L #Tank[4]; L #Tank[5]; L #Tank[6]; L #Tank[7]; L #Tank[8]; L #Tank[9]; L #Tank[10]; L #Tank[64]; L #Tank[100]; END_FUNCTION Page 14
연습 4.2 해답 : 레지스터간접어드레싱을이용한루프프로그래밍 FUNCTION FC 42 : VOID 연습 4.2: 레지스터간접어드레싱을이용한루프프로그래밍 // 연습 4.2: 레지스터간접어드레싱을이용한루프프로그래밍 VAR_TEMP Tank : ARRAY [1.. 100 ] OF INT ; Loop counter : INT ; Ini_Value : INT ; 루프프로그래밍 LAR1 P#0.0; // AR1에첫번째구성요소의어드레스로드 L 1; // 1을 Accu1 (Ini_W.) 에 L 100; // 100을 Accu1 (loopc.) 에 ; 1을 Accu2 (Ini_Value) 에 BEGN: TAK ; // Accu2에루프카운터, Accu1에 Ini_V. T LW [AR1,P#0.0]; // Ini_Value를 Tank[i] 로전송 INC 1; // Ini_Value을증가시킴 +AR1 P#2.0; // AR1을 2 바이트만큼증가시킴 TAK ; // Accu1에루프카운터, Accu2에 Ini_V. LOOP BEGN; // 루프카운터를감소시키고필요하다면점프 로컬데이터 (Local Data) 의상태표시를위한네트워크 L #Tank[1]; L #Tank[2]; L #Tank[3]; L #Tank[4]; L #Tank[5]; L #Tank[6]; L #Tank[7]; L #Tank[8]; L #Tank[9]; L #Tank[10]; L #Tank[64]; L #Tank[100]; END_FUNCTION Page 15
연습 4.3 해답 : 합계및평균값계산함수 FUNCTION FC 43 : VOID 연습 4.3: 합계및평균값계산함수 // 연습 4.3: 합계와평균값계산함수 VAR_INPUT Measured_values : ANY ; VAR_OUTPUT Sum : REAL ; Mean_value : REAL ; VAR_TEMP Loop_counter : WORD ; DB_No : WORD ; L P##Meas_values; // ANY 포인터의영역포인터로드 LAR1 ; // AR1에있는영역포인터 L B [AR1,P#1.0]; // 데이터형식별자읽기 L 8; // 식별자 REAL(16#08) 로드 ==I ; JC REAL; // 데이터형이 REAL이면점프 NOP 0; // REAL이아닌데이터형을위한인스트럭션 CLR ; // RLO=0 SAVE ; // BR =0 L L#-1; // 잘못된 REAL 숫자로드 T #Sum; T #Mean_value; BEU ; REAL: NOP 0; // REAL 데이터형을위한인스트럭션 L W [AR1,P#2.0]; // 배열요소의개수로드 T #Loop_counter; // 루프카운터초기화 L W [AR1,P#4.0]; // DB 번호또는 0 로드 T #DB_No; // DB_No= 가 0이면 OPN DB[DB_No]=NOP OPN DB [#DB_No]; // DB가존재하지않는경우런타임오류!! L D [AR1,P#6.0]; // AR1에실질어드레스의영역포인터로드 LAR1 ; // 영역식별자가 "DI" 이면오류 L 0.000000e+000; // 0을 Accu1 (Sum =0.0) 에 L #Loop_counter; // 카운터를 ACCU1에, Sum=0을 ACCU2에 BEGN: TAK ; // ACCU2에 Loopc, ACCU1에합계 ENT ; // ACCU3에 Loopc, ACCU2에합계 L D [AR1,P#0.0]; // ACCU1에배열요소 +R ; // ACCU1에합계, ACCU2에 Loopc +AR1 P#4.0; // 4 바이트만큼 AR1을증가시킴 TAK ; // ACCY1에 Loopc, ACCU2에 Sum LOOP BEGN; // loopc를감소시키고필요하면점프 TAK ; // ACCU1에 Sum T #Sum; // 합계를 #Sum에 L #Loop_counter; // ACCU2에합계, ACCU1에개수 DTR ; // 부호가정의되지않은정수 (16비트) 를 REAL로 /R ; // ACCU1에평균값 T #Mean_value; // 평균값을 #Mean value에 SET ; // BR-Bit를 1로설정 SAVE ; END_FUNCTION Page 16
연습 5.1 해답 : SFC 1 를이용한시스템클럭읽기 (READ_CLK) FUNCTION FC 51 : VOID 연습 5.1: SFC 1 을이용한시스템클럭읽기 (READ_CLK) // 연습 5.1: SFC 1 를이용한시스템클럭읽기 (READ_CLK) //16Bit-SM 용버전 AUTHOR : PT41 FAMILY : A2_0 NAME : ST7PRO2 VERSION : 0.0 VAR_TEMP Date_Time : DATE_AND_TIME ; RET_VAL_SFC1 : INT ; SFC 1 (READ_CLK) call // 현재의날짜와시간 // 값 SFC 1 반환 CALL "READ_CLK" ( RET_VAL := #Ret_Val_SFC1, CDT := #Date_Time); NOP 0; 시간, 분표시 LAR1 P##Date_Time // 변수어드레스결정 L LB [AR1, P#3.0]; // 시간을읽고 T QB 12; // 디스플레이에출력 L LB [AR1, P#4.0]; // 분을읽고 T QB 13; // 디스플레이에출력 END_FUNCTION Page 17
연습 6.1 해답 : FB1 (1 부 ) FUNCTION_BLOCK "Station" VERSION : 0.1 VAR_INPUT Initial : BOOL ; Proxy_Switch : BOOL ; Acknowledge : BOOL ; Clock_Bit : BOOL ; VAR_OUTPUT LED : BOOL ; Transp_req : BOOL ; VAR_IN_OUT Conv_busy : BOOL ; VAR State : STRUCT Busy : BOOL ; Completed : BOOL ; Waiting : BOOL ; END_STRUCT ; Aux_1 : BOOL ; Aux_2 : BOOL ; 초기화 // 초기화를이용하여, 기본상태, 즉, 스테이션의상태설정 //"Busy" A #Initial; R #State.Waiting; S #State.Busy; R #State.Completed; R #Conv_busy; State: Busy // 처리가이상태로진행됩니다. 마지막으로작업자가 // 작업장확인버튼을통해부품의처리가완료되었음을확인하면 // 처리가종료됩니다. AN JC S R A R R S #State.Busy; REDY; #LED; #Transp_req; #Acknowledge; #State.Busy; #LED; #State.Completed; // ( 다음페이지에서계속 ) Page 18
연습 6.1 해답 : FB1 (2 부 ) 상태 : 완료 // 완료된상태에서는완료된부품이전송벨트상에놓여질때까지대기합니다. // 전송벨트에아무것도없으면입력신호 #Band_frei 가신호를보냅니다. REDY: AN #State.Completed; JC WAIT; A #Clock_Bit; = #LED; AN #Conv_busy; A #Proxy_Switch; S #Conv_busy; S #Transp_req; A #Transp_req; A #Proxy_Switch; FN #Aux_1; R #State.Completed; S #State.Waiting; 상태 : 대기 // 처리되지않은새로운부품을기다립니다. // 처리되지않은새로운부품이도착되면전송벨트의인접스위치가신호를보냅니다. WAIT: AN #State.Waiting; JC ENDE; R #LED; A #Proxy_Switch; // 처리되지않은새로운부품이도착됨 R #Transp_req; // 정지벨트 A #Proxy_Switch; FN #Aux_1; // 제거후에처리시작 R #Conv_busy; 다시한번컨베이어를활성화함 R #State.Waiting; S #State.Busy; ENDE: BEU ; END_FUNCTION_BLOCK Page 19
연습 6.1 해답 : OB1 ORGANIZATION_BLOCK OB 1 VERSION : 0.1 VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1 ( 들어오는이벤트 ), 비트 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드재시작스캔1), 3 (OB 1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 제어 : Station_1 CALL "Station", "Station_DB" ( Initial := I 0.0, Proxy_Switch := "INI1", Acknowledge:= "S1", Clock_Bit := M 10.1, LED := "H1"); END_ORGANIZATION_BLOCK Page 20
연습 6.2 해답 : FB2 (1 부 ) FUNCTION_BLOCK "Transport" 컨베이어제어 VERSION : 0.1 VAR_INPUT Initial : BOOL ; L_Barrier : BOOL ; Acknowledge : BOOL ; Transp_req : BOOL ; Clock_Bit : BOOL ; VAR_OUTPUT LED : BOOL ; Conv_right : BOOL ; Conv_left : BOOL ; VAR State : STRUCT Waiting : BOOL ; Conv_right : BOOL ; Assembly : BOOL ; Conv_left : BOOL ; END_STRUCT ; 초기화 A #Initial; S #State.Waiting; R #State.Conv_right; R #State.Assembly; R #State.Conv_left; 상태 : 대기 // 완성된부품을위해벨트가이상태에서대기함. AN #State.Waiting; JC RECH; R #Conv_right; R #Conv_left; R #LED; A #Transp_req; R #State.Waiting; S #State.Conv_right; 상태 : Conv_right // 이상태는완성된부품이직접최종어셈블리로전송되는과정을설명합니다. RECH: AN #State.Conv_right; JC ENDM; S #Conv_right; A #Clock_Bit; = #LED; AN #L_Barrier; R #Conv_right; R #State.Conv_right; S #State.Assembly; ( 다음페이지에서계속 ) Page 21
연습 6.2 해답 : FB2 (2 부 ) 상태 : 어셈블리 // 이상태에서는벨트에서완성된부품을제거하고처리되지않은새로운 // 부품을놓습니다. 그런후 S4를이용하여비어있는처리스테이션의방향으로 // 처리되지않은새로운부품의전송이시작됩니다. // ENDM: AN #State.Assembly; JC LINK; S #LED; A #Acknowledge; R #LED; R #State.Assembly; S #State.Conv_left; 상태 : Conv_left // 이상태에서완성된부품을전달한스테이션으로처리되지않은 // 새로운부품이전송됩니다. LINK: AN #State.Conv_left; JC ENDE; S #Conv_left; A #Clock_Bit; = #LED; AN #Transp_req; R #Conv_left; R #State.Conv_left; S #State.Waiting; ENDE: BEU ; END_FUNCTION_BLOCK Page 22
연습 6.2 해답 : OB1 ORGANIZATION_BLOCK OB 1 VERSION : 0.1 VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1( 들어오는이벤트 ), 비트 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드재시작스캔1), 3 (OB1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 제어 : Station_1 CALL "Station", "Station_DB" ( Initial := I 0.0, Proxy_Switch := "INI1", Acknowledge := "S1", Clock_Bit := M 10.1, LED := "H1", Transp_req := "Transport_DB".Transp_req); 제어 : 컨베이어 CALL "Transport", "Transport_DB" ( Initial := I 0.0, L_Barrier := "LS1", Acknowledge := "S4", Clock_Bit := M 10.1, LED := "H4", Conv_right := "K1 CONV", Conv_left := "K2_CONV"); END_ORGANIZATION_BLOCK Page 23
연습 6.3 해답 : FB10 (1 부 ) FUNCTION_BLOCK FB 10 VERSION : 0.1 VAR Station_1 : "Station"; Station_2 : "Station"; Station_3 : "Station"; Transport : "Transport"; Conv_busy : BOOL ; VAR_TEMP Trans_1 : BOOL ; Trans_2 : BOOL ; Trans_3 : BOOL ; Trans : BOOL ; Station_1 CALL #Station_1 ( Initial := I 0.0, Proxy_Switch := "INI1", Acknowledge := "S1", Clock_Bit := "CLOCK_BIT", LED := "H1", Transp_req := #Trans_1, Conv_busy := #Conv_busy); Station_2 CALL #Station_2 ( Initial := I 0.0, Proxy_Switch := "INI2", Acknowledge := "S2", Clock_Bit := "CLOCK_BIT", LED := "H2", Transp_req := #Trans_2, Conv_busy := #Conv_busy); Station_3 CALL #Station_3 ( Initial := I 0.0, Proxy_Switch := "INI3", Acknowledge := "S3", Clock_Bit := "CLOCK_BIT", LED := "H3", Transp_req := #Trans_3, Conv_busy := #Conv_busy); for Automation // ( 다음 and Drives 페이지에서계속 ) Page 24
연습 6.3 해답 : FB10; OB1 Logic: Transp_req //#Transp_req의논리만들기 O #Trans_1; O #Trans_2; O #Trans_3; = #Trans; Transport CALL #Transport ( Initial := I 0.0, L_Barrier := "LS1", Acknowledge := "S4", Transp_req := #Trans, Clock_Bit := "CLOCK_BIT", LED := "H4", Conv_right := "K1_CONV", Conv_left := "K2_CONV"); END_FUNCTION_BLOCK ORGANIZATION_BLOCK OB 1 VERSION : 0.1 VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1( 들어온는이벤트 ), 비트 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드시작스캔1), 3 (OB 1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 CALL FB 10, DB 10 ; END_ORGANIZATION_BLOCK Page 25
추가연습 6.4 해답 : DB6, FB6 DATA_BLOCK DB 6 FB 1 CU := FALSE; R := FALSE; PV := 0; Q := FALSE; CV := 0; Edge_memory_bit_CU := FALSE; Edge_memory_bit_R := FALSE; END_DATA_BLOCK FUNCTION_BLOCK FB 6 VAR_INPUT CU : BOOL ; R : BOOL ; PV : INT ; VAR_OUTPUT Q : BOOL ; CV : INT ; VAR Edge_memory_bit_CU : BOOL ; Edge_memory_bit_R : BOOL ; A #CU; // 카운트업시작 FP #Edge_memory_bit_CU; // 에지메모리비트설정 JCN NZHL; // 에지가없으면점프 L #CV; // 현재값로드 L 1; // 1 로드 +I ; // 16비트더하기 A OV; // 과잉? JCN NOVL; // 과잉이없으면점프 L 32767; // 그렇지않으면 : 최대값로드 NOVL: T #CV; // 결과를 CV로전송 NZHL: NOP 0; // 카운트업종료 // A #R; // 리셋시작 FP #Edge_memory_bit_R; // 에지메모리비트설정 JCN NRCK; // 에지가없으면점프 L 0; // 16비트상수인 0 로드 T #CV; // 현재값으로전송 NRCK: NOP 0; // 리셋종료 // L #CV; // 출력 Q 처리시작 L #PV; // 사전설정값로드 >=I ; // CV >= PV? = #Q; // RLO를출력Q로지정 END_FUNCTION_BLOCK Page 26
연습 7.2 해답 : 데이터블록검사 FUNCTION FC 72 : INT VERSION : 0.1 VAR_INPUT DB_No : WORD ; VAR_TEMP I_DB_Length : WORD ; I_RET_VAL : INT ; I_Write_Protect : BOOL ; DB 검사 CALL "TEST_DB" ( DB_NUMBER := #DB_No, RET_VAL := #I_RET_VAL, DB_LENGTH := #I_DB_Length, WRITE_PROT := #I_Write_Protect); L #I_RET_VAL; L W#16#0; ==I ; JC DBOK; // 작업메모리에서이용할수있는 DB TAK ; L W#16#80A1; ==I ; JC NODB; // CPU에서이용할수없는 DB TAK ; L W#16#80B1; ==I ; JC NODB; // 작업메모리에서이용할수없는 DB TAK ; L W#16#80B2; ==I ; JC DBLM; // 로드메모리에만있는 DB NODB: L -1; T #RET_VAL; // CPU에서이용할수없는 DB BEU ; DBLM: L 1; T #RET_VAL; // 로드메모리에만있는 DB BEU ; DBOK: L 0; T #RET_VAL; // 작업메모리에서이용할수있는 DB END_FUNCTION Page 27
연습 7.3 해답 : DB 만들기 ORGANIZATION_BLOCK OB 100 VERSION : 0.1 VAR_TEMP OB100_EV_CLASS : BYTE ; //16#13, 이벤트클래스 1, 이벤트상태로들어가기, // 진단버퍼에로그된이벤트 OB100_STRTUP : BYTE ; //16#81/82/83/84 시작방법 OB100_PRIORITY : BYTE ; //27 ( 우선순위 1이가장낮음 ) OB100_OB_NUMBR : BYTE ; //100 ( 조직블록 100, OB100) OB100_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB100_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB100_STOP : WORD ; //CPU를정지시킨이벤트(16#4xxx) OB100_STRT_INFO : DWORD ; // 시스템시작방법에관한정보 OB100_DATE_TIME : DATE_AND_TIME ; //OB 100 시작날짜와시간 DB10 만들기 CALL "CREAT_DB" ( LOW_LIMIT := W#16#A, // 십진수 10 (DB10) 과같음 UP_LIMIT := W#16#A, // " COUNT := W#16#28, // 십진수 40 (40 바이트 ) 과같음 RET_VAL := MW 0, DB_NUMBER := QW 12); END_ORGANIZATION_BLOCK Page 28
연습 7.4 해답 : 로드에서작업메모리로 DB 복사 ORGANIZATION_BLOCK OB 1 // 로드에서작업메모리로 DB 복사 VERSION : 2.10 VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1 ( 들어오는이벤트 ), Bits 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드재시작스캔1), 3 (OB1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 CALL "BLKMOV" ( SRCBLK := P#DB10.DBX 0.0 BYTE 40, RET_VAL := QW 12, DSTBLK := P#DB20.DBX 0.0 BYTE 40); END_ORGANIZATION_BLOCK Page 29
연습 7.5 해답 : DB 초기화 FUNCTION FC 75 : BOOL // 연습 7.5: DB 초기화 (S7-400 전용 ) VERSION : 0.1 VAR_INPUT DB_NUM : WORD ; INI : BYTE ; VAR_TEMP I_RET_VAL : INT ; I_DB_Length : WORD ; I_WRITE_PROT : BOOL ; I_ANY : ANY ; DB_No : WORD ; I_INI : BYTE ; I_RET_VAL1 : INT ; //DB가작업메모리에있는지확인하고필요할경우초기화합니다. CALL "TEST_DB" ( DB_NUMBER := #DB_NUM, RET_VAL := #I_RET_VAL, DB_LENGTH := #I_DB_Length, WRITE_PROT := #I_WRITE_PROT); L #I_RET_VAL; L W#16#0; ==I ; // 작업메모리에들어있는 DB AN #I_WRITE_PROT; JC OK; CLR ; // 초기화할수없음 = #RET_VAL; // 거짓 (FALSE) 반환 BEU ; OK: LAR1 P##I_ANY; // 임시변수 ANY 지정 L B#16#10; // ANY의식별자를 T LB [AR1,P#0.0]; // 바이트-오프셋 0에 L B#16#2; // BYTE 데이터형의식별자를 T LB [AR1,P#1.0]; // 바이트-오프셋 1에 L #I_DB_Length; // DB 길이를바이트로 T LW [AR1,P#2.0]; // 바이트-오프셋 2에로드 L #DB_NUM; // DB 번호를 T LW [AR1,P#4.0]; // 바이트-오프셋 4에로드 L P#DBX 0.0; // DBX0.0의포인터를 T LD [AR1,P#6.0]; // 바이트-오프셋 6에로드 L #INI; // 초기화바이트를 T #I_INI; // 임시변수에 CALL "FILL" ( BVAL := #I_INI,// 임시변수에만사용 RET_VAL := #I_RET_VAL, BLK := #I_ANY); SET ; = #RET_VAL; BE ; END_FUNCTION Page 30
연습 7.6 해답 : 진단버퍼에메시지기록 (SFC 52) FUNCTION FC 76 : VOID // 연습 7.6: 진단버퍼에메시지기록 (SFC 52) VERSION : 0.0 VAR_TEMP I_RET_VAL : INT ; info1 : WORD ; info2 : DWORD ; L T L T W#16#8; #info1; W#16#1; #info2; CALL "WR_USMSG" ( SEND := TRUE, EVENTN := W#16#9B0A, INFO1 := #info1, INFO2 := #info2, RET_VAL := #I_RET_VAL); END_FUNCTION Page 31
연습 8.1 해답 : FC43 에서의오류처리 (1 부 ) FUNCTION FC 81 : INT 연습 8.2: 오류처리가있는합계, 평균값계산 //S7-400 용해답 VERSION : 0.0 VAR_INPUT Measured_values : ANY ; VAR_OUTPUT Sum : REAL ; Mean_value : REAL ; VAR_TEMP Loop_counter : WORD ; DB_No : WORD ; Sum_1 : REAL ; sfc_ret_val : INT ; sfc_prgflt : DWORD ; sfc_accflt : DWORD ; L P##Measured_values; // ANY 포인터의영역포인터로드 LAR1 ; // AR1에영역포인터 L B [AR1,P#1.0]; // 데이터형식별자읽기 L 8; // 식별자 REAL(16#08) 로드 ==I ; L -1; // 데이터형식별자가 REAL이아님 JCN ERRO; // 데이터형이 REAL이아니면점프 // 마스크동기화오류 : 호출했던 DB가존재하지않음 // 전역 DB의오류번호 // 인스턴스 DB의오류번호, // 읽기에서영역오류,, // 읽기에서영역길이오류 CALL "MSK_FLT" ( PRGFLT_SET_MASK := DW#16#40C0014, ACCFLT_SET_MASK := DW#16#0, RET_VAL := #sfc_ret_val, PRGFLT_MASKED := #sfc_prgflt, ACCFLT_MASKED := #sfc_accflt); L W [AR1,P#2.0]; // 배열요소의개수로드 T #Loop_counter; // 루프카운터초기화 L W [AR1,P#4.0]; // DB 번호또는 0 로드 T #DB_No; // DB_No=0이면 OPN DB[DB_No]=NOP OPN DB [#DB_No]; // 런타임오류!!, DB가존재하지않는경우 L D [AR1,P#6.0]; // AR1에실질어드레스의영역포인터로드, LAR1 ; // 오류!! 영역식별자가 "DI" 이면 L 0.000000e+000; // 0을 Accu1 ( 합계 =0.0) 에 L #Loop_counter; // 카운터를 ACCU1에, Sum=0을 ACCU2에 // ( 다음페이지에서계속 ) Page 32
연습 8.1 해답 : FC43 에서의오류처리 (2 부 ) BEGN: TAK ; // ACCU2에 Loopc, ACCU1에합계 ENT ; // ACCU3에 Loopc, ACCU2에합계 L D [AR1,P#0.0]; // ACCU1에배열요소 +R ; // ACCU1에합계, ACCU2에 Loopc +AR1 P#4.0; // Ar1을 4 바이트만큼증가시킴 TAK ; // ACCU1에 Loopc, ACCU2에합계 LOOP BEGN; // Loopc를감소시키고필요한경우점프 TAK ; // ACCU1에합계 T #Sum_1; // 합계를 #Sum에 // 오류평가 CALL "READ_ERR" ( PRGFLT_QUERY := DW#16#40C0014, ACCFLT_QUERY := DW#16#0, RET_VAL := #sfc_ret_val, PRGFLT_CLR := #sfc_prgflt, ACCFLT_CLR := #sfc_accflt); L #sfc_prgflt; // 잘못된 DB 확인 L DW#16#40C0000; UD ; // Biweises 반올림 " L -2; // DB의오류코드가존재하지않음 JZ ERRO; // 오류이면점프 L #sfc_prgflt; // 영역또는영역길이오류가있는지확인 L DW#16#14; UD ; L -4; // 영역또는영역길이오류의식별자 JZ ERRO; // 오류이면점프 // 오류가발생하지않았으면 정상 처리과정을진행 L #Sum_1; L #Loop_counter; // ACCU2에합계, ACCU1에개수 DTR ; // 부호가정의되지않은정수 (16비트) 를 REAL에 /R ; // ACCU1에평균값 T #Mean_value; // #Mean_value에평균값 SET ; // BR 비트를 1로설정 SAVE ; L 0 ; // 모든식별자가이상없음 T RET_VAL; JU DMSK; // 동기화오류마스크해제로점프 ERRO: CLR ; // 오류 RLO=0일때의인스트럭션 SAVE ; // BR =0 T #RET_VAL; // 오류코드를 RET_VAL에전송 L L#-1; // 잘못된 REAL 숫자로드 T #Sum; T #Mean_value; DMSK: NOP 0; // 동기오류표시해제 CALL "DMSK_FLT" ( PRGFLT_RESET_MASK := DW#16#40C0014, ACCFLT_RESET_MASK := DW#16#0, RET_VAL := #sfc_ret_val, PRGFLT_MASKED := #sfc_prgflt, ACCFLT_MASKED := #sfc_accflt); BEU ; END_FUNCTION Page 33
연습 9.2 해답 (1 부, FB1) FUNCTION_BLOCK "Station" VERSION : 0.1 VAR_INPUT Initial : BOOL ; Proxy_Switch : BOOL ; Acknowledge : BOOL ; Clock_Bit : BOOL ; VAR_OUTPUT LED : BOOL ; Transp_req : BOOL ; VAR_IN_OUT conv_busy : BOOL ; VAR State : STRUCT Busy : BOOL ; Completed : BOOL ; Waiting : BOOL ; END_STRUCT ; Aux_1 : BOOL ; Aux_2 : BOOL ; 초기화 // 초기화를이용하면기본상태, 즉, 스테이션이 Busy 상태로설정됩니다. A R S R R #Initial; #State.Waiting; #State.Busy; #State.Completed; #conv_busy; State: Busy // 처리가이상태에서진행됩니다. 작업자가작업장확인버튼을 // 눌러부품의처리가완료되었음을확인하면 // 처리가종료됩니다. AN JC S R A R R S #State.Busy; REDY; #LED; #Transp_req; #Acknowledge; #State.Busy; #LED; #State.Completed; // ( 다음페이지에서계속 ) Page 34
연습 9.2 해답 (2 부, FB1 계속 ) State: Completed // 최종상태에서는완성된부품이전송벨트에놓여질때까지대기합니다. // 전송벨트에아무것도없으면입력신호 #Band_frei가신호를보냅니다. REDY: AN #State.Completed; JC WAIT; A #Clock_Bit; = #LED; AN #Conv_busy; A #Proxy_Switch; S #Conv_busy; S #Transp_req; A #Transp_req; A #Proxy_Switch; FN #Aux_1; R #State.Completed; S #State.Waiting; State: Waiting // 처리되지않은새로운부품을기다립니다. 새로운부품이도착되면전송벨트의인접스위치가 // 신호를보냅니다. WAIT: AN #State.Waiting; JC ENDE; R #LED; A #Proxy_Switch; // 처리되지않은새로운부품이도착됨 R #Transp_req; // 정지벨트 A #Proxy_Switch; FN #Aux_1; // 제거후, 처리시작 R #Conv_busy; // 다시한번컨베이어를활성화함 R #State.Waiting; S #State.Busy; ENDE: BEU ; Page 35
FUNCTION_BLOCK "Transport" 컨베이어제어 VERSION : 0.1 VAR_INPUT Initial : BOOL ; L_Barrier : BOOL ; Acknowledge : BOOL ; Transp_req : BOOL ; Clock_Bit : BOOL ; VAR_OUTPUT LED : BOOL ; Conv_right : BOOL ; Conv_left : BOOL ; Count_Value :INT ; VAR State : STRUCT Waiting : BOOL ; Transport_right : BOOL ; Assembly : BOOL ; Transport_left : BOOL ; END_STRUCT ; Counter: SFB0; 초기화 연습 9,2 해답 (3 부, FB2) A S R R R #Initial; #State.Waiting; #State.Transport_right; #State.Assembly; #State.Transport_left; call #Counter (R:= #Initial); // 필요하다면리셋 State: "Waiting" // 컨베이어는이상태에서완성된부품을기다립니다. AN #State.Waiting; JC RECH; R #Conv_right; R #Conv_left; R #LED; A #Transp_req; R #State.Waiting; S #State.Transport_right; // ( 다음페이지에서계속 ) Page 36
연습 9.2 해답 (4 부, FB2 계속 ) State: Transport_right // 이상태는완성된부품이최종어셈블리로전송되는과정을설명합니다. RECH: AN #State.Conv_right; JC ENDM; S #Conv_right; A #Clock_Bit; = #LED; AN #L_Barrier; R #Conv_right; R S #State.Conv_right; #State.Assembly; AN #L_Barrier; = #L_Barrier; CALL #Counter ( CU := #L_Barrier, CV := #Current_Value); State: Assembly // 이상태에서완성된부품이제거되고처리되지않은새로운부품이벨트에놓여집니다. // 그런후 S4를이용해비어있는처리스테이션방향으로의부품전송이 // 시작됩니다. ENDM: AN #State.Assembly; JC LINK; S #LED; A #Acknowledge; R #LED; R #State.Assembly; S #State.Conv_left; State: Conv_left // 이상태에서재료가완성된부품을전달한스테이션으로전송됩니다. LINK: AN #State.Conv_left; JC ENDE; S #Conv_left; A #Clock_Bit; = #LED; AN #Transp_req; R #Conv_left; R #State.Conv_left; S #State.Waiting; ENDE: BEU ; END_FUNCTION_BLOCK Page 37
연습 9.2 해답 (5 부, FB10) FUNCTION_BLOCK FB 10 VERSION : 0.1 VAR Station_1 : "Station"; Station_2 : "Station"; Station_3 : "Station"; Transport : "Transport"; Conv_busy : BOOL ; VAR_TEMP Trans_1 : BOOL ; Trans_2 : BOOL ; Trans_3 : BOOL ; Trans : BOOL ; Station_1 CALL #Station_1 ( Initial := I 0.0, Proxy_Switch := "INI1", Acknowledge := "S1", Clock_Bit := "CLOCK_BIT", LED := "H1", Transp_req := #Trans_1, Conv_busy := #Conv_busy); Station_2 CALL #Station_2 ( Initial := I 0.0, Proxy_Switch := "INI2", Acknowledge := "S2", Clock_Bit := "CLOCK_BIT", LED := "H2", Transp_req := #Trans_2, Conv_busy := #Conv_busy); Station_3 CALL #Station_3 ( Initial := I 0.0, Proxy_Switch := "INI3", Acknowledge := "S3", Clock_Bit := "CLOCK_BIT", LED := "H3", Transp_req := #Trans_3, Conv_busy := #Conv_busy); for Automation // ( 다음 and Drives 페이지에서계속 ) Page 38
Logic: Transp_req // #Transp_req의논리만들기 O #Trans_1; O #Trans_2; O #Trans_3; = #Trans; 연습 9.2 해답 (6 부, FB10 계속 ) Transport CALL #Transport ( Initial := I 0.0, L_Barrier := "LS1", Acknowledge := "S4", Transp_req := #Trans, Clock_Bit := "CLOCK_BIT", LED := "H4", Conv_right := "K1_CONV", Conv_left := "K2_CONV"); END_FUNCTION_BLOCK L #Transport.Current_value ; ITD ; // DINT까지확장 DTB ; // BCD로변환 T QW2 ; Page 39
DATA_BLOCK DB 10 VERSION : 0.0 연습 9.2 해답 (7 부, DB10) FB 10 Station_1.Initial := FALSE; Station_1.Proxy_Switch := FALSE; Station_1.Acknowledge := FALSE; Station_1.Clock_Bit := FALSE; Station_1.LED := FALSE; Station_1.Transp_req := FALSE; Station_1.Conv_busy:= FALSE; Station_1.State.Busy := FALSE; Station_1.State.Completed := FALSE; Station_1.State.Waiting := FALSE; Station_1.Aux_1 := FALSE; Station_1.Aux_2 := FALSE; Station_2.Initial := FALSE; Station_2.Proxy_Switch := FALSE; Station_2.Acknowledge := FALSE; Station_2.Clock_Bit := FALSE; Station_2.LED := FALSE; Station_2.Transp_req := FALSE; Station_2.Conv_busy := FALSE; Station_2.State.Busy := FALSE; Station_2.State.Completed := FALSE; Station_2.State.Waiting := FALSE; Station_2.Aux_1 := FALSE; Station_2.Aux_2 := FALSE; Station_3.Initial := FALSE; Station_3.Proxy_Switch := FALSE; Station_3.Acknowledge := FALSE; Station_3.Clock_Bit := FALSE; Station_3.LED := FALSE; Station_3.Transp_req := FALSE; Station_3.Conv_busy := FALSE; Station_3.State.Busy := FALSE; Station_3.State.Completed := FALSE; Station_3.State.Waiting := FALSE; Station_3.Aux_1 := FALSE; Station_3.Aux_2 := FALSE; Transport.Initial := FALSE; Transport.L_Barrier := FALSE; Transport.Acknowledge := FALSE; Transport.Transp_req := FALSE; Transport.Clock_Bit := FALSE; Transport.LED := FALSE; Transport.Conv_right := FALSE; Transport.Conv_left := FALSE; Transport.State.Waiting := FALSE; Transport.State.Transport_right := FALSE; Transport.State.Assembly := FALSE; Transport.State.Transport_left := FALSE; Conv_busy := FALSE; END_DATA_BLOCK Page 40
ORGANIZATION_BLOCK OB 1 VERSION : 0.1 연습 9.2 해답 (8 부, OB1) VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1 ( 들어오는이벤트 ), Bits 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB 1의콜드재시작스캔1), 3 (OB1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 CALL FB 10, DB 10 ; END_ORGANIZATION_BLOCK Page 41
연습 10.1 해답 (1 부 ) ORGANIZATION_BLOCK OB 100 SFB 의 "START 과 "STOP 초기화 VERSION : 0.1 VAR_TEMP OB100_EV_CLASS : BYTE ; //16#13, 이벤트클래스 1, 들어오는이벤트상태, 진단버퍼에 이벤트가로그됨 OB100_STRTUP : BYTE ; //16#81/82/83/84 시작방법 OB100_PRIORITY : BYTE ; //27 ( 우선순위 1이가장낮음 ) OB100_OB_NUMBR : BYTE ; //100 ( 조직블록 100, OB100) OB100_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB100_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB100_STOP : WORD ; //CPU를정지시키는이벤트 (16#4xxx) OB100_STRT_INFO : DWORD ; // 시스템의시작방법에관한정보 OB100_DATE_TIME : DATE_AND_TIME ; //OB100 시작날짜와시간 P_NAME : ARRAY [1.. 9 ] OF CHAR ; //Enter STRING "P_PROGRAM" in PI_NAME // ************************************************************************* // *** CFB의 "PI_NAME 파라미터정의 **** * //************************************************************************** // L 'P_PR'; T MD 100; L 'OGRA'; T MD 104; L 'M'; T MB 108; CALL SFB 20, DB 20 (// SFB "STOP 의초기화 REQ := FALSE, ID := W#16#3, PI_NAME := P#M 100.0 BYTE 9); CALL SFB 19, DB 19 (// SFB "START 의초기화 REQ := FALSE, ID := W#16#3, PI_NAME := P#M 100.0 BYTE 9); END_ORGANIZATION_BLOCK Page 42
ORGANIZATION_BLOCK OB 1 VERSION : 0.1 연습 10.1 해답 : OB100, OB1(2 부 ) VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1 ( 들어오는이벤트 ), Bits 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드재시작스캔1), 3 (OB 1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1 시작날짜와시간 DONE_FLAG_20 : BOOL ; ERROR_FLAG_20 : BOOL ; DONE_FLAG_19 : BOOL ; ERROR_FLAG_19 : BOOL ; STATUS_WORD_20 : WORD ; STATUS_WORD_19 : WORD ; "SFB_STOP" CALL SFB 20, DB 20 ( REQ := I 0.0, DONE := #DONE_FLAG_20, ERROR := #ERROR_FLAG_20, STATUS := #STATUS_WORD_20); "SFB_START" CALL SFB 19, DB 19 ( REQ := I 0.1, DONE := #DONE_FLAG_19, ERROR := #ERROR_FLAG_19, STATUS := #STATUS_WORD_19); // ( 다음페이지에서계속 ) Page 43
연습 10.1 해답 : OB100, OB1 (2 부 ) A( ; // QW2에 SFB START 의 STATUS 워드가반환됨 O #DONE_FLAG_19; O #ERROR_FLAG_19; ) ; JNB _001; L #STATUS_WORD_19; T QW 2; _001: NOP 0; A( ; // QW2에 SFB STOP 의 STATUS 워드가반환됨 O #DONE_FLAG_20; O #ERROR_FLAG_20; ) ; JNB _002; L #STATUS_WORD_20; T QW 2; _002: NOP 0; A I 0.0; // 그렇지않으면, QW2에 FFFF를기록함 BEC ; A I 0.1; BEC ; L W#16#FFFF; T QW 2; END_ORGANIZATION_BLOCK Page 44
연습 10.2 해답 : OB100, OB1 (1 부 ) ORGANIZATION_BLOCK OB 100 완전재시작 //Exercise : S7-400 는 S7-300 외부에서읽어와 S7-300 내부에기록합니다. AUTHOR : AUT95 FAMILY : A2_0 NAME : ST7PROG3 VERSION : 0.0 VAR_TEMP OB100_EV_CLASS : BYTE ; //16#13, 이벤트클래스 1, 이벤트상태로들어가기, 진단버퍼에로그된이벤트 OB100_STRTUP : BYTE ; //16#81/82/83/84 시작방법 OB100_PRIORITY : BYTE ; //27 ( 우선순위 1이가장낮음 ) OB100_OB_NUMBR : BYTE ; //100 ( 조직블록 100, OB100) OB100_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB100_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB100_STOP : WORD ; //CPU를정지시키는이벤트 (16#4xxx) OB100_STRT_INFO : DWORD ; // 시스템시작방법에관한정보 OB100_DATE_TIME : DATE_AND_TIME ; //OB100 시작날짜와시간 PI_NAME : ARRAY [1.. 9 ] OF CHAR ; Initialize CFB "GET" CALL SFB 14, DB 14 ( REQ := FALSE, ID := W#16#3); NOP 0; CFB "PUT 초기화 CALL SFB 15, DB 15 ( REQ := FALSE, ID := W#16#3); END_ORGANIZATION_BLOCK Page 45
연습 10.2 해답 : OB100, OB1 (2 부 ) ORGANIZATION_BLOCK OB 1 사이클 // 연습 : S7400 은 S7-300 외부에서읽어와 S7-300 내에기록합니다. AUTHOR : AUt95 FAMILY : A2_0 NAME : ST7PROG3 VERSION : 0.0 VAR_TEMP OB1_EV_CLASS : BYTE ; // 비트 0-3 = 1 ( 들어오는이벤트 ), Bits 4-7 = 1 ( 이벤트클래스 1) OB1_SCAN_1 : BYTE ; //1 (OB1의콜드재시작스캔1), 3 (OB1의스캔2-n) OB1_PRIORITY : BYTE ; //1 ( 우선순위 1이가장낮음 ) OB1_OB_NUMBR : BYTE ; //1 ( 조직블록 1, OB1) OB1_RESERVED_1 : BYTE ; // 시스템용으로예약됨 OB1_RESERVED_2 : BYTE ; // 시스템용으로예약됨 OB1_PREV_CYCLE : INT ; // 이전 OB1 스캔의순환시간 ( 밀리초 ) OB1_MIN_CYCLE : INT ; //OB1의최소순환시간( 밀리초 ) OB1_MAX_CYCLE : INT ; //OB1의최대순환시간( 밀리초 ) OB1_DATE_TIME : DATE_AND_TIME ; //OB1의시작날짜와시간 NDR_FLAG_14 : BOOL ; ERROR_FLAG_14 : BOOL ; DONE_FLAG_15 : BOOL ; ERROR_FLAG_15 : BOOL ; STATUS_WORD_14 : WORD ; STATUS_WORD_15 : WORD ; "SFB_GET" CALL SFB 14, DB 14 (// "GET 호출 REQ := I 0.2, ID := W#16#3, NDR := #NDR_FLAG_14, ERROR := #ERROR_FLAG_14, STATUS := #STATUS_WORD_14, ADDR_1 := P#I 0.0 BYTE 1, ADDR_2 := P#I 4.0 WORD 1, RD_1 := P#Q 0.0 BYTE 1, RD_2 := P#Q 4.0 WORD 1); // ( 다음페이지에서계속 ) Page 46
"SFB_PUT" 연습 10.2 해답 : OB100, OB1 (3 부 ) CALL SFB 15, DB 15 (//"PUT 호출 ) REQ := I 0.3, ID := W#16#3, DONE := #DONE_FLAG_15, ERROR := #ERROR_FLAG_15, STATUS := #STATUS_WORD_15, ADDR_1 := P#Q 12.0 WORD 1, SD_1 := P#I 2.0 WORD 1); A( ; // QW2에 SFB GET 의 STATUS 워드가반환됨 O #NDR_FLAG_14; O #ERROR_FLAG_14; ) ; JNB _002; L #STATUS_WORD_14; T QW 2; _002: NOP 0; A( ; // QW2에 SFB PUT 의 STATUS 워드가반환됨 O #DONE_FLAG_15; O #ERROR_FLAG_15; ) ; JNB _001; L #STATUS_WORD_15; T QW 2; _001: NOP 0; A I 0.2; // 그렇지않으면 QW2에 FFFF를기록함 BEC ; A I 0.3; BEC ; L W#16#FFFF; T QW 2; END_ORGANIZATION_BLOCK Page 47
"SFB_PUT" 연습 10.2 해답 : OB100, OB1 (3 부 ) CALL SFB 15, DB 15 (// "PUT" 호출 REQ := I 0.3, ID := W#16#3, DONE := #DONE_FLAG_15, ERROR := #ERROR_FLAG_15, STATUS := #STATUS_WORD_15, ADDR_1 := P#Q 12.0 WORD 1, SD_1 := P#I 2.0 WORD 1); A( ; // QW2에 SFB GET 의 STATUS 워드가반환됨 O #NDR_FLAG_14; O #ERROR_FLAG_14; ) ; JNB _002; L #STATUS_WORD_14; T QW 2; _002: NOP 0; A( ; // QW2에 SFB PUT 의 STATUS 워드가반환됨 O #DONE_FLAG_15; O #ERROR_FLAG_15; ) ; JNB _001; L #STATUS_WORD_15; T QW 2; _001: NOP 0; A I 0.2; // 그렇지않으면 QW2에 FFFF를기록함 BEC ; A I 0.3; BEC ; L W#16#FFFF; T QW 2; END_ORGANIZATION_BLOCK Page 48