Marco75 Inserito: 16 febbraio 2005 Segnala Inserito: 16 febbraio 2005 Ciao a tutti,ho un problema di questo tipo:Devo utilizzare la funzione di libreria dello STEP7 "ATH" (conversione ASCII to HEX);questa funzione riceve in ingresso l'indirizzo del primo carattere da convertire, informato POINTER.Purtroppo questo indirizzo di partenza non è per me sempre lo stesso ma in base adei calcoli può variare, cioè vorrei poter puntare ad un qualsiasi byte della DB2 e poi passare questo indirizzo alla ATH.Ho fatto vari tentativi ma ho paura che l'ingresso di tipo POINTER accetti solo puntatori"costanti" del tipo P#DB2.DBX0.0.Grazie mille a tutti coloro che risponderanno.
Matteo Montanari Inserita: 16 febbraio 2005 Segnala Inserita: 16 febbraio 2005 Ho fatto vari tentativi ma ho paura che l'ingresso di tipo POINTER accetti solo puntatori"costanti" del tipo P#DB2.DBX0.0.esatto.potresti "trasferire" i tuoi dati da convertire sempre nella stessa area (utilizzata come area del puntatore)non sò a cosa ti serve il valore in HEX ma ricorda che se si tratta di convertire numeri o lettere da ASCII a Decimale occorre sottrarre alla cifra ASCII la costante 48 (30 HEX) e che un carattere ASCII occupa un byte.può essere che se si tratta di pochi dati di cui fare la conversione ti basti questo, senza utilizzare il blocco "pre-confezionato SIEMENS"in alternativa potresti controllare questo codice se ti è d'aiuto:FUNCTION "ATH" : WORD TITLE = ASCII TO HEX AUTHOR : SEA FAMILY : CONVERT NAME : ATH VERSION : 2.0 VAR_INPUT IN : POINTER; // pointer to an ASCII string N : WORD; // number characters (bytes)in ASCII string END_VAR VAR_OUTPUT OUT : POINTER; // pointer to the hexidecimal destination table END_VAR VAR_TEMP BLKNO : WORD; // Block number INDX_A : DWORD; // Character index INDX_D : DWORD; // Digit index INVFLG : WORD; // Invalid flag TMP1 : BYTE; // value of the table WORD currently read TMP2 : BYTE; // Hex digit ANDed w/0x000F, then added to x30/x37 TMPLEN : WORD; // length val. used in validating hex digits N2 : WORD; // copy of org. TMPLEN value, used for comparison TEMP_AR2 : DWORD; // Storage for AR2 contents, which is restored before return END_VAR BEGIN NETWORK TITLE = TAR2 #TEMP_AR2; // Save Address register 2 contents L 0; T #INVFLG; T #RET_VAL; T #INDX_D; // Open DB of ptr to ascii input digits L P##IN; LAR1 ; // Addr.Reg1 = Ptr to Src. Table L W [AR1,P#0.0]; // load Block No. into accum 1 T #BLKNO; // scrblk = Block No. AUF DB [#BLKNO]; // opens 1st Block, DB L D [AR1,P#2.0]; // load Block Area Reference LAR1 ; // load Block Addr.(area ref.)into Addr.Reg1 //--------------------------------------------------------------------------- // Open DI of ptr to hex output digits L P##OUT; LAR2 ; // Addr.Reg2 = Ptr to output L W [AR2,P#0.0]; // load Block No. into accum 1 L 0; // CORRECTION ADDED BY STEVE LOVELL ON 5/98 ==I ; SPZ BEGN; L W [AR2,P#0.0]; // CORRECTION ADDED BY STEVE LOVELL ON 5/98 T #BLKNO; // scrblk = Block No. AUF DI [#BLKNO]; // opens DI Block // // START OF CORRECTION ADDED BY STEVE LOVELL 5/98 // L DW#16#5000000; // OR mask for DIX memory area in ptr L D [AR2,P#2.0]; // load Block Area Reference; start addr. OD ; // Force memory area to DIX LAR2 ; // Save into AR2 SPA BEG2; // Jump to label BEG2 // // END OF CORRECTION // BEGN: L D [AR2,P#2.0]; // start addr. LAR2 ; // load Block Addr.(area ref.)into Addr.Reg1 BEG2: NOP 0; // CORRECTION ADDED BY STEVE LOVELL ON 5/98 //--------------------------------------------------------------------------- // Check validity of each ascii input characters L 0; T #TMP2; T #TMP1; L #N; T #TMPLEN; T #N2; L 0; ==I ; SPB DONE; // if length=0, there is nothing to do // If length is an odd number, make the length even (add 1) L W#16#1; L #TMPLEN; UW ; L 0; ==I ; SPB BGIN; L #TMPLEN; L 1; +I ; T #TMPLEN; T #N2; BGIN: L #TMPLEN; NEXT: T #TMPLEN; L B [AR1,P#0.0]; // Accum2, if(digit < 0x2F) L B#16#30; // Accum1 <I ; SPB BAD; // Bad, Out of range //---- L B [AR1,P#0.0]; // Accum2, if(digit > 0x0x47) L B#16#46; // Accum1 >I ; SPB BAD; // Bad, Out of range //---- L B [AR1,P#0.0]; // Accum2, if(digit == 0x0x40) L B#16#40; // Accum1 ==I ; SPB BAD; // Bad, Out of range //--------------------------------------------------------------------------- L B [AR1,P#0.0]; // Accum2, if(digit < 0x3A) L B#16#3A; // Accum1 <I ; SPB SB30; // Go subtract 0x30 //---- L B [AR1,P#0.0]; // Accum2, if(digit > 0x40) L B#16#40; // Accum1 >I ; SPB SB37; // Go subtract 0x37 BAD: L 1; // Invalid value: set "invalid' flag T #INVFLG; L 0; T #TMP1; SPB CONT; // Go process as zero value //--------------------------------------------------------------------------- SB30: L B [AR1,P#0.0]; L B#16#30; -I ; T #TMP1; SPA CONT; SB37: L B [AR1,P#0.0]; L B#16#37; -I ; T #TMP1; //--------------------------------------------------------------------------- CONT: L #INVFLG; L 1; ==I ; // if (INVFLG =1) SPBN GOOD; L 7; T #RET_VAL; // Set ErrorCode in RET_VAL L 0; T #INVFLG; // Re-set INVFLG to 0 //---- GOOD: L #INDX_D; // INDX_D = INDX_D + 1; L 1; +I ; T #INDX_D; L 2; // when INDX_D is 2, time to write out a byte ==I ; SPB WOUT; // go merge nibbles & write out hex byte L #TMP1; SLW 4; T #TMP2; // If last nibble needs filler of 0, detect & set it up here L 2; L #TMPLEN; // Is pointer at last byte? <>I ; SPB REPT; // No, pointer is not at last nibble yet L #N2; // Pointer at last nibble, is filler needed? L #N; ==I ; // No, no filler needed SPB REPT; L 0; // Yes, make last nibble a 0 T #TMP1; L #TMPLEN; L 1; -I ; T #TMPLEN; // Decrement TMPLEN manually if using filler WOUT: L #TMP2; L #TMP1; OW ; // Merge 2 nibbles into one byte T B [AR2,P#0.0]; // write one byte to output L 0; T #TMP2; // clear out variables by writing zeros T #INDX_D; // Increment AR2, Hex Ouput pointer, by one byte +AR2 P#1.0; REPT: +AR1 P#1.0; // Increment AR1, ASCII Input pointer, by one byte L 0; T #TMP1; // Clear out TMP1 byte variable L #TMPLEN; // LOOP statement decrements TMPLEN LOOP NEXT; DONE: L 0; L #RET_VAL; <>I ; SPB FAIL; SET ; SPA STOP; FAIL: CLR ; STOP: SAVE ; LAR2 #TEMP_AR2; // Restore Address Register 2 Contents END_FUNCTION mentre questo codice è la funzione inversa FUNCTION "HTA" : VOID TITLE = HEX TO ASCII AUTHOR : SEA FAMILY : CONVERT NAME : HTA VERSION : 2.0 VAR_INPUT IN : POINTER; N : WORD; END_VAR VAR_OUTPUT OUT : POINTER; END_VAR VAR_TEMP BLKNO : WORD; // Block number INDX_D : DWORD; // Digit index TMP1 : WORD; // the BYTE nibble being converted from Hex to Ascii SAVTMP1 : WORD; // the table BYTE that was read last TMPLEN : WORD; // length val. -Number of bytes in table ABYTE : BYTE; // TMP1 value stored as a BYTE value TEMP_AR2 : DWORD; // Storage for AR2 contents, which is restored before return END_VAR BEGIN NETWORK TITLE = TAR2 #TEMP_AR2; // Save Address register 2 contents // If length to be converted is 0, return immediately L #N; L 0; ==I ; SPB DONE; // Open DB of ptr to hex input digits L P##IN; LAR1 ; // Addr.Reg1 = Ptr to Src. Table L W [AR1,P#0.0]; // load Block No. into accum 1 T #BLKNO; // scrblk = Block No. AUF DB [#BLKNO]; // opens 1st Block, DB L D [AR1,P#2.0]; // load Block Area Reference LAR1 ; // load Block Addr.(area ref.)into Addr.Reg1 //--------------------------------------------------------------------------- // Open ptr to output Ascii Locations as a DI L P##OUT; LAR2 ; // Addr.Reg2 = Ptr to Output L W [AR2,P#0.0]; // load Block No. into accum 1 L 0; // CORRECTION ADDED BY STEVE LOVELL 5/98 ==I ; SPZ BEGN; L W [AR2,P#0.0]; // CORRECTION ADDED BY STEVE LOVELL 5/98 T #BLKNO; // scrblk = Block No. AUF DI [#BLKNO]; // opens DI Block // // START OF CORRECTION ADDED BY STEVE LOVELL 5/98 // L DW#16#5000000; // OR mask for DIX memory area in ptr L D [AR2,P#2.0]; // load Block Area Reference; start addr. OD ; // Force memory area to DIX LAR2 ; // Save into AR2 SPA BEG2; // Jump to label BEG2 // // END OF CORRECTION // BEGN: L D [AR2,P#2.0]; // start addr. LAR2 ; // load Block Addr.(area ref.)into Addr.Reg1 BEG2: NOP 0; // CORRECTION ADDED BY STEVE LOVELL 5/98 //--------------------------------------------------------------------------- L #N; // Load length of HEX table BYTS: T #N; L B [AR1,P#0.0]; // Load byte from table T #TMP1; // and write it into TMP1 word T #SAVTMP1; // save a copy of the table's org. value L 2; // number of hex input digits extracted DIGT: T #INDX_D; // 1 byte (2 hex digits); 1 byte=2 nibbles //------------- L #SAVTMP1; // save a copy of the table's org. value T #TMP1; L 2; L #INDX_D; <>I ; SPB MASK; L #TMP1; SRW 4; T #TMP1; //------------- MASK: L #TMP1; // Accum 2 L W#16#F; // Accum 1 UW ; // TMP1 AW 0x000F (mask off all but lower nibble) T #ABYTE; // convert from WORD to BYTE L B#16#A; // Load 0x0A <I ; // (Accum2 < Accum1)? (ABYTE < 0x0A)? SPB A030; // Jump to Add 0x30 SPA A037; // Jump to Add 0x37 // Add 0x30 A030: L B#16#30; L #ABYTE; +I ; // 0x30 + ABYTE T #ABYTE; SPA CONT; // Jump to continue // Add 0x37 A037: L B#16#37; L #ABYTE; +I ; // 0x37 + ABYTE T #ABYTE; //--------------------------------------------------------------------------- // Continue CONT: L #ABYTE; T B [AR2,P#0.0]; // Write BYTE to ouput +AR2 P#1.0; // Increment pointer to output (by 1 byte) //--------------------------------------------------------------------------- L #SAVTMP1; // Copy original table's BYTE value into TMP1 T #TMP1; L #INDX_D; LOOP DIGT; // }while (INDX_D <= 2) //--------------------------------------------------------------------------- +AR1 P#1.0; L 0; // Clear out TMP1 WORD T #TMP1; // before reading next byte from table L #N; LOOP BYTS; // }while (N > 0) SPA DONE; //--------------------------------------------------------------------------- DONE: SET ; SAVE ; LAR2 #TEMP_AR2; // Restore Address Register 2 Contents END_FUNCTION
STEU Inserita: 16 febbraio 2005 Segnala Inserita: 16 febbraio 2005 Caro Marco ti posso consigliare di andare a vedere il manuale Programmazione con step 7 che trovi nella documentazione sotto il menu Siemens che spiega come è fatto un parametro pointer.quindi tu come parametro devi passare all'FC un doppia parola ,md ad esempio,e all'interno della doppia parola devi mettere i dati come descritto nela manuale dopo averli calcolati.La spiegazione la trovi nell'appendice dalla pagina A51 alla pagina A55Se non è chiaro posta di nuovo.Ciao
Marco75 Inserita: 17 febbraio 2005 Autore Segnala Inserita: 17 febbraio 2005 Grazie ragazzi,conoscendo esattamente il formato dei dati pointer ed avendo a disposizionei sorgenti delle funzioni ho tutte le informazioni necessarie per potermi crearedelle funzioni ad hoc. A proposito, come si rimediano quei sorgenti?Ancora grazie e a prestoMarco
Matteo Montanari Inserita: 17 febbraio 2005 Segnala Inserita: 17 febbraio 2005 A proposito, come si rimediano quei sorgenti?i sorgenti sono protetti, basta "sproteggerli"... :ph34r:
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