zoz Inserito: 24 dicembre 2010 Segnala Inserito: 24 dicembre 2010 Ciao a tutti, sono nuovo del forum.Colgo l'occasione per chiedervi aiuto su una cosa. Sto imparando a programmare in AWL e ho un disperato bisogno di utilizzare i puntatori,(cosa da me piuttosto sconosciuta). Purtroppo sul manuale AWL simens non dice grandi cose. Sapete dove posso trovare una dispensa o qualche articolo a riguardo?Mi interessano sopratutto per le operazioni di calcolo, incremento e lettura e scrittura su DB. Se potete aiutarmi, vi ringrazio.
gaserma Inserita: 25 dicembre 2010 Segnala Inserita: 25 dicembre 2010 Usa la funzione "Cerca" e troverai quello che ti serveBuon Natale
busanela Inserita: 25 dicembre 2010 Segnala Inserita: 25 dicembre 2010 Ciao,ecco un breve Tutorial di Federico Milan a riguardo. E' piuttosto completo per introdurti, al momento, in questo argomento.
zoz Inserita: 29 dicembre 2010 Autore Segnala Inserita: 29 dicembre 2010 Grazie! La guida la conoscevo già.. Poco esauriente a mio avviso. Vi chiedo un altra cosa. Ho bisogno di puntare a un bit di un byte di una word di periferia e resettarlo. Come posso fare con i puntatori?
Livio Orsini Inserita: 29 dicembre 2010 Segnala Inserita: 29 dicembre 2010 Ho bisogno di puntare a un bit di un byte di una word di periferia e resettarlo.Come posso fare con i puntatori?Perchè vuoi complicare le cose? Per resettare un bit di una word basta usare una maschera in AND con la word.
zoz Inserita: 29 dicembre 2010 Autore Segnala Inserita: 29 dicembre 2010 Si, hai ragione. Ma ho iniziato da poco a programmare in Awl e non mi viene facile l'utilizzo dei puntatori. Ecco perchè chiedevo un' aiuto con i puntatori :-) era didattico..ad ogni modo presumo non si possa puntare a un bit di una word di periferia, S7 non me lo permette... Mah...
Livio Orsini Inserita: 29 dicembre 2010 Segnala Inserita: 29 dicembre 2010 (modificato) I puntatori tipicamente puntano ad un indirizzo di memoria. La memoria nei sistemi Siemens, ma non solo, è organizzata a bytes, pertanto i puntatori puntano ad un byte.Se non ricordo male, ci sono istruzioni specifiche in S7 (in microwin sicuramente) che settano, resettano e testano uno o più bits di un singolo byte. Modificato: 29 dicembre 2010 da Livio Orsini
mubeta Inserita: 29 dicembre 2010 Segnala Inserita: 29 dicembre 2010 Mi sembra qui ci sia un errore di fondo.le word di periferia non sono memorizzate nell'immagine di processo, quindi non è assolutamente possibile modificarne i valori; esse si possono solo leggere e scrivere con istruzioni di lettura e scrittura immediata, come byte, word o dword ... nulla per i bit. Il mascheramento andrebbe fatto in locale, su delle memorie di appoggio.
batta Inserita: 30 dicembre 2010 Segnala Inserita: 30 dicembre 2010 Se con "bit di un byte di una word di periferia" intendi un bit di un canale analogico (PEW o PSW, per esempio), allora, come dice mubeta, devi accontentarti di lavorare a byte, word o dword.Se invece intendi semplicemente un ingresso o una uscita digitale, puoi agire direttamente sul bit.Detto questo, c'è da precisare che in Step7 i puntatori non puntano il byte, ma il bit.esempi:U E[MD100]U M[DB10.DBD4]= A[MD104]Dove MD100 è la variabile che contiene l'indirizzo dell'ingresso che si desidera leggere.Tenendo presente, come detto sopra, che si deve impostare l'indirizzo dl bit, l'indirizzo si calcola moltiplicando x8 (o con shift a sinistra di 3 bit) il numero del byte, e sommando il numero del bit all'interno del byte.Esempi:E0.5 --> 0*8 + 5 = 5E12.2 --> 12*8 + 2 = 98
Livio Orsini Inserita: 30 dicembre 2010 Segnala Inserita: 30 dicembre 2010 (modificato) ..c'è da precisare che in Step7 i puntatori non puntano il byte, ma il bitQuesto non lo sapevo! E' un caso più unico che raro. Modificato: 30 dicembre 2010 da Livio Orsini
batta Inserita: 30 dicembre 2010 Segnala Inserita: 30 dicembre 2010 Per essere più precisi, il formato Pointer, lungo 6 byte, è composto come segue.Partendo dal byte più significativo, secondo lo standard Motorola o Big Endian:byte 0 e 1: numero del DBbyte 2: codice area di memoriabyte 3-4-5: indirizzo.Dei byte 3-4-5 i 5 bit più significativi (dal bit 19 al bit 23) sono sempre a zero. I successivi 16 bit (dal bit da 3 al bit 18) contengono l'indirizzo del byte. I 3 bit meno significativi (dal bit 0 al bit 2) contengono l'indirizzo del bit.Di fatto risulta molto più comodo considerare che l'indirizzo punti direttamente al bit.Negli esempi del mio precedente post si notano principalmente due cose:1) ho utilizzato un puntatore a 32 bit e non a 48 bit, come sopra descritto. In questo modo si perde l'informazione del numero del DB, che in questo caso non è rilevante.2) il byte che dovrebbe contenere l'area di memoria (byte 2 nel caso di puntatore a 48 bit, byte 0 nel caso di puntatore a 32 bit) è posto semplicemente a zero. Questo è possibile perché l'area di memoria è indicata in modo esplicito nell'istruzione. Scrivendo "U E[MD0]" si definisce in modo inequivocabile l'area degli ingressi.Altro modo (più completo ed elegante) di lavorare con i puntatori, consiste nell'utilizzare i registi degli indirizzi AR1 e AR2. Ma l'argomento, oltre ad essere già stato ampiamente trattato nel forum, è piuttosto lungo.Nella sezione "Tips & Tricks - PLC esempi di programmazione" ci sono anche alcuni miei piccoli lavori che, al di là della funzione principale svolta che potrebbe non interessare, utilizzano i puntatori, con tanto di spiegazioni.
zoz Inserita: 10 gennaio 2011 Autore Segnala Inserita: 10 gennaio 2011 Ma per esempio, se volessi scrivere una word che è nella db1 sulla db2, in modo ripetitivo, come potrei fare? Allora, io ho ragionato così. Ditemi dove sbaglio per piacere. L DB1.DBW 0 //Carico la DBW0 del DB1 ITD //La converto in 32bit L L#2 // carico una costante a 32 (Perche sul db 2 voglio fare un salto ogni 2byte) *D // Moltiplico SLD 3 //shifto a SX per avere il formato puntatore L P#0.0 // carico un puntatore 0.0 +D // Lo sommo al valore precedente LAR1 // metto tutto il risultato in AR1 AUF DB 2 // apro db2 T DBW [AR1,P#0.0] // Trasferisco sulla word che dovrebbe essere 2 con un offset di 0.0Unico problema... Non funziona. Perchè? Cosa sbaglio? Dove cade il mio ragionamento? ho un disperato bisogno di comprendere sti puntatori, ma non ne salto fuori. Perfino il simulatore mi sta scongiurando, non ne può più....
rguaresc Inserita: 11 gennaio 2011 Segnala Inserita: 11 gennaio 2011 (modificato) mi sembra che tu stia facendo confusione fra dati e indirizzi. // preparo l'indirizzo: AUF DB2 L L#2 // carico una costante a 32 (Perche sul db 2 voglio fare un salto ogni 2byte) SLD 3 //shifto a SX per avere il formato puntatore L P#DBX0.0 // carico un puntatore della posizione 0.0 di DB2 +D // Lo sommo al valore precedente LAR1 // metto tutto il risultato in AR1, il registro AR1 punterà a DBX2.0 // trasferisco il dato L DB1.DBW 0 //Carico la DBW0 del DB1 AUF DB2 T DBW [AR1,P#0.0] // Trasferisco sulla word che dovrebbe essere 2 con un offset di 0.0 Modificato: 11 gennaio 2011 da rguaresc
zoz Inserita: 11 gennaio 2011 Autore Segnala Inserita: 11 gennaio 2011 Ti ringrazio per l'aiuto... Poi se si vuole farlo in modo continuo, basta incrementare AR1 di 2 e metterci un loop per le volte desiderate, tutto insieme a un bel salto. Ho appena provato e funziona alla grande. Figata.Comunque hai proprio ragione, faccio confusione con indirizzi e dati. Consigli per levarmi questo problema??? :D STO AWL comincia a piacermi! :-))))
FabioD85 Inserita: 31 luglio 2012 Segnala Inserita: 31 luglio 2012 Buongiorno, sapete dirmi se cè un manuale o qualsiasi guida fatta bene su come programmare con i puntatori, capirne come funzionano e che cosa ci si può fare. La guida che è presente nel sito non mi soddisfa molto. Grazie attendo risposta
antstan Inserita: 8 agosto 2012 Segnala Inserita: 8 agosto 2012 (modificato) Ciao, non mi ero reso conto di questa discussione quindi ho lanciato un'altra discussione simile e mi scuso... Pongo il mio problema quì. Batta ma come utilizzo i puntatori a 48 bit? Cioè io voglio puntare con AR1 ad una DB e con AR2 ad un'altra DB ed utilizzarli contemporaneamente senza richiamare ogni volta gli AUF. Ma come fare??? L'obiettivo è puntare ai dati in questo modo: L B [AR1,P#0.0] T B [AR2,P#0.0] In ciclo poi modifico direttamente AR1 ED AR2 incrementandoli a mio piacere... Modificato: 8 agosto 2012 da antstan
LudB Inserita: 9 agosto 2012 Segnala Inserita: 9 agosto 2012 Antstan, da quel che so io (e vado un po' a tentoni) i registri indirizzo a disposizione sono almeno due... quindi... //carico il DBx nel primo registro indirizzi AUF DBx LAR1 //carico il DBy nel secondo registro indirizzi AUF DBy LAR2 //adesso Ar1 e Ar2 sono impostati basta chiamare con gli offset //copio il primo bite di DBx nel secondo di DBy L DBB[Ar1,P#0.0] T DBB[Ar2,P#1.0]
antstan Inserita: 10 agosto 2012 Segnala Inserita: 10 agosto 2012 invece non è così. Come ho potuto capire i registri non contengono informazioni sul DB da puntare. Per tale motivo se AR1 deve puntare al DB X ed AR2 al DB Y quando si richiama un puntatore diverso si deve rifare l'AUF. Mi sembra strano ma i test da me effettuati... Scrivo un esempio su cui ho fatto dei test, prendo dei puntatori come ingresso alla FB: L P##P_Buffer // Variabile puntatore LAR1 L W [AR1,P#0.0] T #T_Db_Buffer // Variabile intera L D [AR1,P#2.0] LAR1 TAR1 #T_P_Buffer // DWord L P##P_BlockIn // Variabile puntatore LAR1 L W [AR1,P#0.0] T #T_Db_BufferIn // Variabile intera L D [AR1,P#2.0] LAR1 TAR1 #T_P_BufferIn // DWord // così ho salvato le mie locazioni ora quando mi servono faccio così LAR1 #T_P_Buffer LAR2 #T_P_BufferIn Auf #T_Db_Buffer L B [AR1, P0.0] T Byte_App Auf #T_Db_BufferIn L Byte_App T B[AR2,P0,0] Questo è l'unico modo in cui sono riuscito a farlo andare... Attendo notizie da chi è più esperto di me.
LudB Inserita: 10 agosto 2012 Segnala Inserita: 10 agosto 2012 antstan effettivamente mi devo ricredere ho provato del semplicissimo codice: FUNCTION "TestPun" : VOID TITLE = VERSION : 0.1 VAR_INPUT DBX_num : INT ; DBY_num : INT ; END_VAR VAR_OUTPUT Somma : INT ; END_VAR VAR_TEMP Buffer : INT ; END_VAR BEGIN NETWORK TITLE = L #DBX_num; //prendo il numero del DBX T #Buffer; // lo metto in un buffer temporaneo (non so bene perché devo fare così, ma o così o chiodi...) AUF DB [#Buffer]; // apro il DB num X L P#DBX 0.0; // carico l'indirizzo zero LAR1 ; // salvo l'indirizzo zero del DB num X in AR1 (in realtà vedremo che non è così... salvo solo lo scostamento dal primo dato del DB)... L #DBY_num; T #Buffer; AUF DB [#Buffer]; L P#DBX 0.0; LAR2 ; L DBW [AR1,P#0.0]; L DBW [AR2,P#0.0]; +I ; T #Somma; END_FUNCTION Poi ho provato: FUNCTION "TestPun2" : VOID TITLE = VERSION : 0.1 VAR_INPUT DBX_num : INT ; Merker : WORD ; END_VAR VAR_OUTPUT Somma : INT ; END_VAR VAR_TEMP Buffer : INT ; END_VAR BEGIN NETWORK TITLE = L #DBX_num; //prendo il numero del DBX T #Buffer; // lo metto in un buffer temporaneo (non so bene perché devo fare così, ma o così o chiodi...) AUF DB [#Buffer]; // apro il DB num X L P#DBX 0.0; // carico l'indirizzo zero LAR1 ; // salvo l'indirizzo zero del DB num X in AR1 (in realtà vedremo che non è così... salvo solo lo scostamento dal primo dato del DB)... L P##Merker; LAR2 ; L DBW [AR1,P#0.0]; L MW [AR2,P#0.0]; +I ; T #Somma; END_FUNCTION Poi ho provato anche: FUNCTION "TestPun3" : VOID TITLE = VERSION : 0.1 VAR_INPUT DBX_num : INT ; Merker : WORD ; END_VAR VAR_OUTPUT Somma : INT ; END_VAR VAR_TEMP Buffer : INT ; END_VAR BEGIN NETWORK TITLE = L P##Merker; LAR1 ; L #DBX_num; //prendo il numero del DBX T #Buffer; // lo metto in un buffer temporaneo (non so bene perché devo fare così, ma o così o chiodi...) AUF DB [#Buffer]; // apro il DB num X L P#DBX 0.0; // carico l'indirizzo zero LAR2 ; // salvo l'indirizzo zero del DB num X in AR2 (in realtà vedremo che non è così... salvo solo lo scostamento dal primo dato del DB)... L DBW [AR2,P#0.0]; L MW [AR1,P#0.0]; +I ; T #Somma; END_FUNCTION Infine ho chiamato le due funzioni in OB1: CALL "TestPun" DBX_num:=6 DBY_num:=7 Somma :=MW480 CALL "TestPun2" DBX_num:=6 Merker :=MW482 Somma :=MW484 CALL "TestPun3" DBX_num:=6 Merker :=MW482 Somma :=MW486 Ed ho analizzato i risultati: DB6.DBW 0 = 123 DB7.DBW 0 = 456 MW480 = 912 (!!!!) mi doveva venire 123+456=579; mentre in realtà mi ha sommato due volte DB7.DBW 0 infatti: 456+456=912 DB6.DBW 0 = 123 MW482 = 777 MW484 = 900 //ovvero con un DB e un merker non crea problemi (uso effettivamente le aree di memoria che volevo) MW486 = 900 Allora sembra proprio che passando il secondo DB al registro indirizzi 2 sovrascrivo anche il registro indirizzi 1... suppongo quindi che per puntare al DB il PLC utilizzi qualche altro registro che è uno solo.... ovvero può accedere un solo DB per volta (da cui bisogna richiamare sempre AUF DB ogni volta si cambia DB...) Guardando lo stack infatti sia AR1 che AR2 hanno lo stesso valore P#DBX0.0 = 84000000 hex (la prima area di memoria di un generico DB) mentre a sinistra c'è una voce che indica il DB aperto... Suppongo quindi che l'indirizzamento a DB sia così fatto PUNDB->ARx con AUF si setta PUNDB che è uno solo... Non si finisce mai di imparare... E' giusto, quello che scrivo?
LudB Inserita: 10 agosto 2012 Segnala Inserita: 10 agosto 2012 Nota: Dice Batta Per essere più precisi, il formato Pointer, lungo 6 byte, è composto come segue. Partendo dal byte più significativo, secondo lo standard Motorola o Big Endian: byte 0 e 1: numero del DB byte 2: codice area di memoria byte 3-4-5: indirizzo. Poi noi sappiamo che AR1 e AR2 sono a 32 bit (4 byte)... quindi è chiaro che i byte 0 e 1 non sono memorizzati in AR1 e/o AR2... da cui il problema...
antstan Inserita: 10 agosto 2012 Segnala Inserita: 10 agosto 2012 Concordo su tutto, In realtà la paura è che il continuo uso degli AUF appesantisca la funzione... Ho letto che si possono "aprire" 2 DB in contemporanea, 1 come Auf DB XXX e l'altro come istanza AUF DI YYY ma non sono riuscito ad utilizzarli... In ogni caso Batta ha affermato: Negli esempi del mio precedente post si notano principalmente due cose: 1) ho utilizzato un puntatore a 32 bit e non a 48 bit, come sopra descritto. In questo modo si perde l'informazione del numero del DB, che in questo caso non è rilevante. 2) il byte che dovrebbe contenere l'area di memoria (byte 2 nel caso di puntatore a 48 bit, byte 0 nel ca... Quindi probabilmente esiste un modo per utilizzare puntamenti a 48 bit ma io non l'ho trovato... Forse quando tornerà dalle vacanze...
l.bonacini Inserita: 10 agosto 2012 Segnala Inserita: 10 agosto 2012 (modificato) L'unico modoo è quellodii usare le db di istanza, ricorda che le word non saranno DBW ma ben DIW per i dati della db aperta come istanza Modificato: 10 agosto 2012 da l.bonacini
walterword Inserita: 11 agosto 2012 Segnala Inserita: 11 agosto 2012 imparate SCL , il linguaggio strutturato "ST" che si integra in step 7 I puntatori sono ormai cosa remota . Con SCL si posso no fare lavori complessi ed in pochi minuti , con i puntatori ci verrebbero settimane per raggiungere lo scopo ciao Walter
batta Inserita: 12 agosto 2012 Segnala Inserita: 12 agosto 2012 Con SCL si posso no fare lavori complessi ed in pochi minuti , con i puntatori ci verrebbero settimane per raggiungere lo scopo ciao In SCL lavorare con i puntatori è molto semplice, ma affermare che la differenza va da pochi minuti a settimane, mi pare un tantino esagerato, non credi? Poi noi sappiamo che AR1 e AR2 sono a 32 bit (4 byte)... quindi è chiaro che i byte 0 e 1 non sono memorizzati in AR1 e/o AR2... da cui il problema... Se in una funzione (FC o FB) dichiari un parametri in ingresso di tipo POINTER e, quando richiami la funzione, a questo parametro colleghi una variabile, in realtà passi alla funzione l'indirizzo di tale variabile. All'interno della funzione puoi scrivere: L P##Adr_IN LAR1 L W [AR1,P#0.0] T #Nr_DB L D [AR1,P#2.0] T #Adr_32bit Dove: - "Adr_IN" è il parametro in ingresso di tipo POINTER - "Nr_DB" è una variabile di tipo INT contenente il numero del DB (byte 0 e 1 della variabile "Adr_IN"). Se la variabile passata alla funzione non appartiene ad un DB, il valore sarà zero. - "Adr_32bit" è una variabiel di tipo DINT o DWORD contenente l'indirizzo della variabile, area di memoria compresa (byte 2-3-4-5 della variabile "Adr_IN") Nello stesso modo, si possono passare ad una funzione puntatori in formato ANY (10 byte).
walterword Inserita: 13 agosto 2012 Segnala Inserita: 13 agosto 2012 ti diro' che in molti impianti se on fosse esistito SCL avrei sicuramente cambiato mestiere ... i predecessori che lavoravano in awl hanno fatto sempre lavori limitati e chi ha voluto esagerare si e' trovato nel guano , oltre al fatto che poi la manutenibilità nel futuro e' pressoch' nulla . Impianti con tracking , magazzino autmatici con inserimento , modifica , recupero quote , nomi di prodotti o tipi (stringhe) d confrontare , cercare , formattare ....creare stringhe da inviare a stampanti , ricevere in seriale , gestire comunicazioni tcp/ip con aggeggi di ogni sorta ... In awl non ne vieni fuori più e per progettare il tutto ci vogliono giorni e poi e poi giorni in messa in servizio e poi giorni per rifare ....quindi settimane . Se invece devi puntare ad una tabella di valori int o dint o real allora ce la puoi fare . Non servovo a niente i puntatori , tutti gli ambienti di sviluppo plc , e anche i microprocessori , hanno il linguaggio ad alto livello ST , siemens ha SCL , ok si paga ma non e' poi cosi caro il prezzo considerando la quantità di codice prodotto ,testato e messo in funzione . La cosa importante e' saper gestire o avere fantasia nel creare la corretta base di dati , e qui step7 mette a disposizione meravigliosi DB che possono essere composti da array di strutture, da array di array di strutture ect . Quindi il lavoro principale e' l'analisi del sistema e mettere bene a fuoco cosa e come si deve fare. Per il resto con SCL poi si fa alla svelta , molto alla svelta . Non capisco come mai nel 2012 si voglia ancora ostinarsi a programmare i puntatori in awl ,forse per dimostrare le proprie capacità o una remota nostalgia ....non vi capisco ... Con questo senza nulla togliere alla vostra professionalità . In RSLogix , allen bradley , Schneider , Matsushita , Beckhoff , Vago ect ect c'e' sempre un tool ST . Codesys ha ST , Logic Lab ha ST , hanno tutti il linguaggio ST e lo usano tutti in maniera veloce e funzionale . I soft plc che sono ospitati da pc si programmano in ST , C , C++ La concentrazione del programmatore deve focalizzarsi sul cosa fare , fare alla svelta , rifare il meno possibile , riportare funzioni in altri progetti e ragionare , pensare programmando . Poi le macchine lavorano epr noi , compilano , arrangiano e sistemano .... bisogna pensare che l'automazione ormai e' una nicchia dell'informatica se la si fa a certi livelli , e di conseguenza adattarsi . Devo ammettere che la gestione puntatori in s7-200 e' molto piu veloce di step7 , in s7-200 e' come in C , "&" e " * " ... ciao Walter
Messaggi consigliati