Помогите разобраться с алгоритмом

Промышленные Логические Контроллеры SIMATIC S7-200/300/400
BRAIN
Posts: 27
Joined: Sat Nov 21, 2009 8:06 pm
Location: Yaroslavl, Russia

Помогите разобраться с алгоритмом

Post by BRAIN »

Доброго времени суток.

Задача: написать некую функцию для для опроса Db (200 byte) при обнаружении первого бита равного "1" выдавать его номер тоесть например: в шестом байте 3 бит = 1 то результатом функции будет 5*8+3=43.
Функция готова и даже работает (иногда :)) проблема в том что при некоторых ситуациях она вызывает зацикливание и контроллер естественно уходит в стоп по превышению времени цикла.
Помогите разобраться!
Code
Show

Code: Select all

FUNCTION "AIS_LOOK_FOR_ALARM" : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  DB_source : INT ;	
  lenght_byte : INT ;	
  start_byte : INT ;	
END_VAR
VAR_OUTPUT
  ALARM_NUMBER : WORD ;	
END_VAR
VAR_TEMP
  db_s : WORD ;	
  item : INT ;	
  SB : INT ;	
  PS : DWORD ;	
  item_p : INT ;	
  status_byte : BYTE ;	
  DES_ALARM : INT ;	
  OSTATOK : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =


      L     #start_byte; 
      T     #SB; 

      L     0; 
      T     #item; 


      L     #DB_source; 
      T     #db_s; 



loop: L     0; 
      T     #OSTATOK; 
      T     #DES_ALARM; 



      L     #SB; 
      L     #item; 
      +I    ; 
      SLD   3; 
      T     #PS; 

      AUF   DB [#db_s]; 
      L     DBB [#PS]; 
      T     #status_byte; 

      L     B#16#0; 
      <>I   ; 
      SPB   calc; 

      L     #item; 
      INC   1; 
      T     #item; 
      L     #lenght_byte; 
      >=I   ; 


      SPB   end; 

      SPA   loop; 
calc: L     0; 
      T     #OSTATOK; 
      T     #DES_ALARM; 

      L     #item; 
      L     0; 
      ==I   ; 
      SPB   m000; 

      L     #item; 
      DEC   1; 
      T     #item_p; 
      L     8; 
      *I    ; 
      T     #DES_ALARM; 

//Номер бита в найденом байте
m000: NOP   0; 

      U     L     12.0; 
      SPBN  m001; 
      L     1; 
      T     #OSTATOK; 
      SPA   end; 
m001: U     L     12.1; 
      SPBN  m002; 
      L     2; 
      T     #OSTATOK; 
      SPA   end; 
m002: U     L     12.2; 
      SPBN  m003; 
      L     3; 
      T     #OSTATOK; 
      SPA   end; 
m003: U     L     12.3; 
      SPBN  m004; 
      L     4; 
      T     #OSTATOK; 
      SPA   end; 
m004: U     L     12.4; 
      SPBN  m005; 
      L     5; 
      T     #OSTATOK; 
      SPA   end; 
m005: U     L     12.5; 
      SPBN  m004; 
      L     6; 
      T     #OSTATOK; 
      SPA   end; 
m006: U     L     12.6; 
      SPBN  m006; 
      L     7; 
      T     #OSTATOK; 
      SPA   end; 
m007: U     L     12.7; 
      SPBN  m007; 
      L     8; 
      T     #OSTATOK; 
      SPA   end; 


end:  L     #DES_ALARM; 
      L     #OSTATOK; 
      +I    ; 
      T     #ALARM_NUMBER; 
END_FUNCTION
sania
Site Admin
Posts: 1387
Joined: Sat Aug 13, 2005 6:15 am

Re: Помогите разобраться с алгоритмом

Post by sania »

loop так не делается.ты его в минус загоняешь и он не может выйти
пример юзания:
смотри коменты это важные места
Sample LOOP
Show

Code: Select all

  L     "DB500".DB_Report_Check
      L     800
      >I    
      JC    lops

      L     "DB500".Number_Reports
      T     "DB500".DB_Number_Loops
lops: L     "DB500".DB_Number_Loops           //загрузка стартового значения для циклов
DBad: T     "DB500".DB_Number_Loops         //скока циклов осталось

      L     "DB500".DB_Report_Check   
      OPN   DB [DBW 4]                
      A     DBX   22.0
      S     "Mem_Report_Present"

      A     DBX   22.0
      JC    next
      A     "Mem_Report_Present"
      JC    next
      L     "DB500".DI_Report_Check
      L     1
      +I    
      T     "DB500".DI_Report_Check

      L     "DB500".DB_Report_Check
      L     1
      +I    
      T     "DB500".DB_Report_Check


      L     "DB500".DB_Number_Loops      //загрузка циклов для вычитания
      LOOP  DBad

      JU    end
next: T     "DB500".DB_Number
      L     200
      -I    
      T     "DB500".DI_Number
      L     1
      +I    
      T     "DB500".DI_Report_Check
      L     200
      +I    
      T     "DB500".DB_Report_Check
      L     "DB500".DB_Number_Loops
      L     1
      -I    
      T     "DB500".DB_Number_Loops
BRAIN
Posts: 27
Joined: Sat Nov 21, 2009 8:06 pm
Location: Yaroslavl, Russia

Re: Помогите разобраться с алгоритмом

Post by BRAIN »

Переделал в соответствиями с рекомендациями всё равно тоже самое не понимаю почему происходит:
code
Show

Code: Select all

FUNCTION "AIS_LOOK_FOR_ALARM" : VOID
TITLE =

VERSION : 0.1


VAR_INPUT
  DB_source : INT ;	
  lenght_byte : INT ;	
  start_byte : INT ;	
END_VAR
VAR_OUTPUT
  ALARM_NUMBER : WORD ;	
END_VAR
VAR_TEMP
  db_s : WORD ;	
  item : INT ;	
  SB : INT ;	
  PS : DWORD ;	
  item_p : INT ;	
  status_byte : BYTE ;	
  DES_ALARM : INT ;	
  OSTATOK : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =

      L     #start_byte; 
      T     #SB; 

      L     #DB_source; 
      T     #db_s; 


      L     0; 
lops: T     #item; 

      L     #item; 
      L     #lenght_byte; 
      >=I   ; 
      SPB   calc; 

      L     0; 
      T     #OSTATOK; 
      T     #DES_ALARM; 



      L     #SB; 
      L     #item; 
      +I    ; 
      SLD   3; 
      T     #PS; 

      AUF   DB [#db_s]; 
      L     DBB [#PS]; 
      T     #status_byte; 

      L     2#0; 

      <>I   ; 
      SPB   calc; 





      L     #item; 
      LOOP  lops; 

calc: L     0; 
      T     #OSTATOK; 
      T     #DES_ALARM; 

      L     #item; 
      L     0; 
      ==I   ; 
      SPB   m000; 

      L     #item; 
      DEC   1; 
      T     #item_p; 
      L     8; 
      *I    ; 
      T     #DES_ALARM; 

//Номер бита в найденом байте
m000: NOP   0; 

      U     L     12.0; 
      SPBN  m001; 
      L     1; 
      T     #OSTATOK; 
      SPA   end; 
m001: U     L     12.1; 
      SPBN  m002; 
      L     2; 
      T     #OSTATOK; 
      SPA   end; 
m002: U     L     12.2; 
      SPBN  m003; 
      L     3; 
      T     #OSTATOK; 
      SPA   end; 
m003: U     L     12.3; 
      SPBN  m004; 
      L     4; 
      T     #OSTATOK; 
      SPA   end; 
m004: U     L     12.4; 
      SPBN  m005; 
      L     5; 
      T     #OSTATOK; 
      SPA   end; 
m005: U     L     12.5; 
      SPBN  m004; 
      L     6; 
      T     #OSTATOK; 
      SPA   end; 
m006: U     L     12.6; 
      SPBN  m006; 
      L     7; 
      T     #OSTATOK; 
      SPA   end; 
m007: U     L     12.7; 
      SPBN  m007; 
      L     8; 
      T     #OSTATOK; 
      SPA   end; 


end:  L     #DES_ALARM; 
      L     #OSTATOK; 
      +I    ; 
      T     #ALARM_NUMBER; 
END_FUNCTION


CHANt
Posts: 501
Joined: Tue Jun 27, 2006 5:52 am
Location: Russia

Re: Помогите разобраться с алгоритмом

Post by CHANt »

Вам указали, что в счетчик цикла надо грузить максим. значение, а Вы ноль туда - счетчик цикла в Step7 только на уменьшение считает.
-----
L 0; \\Ошибка
lops: T #item;
--------
sania
Site Admin
Posts: 1387
Joined: Sat Aug 13, 2005 6:15 am

Re: Помогите разобраться с алгоритмом

Post by sania »

как было сказано указатель циклов обязан быть >0,иначе он не выйдет из него
ну нашёл бит,а дальше остальные проверять не надо?
может просто без циклов сделать?
понятно,что не красиво,зато просто
можно сделать циклами,тока ответь на вопросы
это так,наскоряк накидал
For Test
Show

Code: Select all

L L#0
T      #DES_ALARM_WORD  //Set to 0
T     #DES_ALARM_BYTE    //Set to 0
T      #OSTATOK              //Set to 0

L DBD0
<>D
T #status_dword
L 0
JC Chck

L L#0
L DBD4
<>D
T #status_dword
L 4
JC Chck

// и т.д и т.п.


L L#0
L DBD196
<>D
T #status_dword
L 196
JC Chck
JU All0

Chck: T Int_Temp
L 8
*I
T #DES_ALARM_DWORD

L 0
L LB12  // 1st byte #status_dword
<>I
T #status_byte
L 0
JC Byte

// и т.д и т.п.

L 0
L LB16  // 4 byte #status_dword
<>I
T #status_byte
L 4
JC Byte
JU All0

Byte: T Byte_Temp
L 8
*I
T #DES_ALARM_BYTE

// теперь проверка бита как ты сделал

All0:L     #DES_ALARM_WORD
L     #DES_ALARM_BYTE
+I 
L     #OSTATOK 
+I    
T     #ALARM_NUMBER
BRAIN
Posts: 27
Joined: Sat Nov 21, 2009 8:06 pm
Location: Yaroslavl, Russia

Re: Помогите разобраться с алгоритмом

Post by BRAIN »

ДЛя текущей задачи вроде как и не надо! Но может потребоваться!

Похоже дело не только в цикле где то ещё косяк т. к. что с LOOP что просто переходом эффект одинаковый тоесть функция работает в тех случаях когда бит находится не на краях байта то есть не 1ый или не 8 ой как только эти биты то контроллер встаёт по TIME CYCLE EXCEPT вот вариант последней версии вместе с DB и вызовом
Есть у кого какие мысли! Может кто из опытных программеров откомпилирует исходник
в чём косяк?
Show

Code: Select all

 
DATA_BLOCK "DB11_данные ПК"

VERSION : 0.0


  STRUCT 	
   D0 : WORD ;	
   D01 : WORD ;	//аварии 1-16
   D02 : WORD ;	//аварии 17-32
   D03 : WORD ;	//аварии 33-48
   D04 : WORD ;	//аварии 49-64
   D05 : WORD ;	//аварии 65-80
   D06 : WORD ;	//аварии 81-96
   D07 : WORD ;	//аварии 97-112
   D08 : WORD ;	//аварии 113-128
   D09 : WORD ;	//аварии 129-144
   D010 : WORD ;	//аварии 145-160
   D011 : WORD ;	//аварии 161-176
   D012 : WORD ;	//аварии 177-192
   D013 : WORD ;	//аварии 193-208
   D014 : WORD ;	//аварии 209-224
   D015 : WORD ;	//аварии 225-240
   D016 : WORD ;	//сообщения 241-256
   D017 : WORD ;	//сообщения 257-272
   D018 : WORD ;	//сообщения 273-288
   D019 : WORD ;	//сообщения 289-304
   D020 : WORD ;	//сообщения 305-320
   D021 : WORD ;	//сообщения 321-336
   D022 : WORD ;	
  END_STRUCT ;	
BEGIN
   D0 := W#16#0; 
   D01 := W#16#0; 
   D02 := W#16#0; 
   D03 := W#16#0; 
   D04 := W#16#0; 
   D05 := W#16#0; 
   D06 := W#16#1010; 
   D07 := W#16#1010; 
   D08 := W#16#1010; 
   D09 := W#16#1010; 
   D010 := W#16#0; 
   D011 := W#16#0; 
   D012 := W#16#0; 
   D013 := W#16#0; 
   D014 := W#16#0; 
   D015 := W#16#111; 
   D016 := W#16#101; 
   D017 := W#16#0; 
   D018 := W#16#0; 
   D019 := W#16#0; 
   D020 := W#16#0; 
   D021 := W#16#42; 
   D022 := W#16#0; 
END_DATA_BLOCK

FUNCTION "AIS_LOOK_FOR_ALARM" : VOID
TITLE =

VERSION : 0.1


VAR_INPUT
  DB_source : INT ;	
  lenght_byte : INT ;	
  start_byte : INT ;	
END_VAR
VAR_OUTPUT
  ALARM_NUMBER : WORD ;	
END_VAR
VAR_TEMP
  db_s : WORD ;	
  item : INT ;	
  SB : INT ;	
  PS : DWORD ;	
  item_p : INT ;	
  status_byte : BYTE ;	
  DES_ALARM : INT ;	
  OSTATOK : INT ;	
  item_t : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =

      L     #start_byte; 
      T     #SB; 

      L     #DB_source; 
      T     #db_s; 

      L     #lenght_byte; 
lops: T     #item; 

      L     #lenght_byte; 
      L     #item; 
      -I    ; 
      T     #item_p; 


      L     #SB; 
      L     #item_p; 
      +I    ; 
      SLD   3; 
      T     #PS; 

      AUF   DB [#db_s]; 
      L     DBB [#PS]; 
      T     #status_byte; 

      L     B#16#0; 

      <>I   ; 
      SPB   ext; 

      L     #item; 
      LOOP  lops; 

ext:  L     0; 
      T     #OSTATOK; 
      T     #DES_ALARM; 

      L     #item_p; 
      L     0; 
      ==I   ; 
      SPB   m000; 

      L     #item_p; 
      DEC   1; 
      T     #item_t; 
      L     8; 
      *I    ; 
      T     #DES_ALARM; 

//Номер бита в найденом байте
m000: NOP   0; 

      U     L     12.0; 
      SPBN  m001; 
      L     1; 
      T     #OSTATOK; 
      SPA   end; 
m001: U     L     12.1; 
      SPBN  m002; 
      L     2; 
      T     #OSTATOK; 
      SPA   end; 
m002: U     L     12.2; 
      SPBN  m003; 
      L     3; 
      T     #OSTATOK; 
      SPA   end; 
m003: U     L     12.3; 
      SPBN  m004; 
      L     4; 
      T     #OSTATOK; 
      SPA   end; 
m004: U     L     12.4; 
      SPBN  m005; 
      L     5; 
      T     #OSTATOK; 
      SPA   end; 
m005: U     L     12.5; 
      SPBN  m004; 
      L     6; 
      T     #OSTATOK; 
      SPA   end; 
m006: U     L     12.6; 
      SPBN  m006; 
      L     7; 
      T     #OSTATOK; 
      SPA   end; 
m007: U     L     12.7; 
      SPBN  m007; 
      L     8; 
      T     #OSTATOK; 
      SPA   end; 


end:  L     #DES_ALARM; 
      L     #OSTATOK; 
      +I    ; 
      T     #ALARM_NUMBER; 
END_FUNCTION

ORGANIZATION_BLOCK OB 1

VERSION : 0.1


VAR_TEMP
  OB1_EV_CLASS : BYTE ;	//Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;	//1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ;	//Priority of OB Execution
  OB1_OB_NUMBR : BYTE ;	//1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;	//Reserved for system
  OB1_RESERVED_2 : BYTE ;	//Reserved for system
  OB1_PREV_CYCLE : INT ;	//Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ;	//Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ;	//Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;	//Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =

      CALL "AIS_LOOK_FOR_ALARM" (
           DB_source                := 11,
           lenght_byte              := 30,
           start_byte               := 2,
           ALARM_NUMBER             := MW    10);

END_ORGANIZATION_BLOCK


sania
Site Admin
Posts: 1387
Joined: Sat Aug 13, 2005 6:15 am

Re: Помогите разобраться с алгоритмом

Post by sania »

так сразу бы и сказал,что последний вариант не канает
вот это по-проще будет
ДБ сделай подходящим размером
Code
Show

Code: Select all

DATA_BLOCK DB 20
TITLE =
VERSION : 0.1


  STRUCT 	
   Alarm1 : INT ;	
   Alarm2 : INT ;	
   Alarm3 : INT ;	
   Alarm4 : INT ;	
   Alarm5 : INT ;	
   Alarm6 : INT ;	
   Alarm7 : INT ;	
   Alarm8 : INT ;	
   Alarm9 : INT ;	
   Alarm10 : INT ;	
   Alarm11 : INT ;	
   Alarm12 : INT ;	
  END_STRUCT ;	
BEGIN
   Alarm1 := 0; 
   Alarm2 := 0; 
   Alarm3 := 0; 
   Alarm4 := 0; 
   Alarm5 := 0; 
   Alarm6 := 0; 
   Alarm7 := 0; 
   Alarm8 := 0; 
   Alarm9 := 0; 
   Alarm10 := 0; 
   Alarm11 := 0; 
   Alarm12 := 0; 
END_DATA_BLOCK

FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  DB_Number : INT ;	
  Start_Byte : INT ;	
  DB_Leight : INT ;	
END_VAR
VAR_OUTPUT
  Number_Alarm : INT ;	
END_VAR
VAR_TEMP
  DB_N : INT ;	
  Loop_Chck : INT ;	
  Start_Bit : INT ;	
  End_Bit : INT ;	
  Check_Bit : DINT ;	
END_VAR
BEGIN
NETWORK
TITLE =

      L     #DB_Number; 
      T     #DB_N; 
      OPN   DB [#DB_N]; 

      L     #Start_Byte; 
      SLW   3; 
      T     #Start_Bit; 

      L     #DB_Leight; 
      SLW   3; 
      T     #Loop_Chck; 
      L     #Start_Bit; 
      +I    ;  
      T     #End_Bit; 
      L     #Loop_Chck; 
lop1: T     #Loop_Chck; 
      L     #End_Bit; 
      TAK   ; 
      -I    ; 
      T     #Check_Bit; 
      A     DBX [#Check_Bit]; 
      JC    Alrm; 
      L     #Loop_Chck; 
      LOOP  lop1; 

      L     0; 
      T     #Check_Bit; 
      JU    End; 
Alrm: L     #Check_Bit;
      L     #Start_Bit; 
      -I    ; 
      L     1; 
      +I    ; 
End:  T     #Number_Alarm; 

END_FUNCTION

ORGANIZATION_BLOCK OB 1
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1


VAR_TEMP
  OB1_EV_CLASS : BYTE ;	//Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;	//1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ;	//Priority of OB Execution
  OB1_OB_NUMBR : BYTE ;	//1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;	//Reserved for system
  OB1_RESERVED_2 : BYTE ;	//Reserved for system
  OB1_PREV_CYCLE : INT ;	//Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ;	//Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ;	//Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;	//Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =

      CALL FC     1 (
           DB_Number                := 20,
           Start_Byte               := 0,
           DB_Leight                := 20,
           Number_Alarm             := MW     0);
      NOP   0; 
END_ORGANIZATION_BLOCK
BRAIN
Posts: 27
Joined: Sat Nov 21, 2009 8:06 pm
Location: Yaroslavl, Russia

Re: Помогите разобраться с алгоритмом

Post by BRAIN »

УУУх! Пока ещё нет времени сесть откомпилировать и разобраться! Спасибо за помощь !
BRAIN
Posts: 27
Joined: Sat Nov 21, 2009 8:06 pm
Location: Yaroslavl, Russia

Re: Помогите разобраться с алгоритмом

Post by BRAIN »

Для чего вообще происходит сдвиг битов?

Code: Select all

      L     #Start_Byte;
      SLW   3;
      T     #Start_Bit;
sania
Site Admin
Posts: 1387
Joined: Sat Aug 13, 2005 6:15 am

Re: Помогите разобраться с алгоритмом

Post by sania »

чтоб сформировать pointer,он работает по-битно