over Inserito: 24 luglio 2006 Segnala Inserito: 24 luglio 2006 (modificato) ...Premetto che ho gia usato la funzione cerca...Ciao a tutto il forum,Vorrei riscrivermi la funzione Real to String, ma non avendo nessuna esperienza coi puntatorimi sono subito arenato Il codice che ho scritto (per il momento) e' tutto qui sotto (ovviamente chiamato da OB1)ma con tabella variabili "alla mano" ho gia' visto che la DB120.DBB0..100 (area del SEND_DATA.InputString) non viene aggiornato col valore di RET_VAL.-------------------------FC1-------------------------- CALL FC 32 Value :=MD130 <--valore real da convertire RET_VAL:="SEND_DATA".InputString <--P#DB120.DBX0.0----------------------------------------------------------------------------------FC32-------------------------- L P##RET_VAL <---di tipo string[254] LAR1 L 'S' <-- Vorrei scrivere il carattere "S" sul primo carattere utile di RET_VAL T B [AR1,P#2.0]---------------------------------------------------------C'e' qualcuno che mi puo' dire perche' SEND_DATA.InputString non viene aggiornato colvalore di RET_VAL?Grazie anticipatamente per le risposte che mi darete.Over. Modificato: 24 luglio 2006 da over
Matteo Montanari Inserita: 17 agosto 2006 Segnala Inserita: 17 agosto 2006 (modificato) dichiari di voler "scrivere" una funzione Real to String, nè esiste già una fatta nelle librerie Siemens (FC 30 R_STRNG nella libreria "IEC Function Blocks").comunque per risolvere il problema che hai posto: L P##RET_VAL LAR1 L W [AR1,P#0.0] T #w_db_nr // appoggio per puntare il blocco dati "puntato" AUF DB [#w_db_nr] L D [AR1,P#2.0] LAR1 LAR2 //; L 'S' T B [AR2,P#2.0]Il codice risulta essere questo.in Siemens i primi due caratteri sono utilizzati dal sistema. (quindi la prima Word)il carattere "S" viene visualizzato in DB120.DBB2, il primo carattere disponibile. Modificato: 17 agosto 2006 da keosmm
over Inserita: 19 agosto 2006 Autore Segnala Inserita: 19 agosto 2006 dichiari di voler "scrivere" una funzione Real to String...no ...piuttosto di voler ri-scrivermi la funzione real to stringnè esiste già una fatta nelle librerie Siemens (FC 30 R_STRNG nella libreria "IEC Function Blocks").si e' vero, ma non mi garba il formato che ottengo da questa stringa, e' per questo che la voglio riscrivere.Comunque intanto grazie 1000 dello snippet; oggi pomeriggio lo esamino meglio.Ciao e grazie.
Matteo Montanari Inserita: 19 agosto 2006 Segnala Inserita: 19 agosto 2006 dunque, se ti interessa il codice della funzione FC 30 R_STRNG nella libreria "IEC Function Blocks" potresti vedere qui sotto:FUNCTION FC 30 TITLE = Real to String STANDARD VERSION : 0.0 VAR_INPUT IN : REAL; // REAL END_VAR VAR_TEMP l_Exp_10 : DINT; // 10er Exponent d_Temp : DWORD; // Zwischenspeicher l_Mantis : DINT; // Mantisse als DINT l_Man_High : DINT; // High-Teil Mantisse > 9.999.999 l_BCD_Hi : DINT; // High-Teil Mantisse BCD l_BCD_Lo : DINT; // Low-Teil Mantisse BCD w_db_nr : WORD; y_LoopCnt : BYTE; // Schleifenzähler b_Sign : BOOL; // Vorzeichen IN 0=neg., 1=pos. b_Sign_Exp : BOOL; // Vorzeichen Exponent b_Fehl1 : BOOL; // Fehlermerker eingerichter String zu kurz b_q_NaN : BOOL; // Fehlermerker IN kein REAL b_Null : BOOL; // Merker IN = 0.0 RET_VAL : STRING [254] END_VAR BEGIN NETWORK TITLE = // Voreinstellungen SET ; SAVE ; // BIE := 1 S #b_Sign; S #b_Sign_Exp; // Vorzeichen '+' R #b_Null; // Fehlermerker rücksetzen R #b_q_NaN; L L#0; T #l_BCD_Hi; // Merker BCD löschen T #l_BCD_Lo; T #l_Exp_10; // Exponent löschen // Pointer auf IN L P##RET_VAL; //STRING zeiger (db_nr) LAR1 ; L W [AR1,P#0.0]; //db_nr laden T #w_db_nr; AUF DB [#w_db_nr]; L D [AR1,P#2.0]; //STRING offset im db LAR1 ; LAR2 ; // Adressreister 1/2 auf Anfang String // Pruefung ob Ziel lang genug eingerichtet, Minimum 14 Bytes L B [AR1,P#0.0]; //res. Länge im DB L 14; // kleiner als 14 Byte <I ; // ja, dann Fehler = #b_Fehl1; SPB FEHL; //int string > ges. string // Pruefung ob IN eine Gleitpunktzahl L #IN; // IN + 0.0 SLD 1; // Vorzeichen schieben U ==0; // IN positiv = #b_Sign; // Sign:= 1; SRD 1; // IN zurückschieben -> damit ist L 0.000000e+000; // IN die Betragszahl +R ; // IN muss definiert sein als REAL U UO; // Ergebnis liefert unordered? S #b_q_NaN; // Merker IN kein REAL SPB FEHL; U ==0; // wenn IN = 0 S #b_Null; // wird ein Nullstring ausgegeben SPB NWE2; // 1. Lösungsansatz: Exponent zur Basis 10 suchen // Exp_10 = log IN/b; wobei b=Mantisse, wird mit 1 angenommen // Log a = Ln(a)/Ln(10) // 10 LN ; // LN(IN); L 2.302585e+000; //ln (10) /R ; RND+ ; T #l_Exp_10; // Ergebnis ist Exponent zur Basis 10 als INT L 0; +D ; U >=0; = #b_Sign_Exp; // Merker Vorzeichen Exponent SPB Wert; NEGD ; T #l_Exp_10; Wert: T #l_Exp_10; // Betrag von Exp_10 // Nachbildung von 10^x; x steht im LB3 (Temp); L 1.000000e+000; UN L 3.0; SPB E02; L 1.000000e+001; *R ; E02: UN L 3.1; SPB E04; L 1.000000e+002; *R ; E04: UN L 3.2; SPB E08; L 1.000000e+004; *R ; E08: UN L 3.3; SPB E016; L 1.000000e+008; *R ; E016: UN L 3.4; SPB E032; L 1.000000e+016; *R ; E032: UN L 3.5; SPB FERT; L 1.000000e+032; *R ; // 2. Lösungsansatz: Mantisse mit Exp_10 berechnen. // Mantisse = IN/10^EXP_10, mit 10^x aus obiger Nachbildung FERT: L #IN; // Eingangswert IN / 10^x * 10^7 TAK ; UN #b_Sign_Exp; // wenn Sign_Exp negativ SPB Mul; // dann IN*10^x /R ; // sonst IN/10^x SPA Weit; Mul: *R ; Weit: L 1.000000e+007; // Kommastellen REAL schieben nach rechts *R ; RND ; // Mantisse als Int. T #l_Mantis; NETWORK TITLE = // BCD wandel in String und kopieren NWE2: U #b_Null; SPB ZERO; L L#10000000; // Mantisse / 10000000 -> /D ; T #l_Man_High; // liefert Stellen > 9.999.999 DTB ; T #l_BCD_Hi; // BCD-Wert der Mantisse High L #l_Man_High; L L#10000000; // High_Mantisse * 10000000 - Mantisse *D ; // = Mantisse <=9.999.999 L #l_Mantis; TAK ; -D ; DTB ; // Mantisse Low -> BCD T #l_BCD_Lo; // Wandlung Mantisse High in String ZERO: L #l_BCD_Hi; // Mantisse High hat nur eine Stelle OD DW#16#30; // 1. Stelle mit 30h verodern -> BCD to ASCII T B [AR1,P#3.0]; // kopiere in String an 3.Stelle SPA SCHL; // Wandlung Mantisse Low in String und Übertragung in String, es wird mit // der kleinsten Stelle der Mantisse begonnen SCHL: +AR1 P#11.0; L 7; // Schleifenzähler := 7 Zeichen= Nachkommastellen LOP: T #y_LoopCnt; L #l_BCD_Lo; UD DW#16#F; // eine Tetrade einblenden OD DW#16#30; // mit 30h. verodert -> BCD to ASCII T B [AR1,P#0.0]; // in String ablegen L #l_BCD_Lo; SRD 4; // nächste Tetrade rechtsbündig T #l_BCD_Lo; L -8; // AR1 - 1 Bytestelle +AR1 ; L #y_LoopCnt; LOOP LOP; // im String steht: -x-xxxxxxx---- // feste Stellen in String eintragen // Vorzeichen Mantisse eintragen U #b_Sign; // wenn Vorzeichen + L '+'; // dann ASCII + für Mantisse SPB SIG; L '-'; // sonst - SIG: T B [AR2,P#2.0]; // Dezimalpunkt L '.'; // Dezimalpunkt nach erster Stelle T B [AR2,P#4.0]; // Zeichen Exponent 'E' L 'E'; // ASCII E für Exp. T B [AR2,P#12.0]; // Vorzeichen Exponent übergeben U #b_Sign_Exp; // wenn Vorzeichen + L '+'; // dann ASCII + für Mantisse SPB ***P; L '-'; // sonst - ***P: T B [AR2,P#13.0]; // Exponent eintragen L #l_Exp_10; // Exponent -> BCD ITB ; PUSH ; // A1 -> A2 SLW 4; // A1 um eine Tetrade verschieben OW ; // -> -x-x, schafft je um eine Tetrade Platz UW W#16#F0F; OW W#16#3030; // BCD -> ASCII T W [AR2,P#14.0]; // in String L 14; T B [AR2,P#1.0]; // Anzahl Bytes := 14 SPA ENDE; FEHL: CLR ; // ja, dann BIE:=0 SAVE ; ENDE: BE ; END_FUNCTIONchiaramente devi sistemarlo un pochino se incontri degli errori...
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