luca959697 Inserito: 26 novembre 2015 Segnala Share 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. Link al commento Condividi su altri siti More sharing options...
drugo66 Inserita: 26 novembre 2015 Segnala Share 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. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 26 novembre 2015 Segnala Share 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. Link al commento Condividi su altri siti More sharing options...
drugo66 Inserita: 26 novembre 2015 Segnala Share Inserita: 26 novembre 2015 Chiedo venia per gli errori ... Link al commento Condividi su altri siti More sharing options...
FabioS.PLC Inserita: 28 novembre 2015 Segnala Share 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 Link al commento Condividi su altri siti More sharing options...
luca959697 Inserita: 28 novembre 2015 Autore Segnala Share Inserita: 28 novembre 2015 android633 ho scaricato il file. Con quale programma bisogna aprire un file con espansione .ap13? Link al commento Condividi su altri siti More sharing options...
FabioS.PLC Inserita: 29 novembre 2015 Segnala Share 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 Link al commento Condividi su altri siti More sharing options...
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