luca959697 Inserito: 26 novembre 2015 Segnala Inserito: 26 novembre 2015 Devo scrivere in un fc parametrizzato.1) ES: Nel DB1 (DB_A)STRUCT0.1 (OFSET) COMANDO (NOME) BOOL (TIPO DI DATO)Io vorrei scrivere:A "DB_A". COMANDOS BITNel FC parametrizzato come variabile IN: DB_1 (NOME) BLOCK_DB (TIPO DI DATO)Poi scrivoA #DB_1.DBX0.1 (mi dà errore)Invece se scrivoOPN #DB_1A DBX0.1 (Ok)Perché nel primo caso mi dà errore?2)ES: Nel DB6 (DB_A) ho questa situazione:STRUCTRIPRISTINO (NOME) ARRAY [1..10]Nel FC scrivo i parametri IN: DB_1 (NOME) BLOCK_DB (TIPO DI DATO) INDICE INT (TIPO DI DATO)Io vorrei scrivere: #DB_1.RIPRISTINO[INDICE]come faccio a scriverlo usando AWL3)ES: NEL DB3 (DB_B) ho questa situazione:STRUCTB (NOME) "UDT_B" (TIPO DI DATI) (UDT_B è composto da 20 BOOL)Nel FC scrivo i parametri IN/OUT: UDT_PROVA (NOME) "UDT_B" (TIPO DI DATI)Voglio resettare tutti i BOOL di questo UDT e controllare che nessuno dei BOOL di questo UDT abbia assunto valore 1. Questo lo devo fare come negli altri esempi in AWL in un FC parametrizzato.
drugo66 Inserita: 26 novembre 2015 Segnala Inserita: 26 novembre 2015 Ciao,premetto che utilizzo poco AWL, ma prova a risponderti lo stesso.1) Semplicemente perchè non si può: il prefisso # indica al compilatore che stai utilizzando un puntatore; i puntatori per AWL Siemens sono Int o DInt, se ricordo bene, mentre con DB_1.DBX0.1 tu stai utilizzando un bit; per definizione, un puntatore è l'indirizzo ad un area di memoria (quindi un numero).2) In AWL Siemens non puoi utilizzare come indice di un array una variabile, ma sempre e solo una costante: non puoi scrivere ARRAY[INDICE], ma solo ARRAY[1] (secondo me, questo è uno dei punti deboli del linguaggio AWL); in sostanza, sei costretto a dimesionare ed utilizzare un puntatore.3) Se la tua Struct è composta da 32 bit posti all'inizio del blocco dati, ad esempio, per azzerarli basta che fai un move 0 a DBn.DBD0, utilizzando l'indirizzamento assoluto; la stessa cosa puoi farla con un confronto, per sapere se uno dei bit è TRUE (con 20 bit credo cambi poco); in questo modo, però, DBnDBD0 non ha simbolo e non può averlo; un altro modo è quello di utilizzare i puntatori e ciclare verificando o azzerando tutti i bit contenuti nella Struct.Ti consiglio di scaricarti e leggerti la guida di Federico Milan proprio sull'utilizzo dei puntatori ("Puntatori S7" e dovrebbe essere nela sezione download del forum) e di guardarti gli innumerevoli post sull'argomento, sempre sul forum; se cerchi Siemens SIOS con il tuo motore di ricerca preferito, lì troverai, invece, le guide ufficiali di Siemens sul linguaggio AWL: sui puntatori esiste una intera sezione.
batta Inserita: 26 novembre 2015 Segnala Inserita: 26 novembre 2015 1) Come detto da Drugo, semplicemente perché non si può. Non è però per il discorso "puntatore". Il puntatore viene definito con #P. Il solo carattere # indica che si accede ad una variabile dell'interfaccia delle variabili della funzione. 2) Non poter scrivere Array[indice] non è un limite del linguaggio AWL, ma del 300/400. Infatti non puoi usare quella sintassi nemmeno in KOP, ma solo in SCL.Con il 1200 lo puoi fare in SCL e in KOP (l'AWL non c'è). Con il 1500 in SCL, in KOP e in AWL.
drugo66 Inserita: 26 novembre 2015 Segnala Inserita: 26 novembre 2015 Chiedo venia per gli errori ...
FabioS.PLC Inserita: 28 novembre 2015 Segnala Inserita: 28 novembre 2015 (modificato) Ho fatto per esercitarmi delle funzioni che accedono ad uno specifico indice di un array in STL, nello specifico in questo file ( https://mega.nz/#!fkR2xATB!mR_9c9SksWYeUxcKcLkDFfgNFfU4QHDo0RdHxGkiCnE ) trovi le seguenti funzioni: array_dinamico_incrementale (FC3): riceve in ingresso il primo elemento dell'array (tipo pointer) e la dimensione, poi riempe tutti i valori in maniera incrementale, ossia array[0]=0, array[1]=1, array[n]=n, array[dim]=dim-1. copia_array1_in_array_2_dinamico_pointer (FC4): funzione che copia il contenuto di array1 in array2, dim è la dimensione dell'array più piccolo somma_di due_array_elemento_per_elemento (FC5): esegue la somma di due array elemento per elemento, e copia il risultato in un terzo arraysia i due array in ingresso che quello in uscita sono di tipo pointer, la dimensione dim è pari a quella dell'array più piccolo. ci sono poi queste altre due funzioni per resettare il tuo User_Data_type da 20 Bool luca959697_resetta_UDT_con_pointer (FC1) : L P##UDT_ptr //dove UDT_ptr è un Input di tipo Pointer LAR1 L W [ AR1 , P#0.0 ] T #numb_db L D [ AR1 , P#2.0 ] LAR1 L w#16#0 OPN DB [ #numb_db] T W [ AR1 , P#0.0 ] //resetta i primi 16 bit L B [ AR1 , P#2.0 ] //carica gli 8 bit successivi ai primi 16 L b#16#f0 // carica in accu1 11110000 AW //faccio l'and in modo da azzerare solo i primi 4 bit e lasciare intatti gli altri T B [ AR1 , P#2.0 ] e l'altra funzione in alternativa a FC1 è luca959697_resetta_UDT_senza_pointer (FC6): R #UDT_PROVA.Element_1 //dove UDT_PROVA è un InOut di Tipo UDT_B (User Date Type composto da 20 Bool) R #UDT_PROVA.Element_2 R #UDT_PROVA.Element_3 R #UDT_PROVA.Element_4 R #UDT_PROVA.Element_5 R #UDT_PROVA.Element_6 R #UDT_PROVA.Element_7 R #UDT_PROVA.Element_8 R #UDT_PROVA.Element_9 R #UDT_PROVA.Element_10 R #UDT_PROVA.Element_11 R #UDT_PROVA.Element_12 R #UDT_PROVA.Element_13 R #UDT_PROVA.Element_14 R #UDT_PROVA.Element_15 R #UDT_PROVA.Element_16 R #UDT_PROVA.Element_17 R #UDT_PROVA.Element_18 R #UDT_PROVA.Element_19 R #UDT_PROVA.Element_20Ovviamente sono bene accettate le critiche, visto che sto ancora imparando Modificato: 28 novembre 2015 da android633
luca959697 Inserita: 28 novembre 2015 Autore Segnala Inserita: 28 novembre 2015 android633 ho scaricato il file. Con quale programma bisogna aprire un file con espansione .ap13?
FabioS.PLC Inserita: 29 novembre 2015 Segnala Inserita: 29 novembre 2015 (modificato) io uso TIA Portal v13, se non hai TIA portal ti posto qua le funzioni: array_dinamico_incrementale (FC3): riceve in ingresso il primo elemento dell'array (tipo pointer) e la dimensione, poi riempe tutti i valori in maniera incrementale, ossia array[0]=0, array[1]=1, array[n]=n, array[dim]=dim-1. Variabili Input: Array_ptr (Pointer), dim (Int);Variabili Temp: numb_db (Word), count1(Int) L P##Array_ptr //Array_ptr è un Input di tipo Pointer LAR1 L W [ AR1 , P#0.0 ] // Carico su ACCU1 i primi due Byte del Pointer Array_ptr che rappresentano il numero del blocco dati (DB_number) T #numb_db //trasferisco ACCU1 su numb_db per riutilizzarlo dopo quando devo aprire il blocco dati L D [ AR1 , P#2.0 ] // carico su ACCU1 i byte 2,3,4,5 (ossia 32bit) che corrispondono all'area di memoria a cui punta il puntatore Array_ptr all'intero del DB LAR1 // carico l'indizizzo precedente su AR1 L #dim //carico su ACCU1 la dimensione dell'array a cui punta il puntatore Array_ptrinizio : T #count1 // inizio un loop L #dim L #count1 -I // faccio la differenza tra dim e count1 per avere array[0]=0, array[1]=1, altrimenti avrei array[0]=dim-1, array[1]=dim-2 ecc.. OPN DB [ #numb_db] //apro il blocco dati DB dove è presente l'array a cui punta il puntatore Array_ptr T W [ AR1 , P#0.0 ] // trasferisco il valore contenuto in ACCU1 (che sarebbe dim-count1) all'indirizzo corrispondente ad array[dim-count1], quindi array[0]=0, array[1]=1, .. +AR1 P#2.0 // "incremento" AR1 di 2 byte, ossia nel ciclo successivo del loop, l'indirizzo in AR1 è quello dell'elemento immediatamente successivo dell'array L #count1 LOOP inizio //ripeto il loop fino a quando ACCU1, ossia count1>0 (ad ogni ciclo di loop count1 viene decrementato di 1) _________________________________________________________________________________________________________________________________________ copia_array1_in_array_2_dinamico_pointer (FC4): funzione che copia il contenuto di array1 in array2, dim è la dimensione dell'array più piccoloVariabili Input: array1_ptr (Pointer), dim (Int)Variabili Temp: numb_db_array1 (Word), numb_db_array2 (Word), save_ar2 (DWord), count1 (Int)Output: array2_ptr (Pointer) L P##array1_ptr LAR1 L W [ AR1 , P#0.0 ] // Carico su ACCU1 i primi due Byte del Pointer array1_ptr che rappresentano il numero del blocco dati (DB_number) T #numb_db_array1 //trasferisco ACCU1 su numb_db_array1 per riutilizzarlo dopo quando devo aprire il blocco dati L D [ AR1 , P#2.0 ] // carico su ACCU1 i byte 2,3,4,5 (ossia 32bit) che corrispondono all'area di memoria a cui punta il puntatore array1_ptr all'intero del DB LAR1 // carico l'indizizzo precedente su AR1 //salvo ar2 su doubleword e lo ripristino a fine funzione (questo perchè AR2 è utilizzato dal processore e non ripristinarlo può causare problemi) TAR2 T #save_ar2 L P##array2_ptr LAR2 // carico l'indizizzo del puntatore su AR2 L W [ AR2 , P#0.0 ] // Carico su ACCU1 i primi due Byte del Pointer array2_ptr che rappresentano il numero del blocco dati (DB_number) T #numb_db_array2 //trasferisco ACCU1 su numb_db_array2 per riutilizzarlo dopo quando devo aprire il blocco dati L D [ AR2 , P#2.0 ] // carico su ACCU1 i byte 2,3,4,5 (ossia 32bit) che corrispondono all'area di memoria a cui punta il puntatore array2_ptr all'intero del DB LAR2 // carico l'indizizzo precedente su AR2 L #dim //carico su ACCU1 la più piccola dimensione tra i due array (dim è un input della funzione)inizio : T #count1 // inizio un loop OPN DB [ #numb_db_array1] //apro il blocco dati DB dove è presente l'array a cui punta il puntatore array1_ptr L W [ AR1 , P#0.0 ] //carico su ACCU1 l'elemento array1[dim-count1] (dove l'array1 è un array di interi o Word a cui punta array1_ptr) OPN DB [ #numb_db_array2] //apro il blocco dati DB dove è presente l'array a cui punta il puntatore array2_ptr T W [ AR2 , P#0.0 ] // trasferisco il valore presente in ACCU1 su array2[dim-count1], cioè array2[dim-count1]=array1[dim-count1] +AR1 P#2.0 // "incremento" AR1 di 2 byte, ossia nel ciclo successivo del loop l'indirizzo in AR1 è quello della word immediatamente succesiva (elemento successivo) +AR2 P#2.0 //come sopra ma per AR2 L #count1 LOOP inizio //ripeto il loop fino a quando ACCU1, ossia count1>0 (ad ogni ciclo di loop count1 viene decrementato di 1) L #save_ar2 LAR2 //ripristino AR2 precedentemente salvato _________________________________________________________________________________________________________________________________________ somma_di due_array_elemento_per_elemento (FC5): esegue la somma di due array elemento per elemento, e copia il risultato in un terzo arraysia i due array in ingresso che quello in uscita sono di tipo pointer, la dimensione dim è pari a quella dell'array più piccolo.Variabili Input: array1_ptr (Pointer), array2_ptr (Pointer), dim (Int)Variabili Temp: numb_db_array1 (Word), numb_db_array2 (Word), numb_db_array_sum (Word), save_ar2 (DWord), count1 (Int), ar1_array1 (DWord), ar1_array2 (DWord), ar1_sum (DWord), tmp_sum (Int), tmp_int1 (Int), tmp_int2 (Int)Variabili Output: array_sum_ptr (Pointer) L P##array_sum_ptr LAR1 L W [ AR1 , P#0.0 ] // Carico su ACCU1 i primi due Byte del Pointer array_sum_ptr che rappresentano il numero del blocco dati (DB_number) T #numb_db_array_sum //trasferisco ACCU1 su numb_db_array_sum per riutilizzarlo dopo quando devo aprire il blocco dati L D [ AR1 , P#2.0 ] // carico su ACCU1 i byte 2,3,4,5 (ossia 32bit) che corrispondono all'area di memoria a cui punta il puntatore array_sum_ptr all'intero del DB T #ar1_sum //salvo l'indirizzo del primo elemento dell'array_sum (che è l'array di destinazione a cui punta il puntatore array_sum_ptr ) L P##array1_ptr LAR1 L W [ AR1 , P#0.0 ] T #numb_db_array1 L D [ AR1 , P#2.0 ] T #ar1_array1 //come sopra salvo l'indirizzo del primo elemento dell'array1 (che è l'array a cui punta array1_ptr)(è l'indirizzo all'interno del blocco dati numb_db_array1) L P##array2_ptr LAR1 L W [ AR1 , P#0.0 ] T #numb_db_array2 L D [ AR1 , P#2.0 ] T #ar1_array2 //come sopra salvo l'indirizzo del primo elemento dell'array2 (che è l'array a cui punta array2_ptr)(è l'indirizzo all'interno del blocco dati numb_db_array2) L #diminizio : T #count1 //inizio il loop L #ar1_array1 LAR1 //carico su ar1 l'indirizzo dell'elemento dell'array1, ovvero array1[dim-count1] (questo indirizzo è l'indirizzo all'interno del blocco dati numb_db_array1) OPN DB [ #numb_db_array1] //apro il blocco dati DB dove è presente l'array a cui punta il puntatore array1_ptr L W [ AR1 , P#0.0 ] //carico su ACCU1 l'elemento array1[dim-count1] (dove l'array1 è un array di interi o Word a cui punta array1_ptr) T #tmp_int1 //trasferisco tale valore sulla variabile temporanea tmp_int1 +AR1 P#2.0 // "incremento" AR1 di 2 byte, ossia nel ciclo successivo del loop l'indirizzo in AR1 è quello della word immediatamente succesiva (elemento successivo) TAR1 //trasferisco ar1 su ACCU1 T #ar1_array1 // salvo il nuovo indirizzo dell'elemento successivo dell'array L #ar1_array2 LAR1 OPN DB [ #numb_db_array2] L W [ AR1 , P#0.0 ] T #tmp_int2 +AR1 P#2.0 TAR1 T #ar1_array2 //tutto ugale a prima solo che viene fatto per l'array2. L #tmp_int1 L #tmp_int2 +I T #tmp_sum // faccio la somma dei due valori, ossia array1[dim-count1]+array2[dim-count1] e la salvo su tmp_sum L #ar1_sum LAR1 L #tmp_sum OPN DB [ #numb_db_array_sum] T W [ AR1 , P#0.0 ] +AR1 P#2.0 TAR1 T #ar1_sum L #count1 LOOP inizio _______________________________________________________________________________________________________________ *NOTA: In tutti i casi l'array a cui punta il puntatore Array_ptr deve essere di interi o di word, ossia i sui elementi devono essere di 16bit. Modificato: 29 novembre 2015 da android633
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora