8 Bits in Byte speichern

HelmiMUC

Level-1
Beiträge
95
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich steh gerade auf dem Schlauch. Ich lese mir aus einem DB indirekt jeweils ein Bit aus 8 verschiedenen Adressen aus und möchte jeweils dieses Bit in einem Byte laden. Nur steh ich auf dem Schlauch gerade wie ich das am Besten programmier. Normalerweise hab ich mit indirekten Programmieren keine Probleme - nur jetzt komm ich einfach nicht vom Schlauch runter. Vielleicht könnte mir das jemand kurz erklären.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das ist mir schon klar.

ich muss etwas weiter ausholen.

ich habe einen db der etwa so aufgebaut ist:

0.0 1_bool1
0.1 1_bool2
2.0 1_int1
4.0 1_int2
6.0 1_int3
8.0 2_bool1
8.1 2_bool2
10.0 2_int1
12.0 2_int2
14.0 2_int3

ich errechne mit AR1 und lese dann dementsprechend die bool1´s aus.
Ausgelesen werden insgesamt 8 Bits

Die Bools möchte ich dann in einem DB126.DBB16 speichern.
 
Kann es sein, daß Du gerade etwas zu kompliziert denkst und sozusagen den Wald vor lauter Bäumen nicht siehst?

So wie's PeterHollanda geschrieben hat:
Code:
[FONT=courier new]U #ausgelesenes_Bit_1
[COLOR=#333333]= [/COLOR][COLOR=#333333]DB126[/COLOR][COLOR=#333333].[/COLOR][COLOR=#333333]DBX16[/COLOR][COLOR=#333333].0
[/COLOR]
U #ausgelesenes_Bit_2
[COLOR=#333333]= [/COLOR][COLOR=#333333]DB126[/COLOR][COLOR=#333333].[/COLOR][COLOR=#333333]DBX16[/COLOR][COLOR=#333333].1
[/COLOR]
...[/FONT]
oder ist das eigentliche Problem, daß das Ganze in 'ner Schleife geschieht?
 
ja sorry
ich denk leider schon den ganzen Tag kompliziert - und komme dann nicht auf die einfachsten Lösungen

das ist eine Schleife, die 8 mal durchläuft

theoretisch müsste es so funktionieren

U #ausgelesenes_Bit
SPBN end

SET
= db126.dbx16.0

L DB126.DBB16
shl 1
T DB126.DBB16

end: NOP0

oder steh ich immer noch wie der Ochs vorm Berg?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich vermute mal, wenn so:
Code:
/[FONT=courier new]/Schleifenstart, Durchlauf 8x
[/FONT][FONT=courier new]

[/FONT][FONT=courier new]// letztes Bit zum Speichern frei machen:[/FONT]
[FONT=courier new]L DB126.DBB16        // Byte laden[/FONT]
[FONT=courier new]SLW 1                // Bits 1 Stelle nach links verschieben
[/FONT][FONT=courier new]T DB126.DBB16        // Byte speichern[/FONT]

[FONT=courier new]
// Bit an letzter Stelle speichern:
U #ausgelesenes_Bit  // ausgelesenes Bit
= db126.dbx16.0      // an letzte Bitstelle schreiben


//nächster Schleifendurchlauf[/FONT]
Bin mir jetzt aus dem Stehgreif aber nicht sicher, ob Du links oder rechts schieben mußt.
 
Das schaut gut aus - hatte ich in meinem letzten Post auch (ähnlich) geschrieben

und links schieben ist meines Erachtens richtig

Aber das Bit 16.0 muss vor dem Schieben geschrieben werden, denn sonst würde beim ersten Schleifendurchgang sofort geschoben werden, ohne überhaupt zu schreiben
 
...
Aber das Bit 16.0 muss vor dem Schieben geschrieben werden, denn sonst würde beim ersten Schleifendurchgang sofort geschoben werden, ohne überhaupt zu schreiben
Nein, Du mußt erst den alten Brams wegschieben und dann das neue Bit an die freigewordene Stelle schreiben.

Denk mal an den 8. Durchlauf ->

Deine Variante: an
db126.dbx16.0 schreiben, schieben, Bit steht an db126.dbx16.1
bei mir: schieben, altes 8.bit fällt raus, letzten 7 bleiben erhalten, an db126.dbx16.0 schreiben -> 8 gespeicherte Bits​


PS: Wieso fügt die Forumssoftware einfach (immer vor den db126) irgendwelche Enter ein?
Nüschts zu machen. Eigentlich soll alles hinter "Deine Variante:" und "bei mir:" in jeweils einer Zeile stehen.
Kann mir das mal jemand erklären, warum das nicht geht? Ist doch nur simpler Text?
 
Zuletzt bearbeitet:
Kann ich nicht sagen, da ich den Rest Deines Programms ja nicht kenne:
...
Hängt davon ab, wie der Rest der Schleife aussieht.
Ist irgendwie so'n Bauchgefühl, das man als Laie manchmal hat.
:ROFLMAO:




PS: unter SCL würde ich wahrscheinlich ein solches Array indizieren und den Index über den Schleifenzähler ansprechen:
Code:
[FONT=courier new]VAR_TEMP
[/FONT][FONT=courier new]    TmpBYTE : BYTE;[/FONT]
[FONT=courier new]    TmpArray AT TmpBYTE : ARRAY[0..7] OF BOOL ;[/FONT]
[FONT=courier new]END_VAR[/FONT]
Hab' so 'ne Variablenansicht noch nie per Hand in den Lokalvariablen erstellt (unter AWL). Wie sieht das aus (Screenshot)?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
hab Nachtsch. und ein bisschen Zeit,
habe die Anforderung mit ner Sprungleiste gelöst, in einem gekapselten Baustein.
Wenn du was damit anfangen kannst freu ich mich, ansonsten war es ein schönes Training :D.
Die Offsets des Adressregisters mußt du natürlich noch anpassen, nützlich ist der Baustein natürlich auch nur, wenn du die
gleiche Datenstruktur der DB´s beibehälst.
Dass das ganze natürlich noch wesentlich kürzer geht ist mir klar, wollte es halt universell halten.

Code:
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  aktualisieren_Anfordern : BOOL ; 
  DB_Nr : INT ; 
  Anfang : INT ; 
END_VAR

VAR_OUTPUT
  Ausgabe_Byte : BYTE ; 
END_VAR

VAR_IN_OUT
  SPL_B : BYTE ; 
  Hilfsbyte : BYTE ; 
END_VAR

VAR_TEMP
  SPL_Byte : BYTE ; 
  Ausgabe : BYTE ; 
  DB_Nr_Speicher : WORD ; 
  Hilfsbyte_1 : BYTE ; 
END_VAR

BEGIN
NETWORK
TITLE =
      L     #Hilfsbyte; //Lade Hilfsbyte
      T     #Hilfsbyte_1; //transfer nach Temp. Hilfsbyte
     
      U     #aktualisieren_Anfordern; //Anforderung zum aktualisieren
      FP    L      4.0; //positive Flanke zum Anstoss nutzt Hilfsbit 0 aus Hilfsbyte
      SPBN  aus; //Sprung nach aus wenn kein Bedarf
      
      L     #SPL_B; //Hilfsbyte aus In-Out
      T     #SPL_Byte; //nach Temporär kopieren
      L     #DB_Nr; //gewünschter DB in 
      T     #DB_Nr_Speicher; //Temp. Speicher ablegen
      AUF   DB [#DB_Nr_Speicher]; //Öffnen des o.g. Datenbausteins
      L     #Anfang; //Anfangsadresse nach
      LAR1  ; //Adressregister

next: L     #SPL_Byte; //Lade die Nummer des Sprungziels in AKKU1-L-L.
      SPL   LSTX; //Sprungziel, wenn AKKU1-L-L > 3 ist.
      SPA   Bit0; //Sprungziel, wenn AKKU1-L-L = 0 ist.
      SPA   Bit1; //Sprungziel, wenn AKKU1-L-L = 1 ist.
      SPA   Bit2; //Sprungziel, wenn AKKU1-L-L = 2 ist.
      SPA   Bit3; //Sprungziel, wenn AKKU1-L-L = 3 ist.
      SPA   Bit4; //Sprungziel, wenn AKKU1-L-L = 4 ist.
      SPA   Bit5; //Sprungziel, wenn AKKU1-L-L = 5 ist.
      SPA   Bit6; //Sprungziel, wenn AKKU1-L-L = 6 ist.
      SPA   Bit7; //Sprungziel, wenn AKKU1-L-L = 7 ist.
LSTX: SPA   COMM; 

Bit0: U     DBX [AR1,P#0.0]; //ausgelesenes bit Nr.0
      =     L      1.0; //zuweisen auf Temp.var.  Ausgabe
      L     1; //nächster Schritt
      SPA   COMM; 
Bit1: U     DBX [AR1,P#0.1]; //ausgelesenes bit Nr.1
      =     L      1.1; //zuweisen auf Temp.var.  Ausgabe
      L     2; //nächster Schritt
      SPA   COMM; 
Bit2: U     DBX [AR1,P#0.2]; //ausgelesenes bit Nr.2
      =     L      1.2; //zuweisen auf Temp.var.  Ausgabe
      L     3; //nächster Schritt
      SPA   COMM; 
Bit3: U     DBX [AR1,P#1.1]; //ausgelesenes bit Nr.3
      =     L      1.3; //zuweisen auf Temp.var.  Ausgabe
      L     4; //nächster Schritt
      SPA   COMM; 
Bit4: U     DBX [AR1,P#1.2]; //ausgelesenes bit Nr.4
      =     L      1.4; //zuweisen auf Temp.var.  Ausgabe
      L     5; //nächster Schritt       
      SPA   COMM; 
Bit5: U     DBX [AR1,P#1.4]; //ausgelesenes bit Nr.5
      =     L      1.5; //zuweisen auf Temp.var.  Ausgabe
      L     6; //nächster Schritt
      SPA   COMM; 
Bit6: U     DBX [AR1,P#2.1]; //ausgelesenes bit Nr.6
      =     L      1.6; //zuweisen auf Temp.var.  Ausgabe
      L     7; //nächster Schritt
      SPA   COMM; 
Bit7: U     DBX [AR1,P#2.4]; //ausgelesenes bit Nr.7
      =     L      1.7; //zuweisen auf Temp.var.  Ausgabe
      L     0; //nächster Schritt
      SPA   COMM; 
COMM: T     #SPL_Byte; 
      L     #SPL_Byte; //Temporär nach
      T     #SPL_B; //In-Out schnittstelle kopieren
      L     0; //Vergleich mit ungleich 0
      <>I   ; //SPL ist noch nicht fertig
      SPB   next; //Sprungziel wenn noch nicht fertig
      L     #Ausgabe; //Lade Temp. Byte
      T     #Ausgabe_Byte; //Transfer nach Out (konsistent)
aus:  NOP   0; //Sprungziel bei kein Bedarf
      L     #Hilfsbyte_1; //Hilfsbyte aus Temp.Speicher laden
      T     #Hilfsbyte; //Nach In-Out schreiben
END_FUNCTION

gruß Thomas

P.S.: Wenn die Cracks mal drüber fliegen, wäre ich über Rückmeldungen positiver oder negativer Natur froh.
 
Nein, Du mußt erst den alten Brams wegschieben und dann das neue Bit an die freigewordene Stelle schreiben.

Denk mal an den 8. Durchlauf ->

Deine Variante: an
db126.dbx16.0 schreiben, schieben, Bit steht an db126.dbx16.1


bei mir: schieben, altes 8.bit fällt raus, letzten 7 bleiben erhalten, an db126.dbx16.0 schreiben -> 8 gespeicherte Bits​
Es muss doch rechts schieben sein, sonst ist mein niederwertigstes Bit nach 8 Schleifendurchgängen an der höherwertigsten Stelle
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...
ich habe einen db der etwa so aufgebaut ist:

0.0 1_bool1
0.1 1_bool2
2.0 1_int1
4.0 1_int2
6.0 1_int3
8.0 2_bool1
8.1 2_bool2
10.0 2_int1
12.0 2_int2
14.0 2_int3

ich errechne mit AR1 und lese dann dementsprechend die bool1´s aus.
Ausgelesen werden insgesamt 8 Bits ...
Dürfte man die Schleife mal sehen, mit der Du die boolschen Werte ausliest?
 
Zurück
Oben