Hallo, ich möchte gern folgende RAM Matrix im RAM eines Mega 16 so effektiv wie möglich auslesen. Die farbig hinterlegten Bereiche im Anhang stellen jewals ein Ergebnis das aus 3 Messwerten besteht also 8 x 3 mal den Mittelwert bilden und in einen extra Ram bereich schreiben. Habe momentan ein "Loch" im Kopf und komme nicht so Richtig weiter. Assembler Für Anregungen bin ich dankbar.
Hallo René, das ist doch davon abhängig, wie Du das RAM in der von Dir benutzten Software (welche ist das?) repräsentierst bzw. in welcher Reihenfolge die Daten im RAM landen. Und das wiederum ist von der Programmiersprache abhängig (z.B. läuft in C der 2. Parameter eines Arrays "schneller" als der erste). Du musst die Fragestellung also deutlich spezifischer formulieren, um eine sinnvolle Antwort zu erhalten. In welchem Datenformat liegen die Daten vor? Wertebereich? Welche Genauigkeit muss die Mittelwertbildung haben? Ohne diese Informationen geht es nicht! Viel Grüße obake, der Geist
Ich kann Deine Excel-Datei auch nicht interpretieren. Allerdings habe ich im Gegensatz zu obake mitbekommen, dass Du auf dem Mega16 in Assembler werkeln willst. Wie man das effektiv macht, ist von den Einzelheiten abhängig. Ist die Anzahl der Datensätze klein genug, bietet sich der Zugriff über LDD/STD an. Damit greifst Du über einen Pointer auf mehrere Bytes zu, die versetzt im RAM liegen. Da der Versatz maximal 63 betragen darf, geht es nur für kleine Arrays. Bei mehr Elementen muss dann mit 2 Pointern gearbeitet werden, die Einzelwerte eines Datensatzes kommen dann direkt hintereinander ins RAM und können mit LD reg,x+ angesprochen werden, das Ergebnis bekommt einen eigenen RAM-Bereich und wird mit einem eigenen Pointer adressiert. Du willst den Mittelwert aus 3 Werten. Warum nicht aus 2 oder 4? Mittelwert bildest Du durch Addition der Einzelwerte und Division durch die Anzahl der Werte. Der AVR kann sehr gut durch 2 oder 4 dividieren (LSR/ROR), aber nur sehr umständlich durch 3. Man kann sich das Leben auch unnötig schwer machen. Mehr kann ich jetzt nicht sagen, denn Deine Frage ist wirklich recht konfus formuliert. Formuliere sie neu und gib Dir etwas Mühe, sie unmissverständlich zu formulieren, vermutlich fällt Dir dabei bereits die Lösung ein. ...
Hallo Hannes,
> ... habe ich im Gegensatz zu obake mitbekommen, dass...
René schreibt: "Assembler". Du schreibst: Ich bin auf einem Ego-Trip.
Leute der Umgangston ist mir egal das Ergebnis zählt. @Hannes danke für die Infos ich möchte aus den farblich hinterlegten bereichen die aus je 8 x 3 Werten bestehen je einen Mittelwert je Gruppe A B und C erhalten. Also 8 x A = 8 Werte A addieren / Anzahl = Mittelwert A und im Ram Speichern 8 x B = 8 Werte B addieren / Anzahl = Mittelwert B ... 8 x C = 8 Werte C addieren / Anzahl = Mittelwert C ... und weiter zum nächsten Bereich 3 x 8 Byte (nächste Farbe)
René Schink wrote: > Leute der Umgangston ist mir egal das Ergebnis zählt. > > @Hannes danke für die Infos > > ich möchte aus den farblich hinterlegten bereichen die aus je 8 x 3 > Werten bestehen je einen Mittelwert je Gruppe A B und C erhalten. > > Also 8 x A = 8 Werte A addieren / Anzahl = Mittelwert A und im Ram > Speichern > 8 x B = 8 Werte B addieren / Anzahl = Mittelwert B ... > 8 x C = 8 Werte C addieren / Anzahl = Mittelwert C ... > > und weiter zum nächsten Bereich 3 x 8 Byte (nächste Farbe) Ich gehe mal davon aus, dass jeder "Wert" ein Byte ist und dass die drei Bytes auch drei unterschiedliche Werte repräsentieren und nicht drei Bytes eines großen Wertes (dann müsste man Überträge berücksichtigen). Ich würde die Datem im RAM so organisieren, dass jeweils 9 Bytes hintereinander einen "Satz" ergeben. Das erste Byte ist dann jeweils das Ergebnis (Mittelwert), dann folgen die 8 Einzelbytes. Nach Gruppe A kommt Gruppe B, dann Guppe C, danach wieder Gruppe A der nächsten Farbe. Der Job der Mittelwertbildung macht nun Folgendes:
1 | mach_mittelwerte: ;Aufruflabel |
2 | ldi yl,low(daten) ;Pointer (Y oder Z, X geht nicht) auf |
3 | ldi yh,high(daten) ;Beginn des ersten Datensatzes positionieren |
4 | mach_next_mw: ;Schleifenbeginn |
5 | clr sum_l ;2 Hilfsregister (Zwischensumme) bereitstellen |
6 | clr sum_h ;und löschen |
7 | ldd tmp,y+1 ;Wert lesen, Byte 1 |
8 | add sum_l,tmp ;Wert aufsummieren |
9 | ; adc sum_h,null ;evtl. Übertrag auch (beim ersten mal noch nicht) |
10 | ldd tmp,y+2 ;Wert lesen, Byte 2 |
11 | add sum_l,tmp ;Wert aufsummieren |
12 | adc sum_h,null ;evtl. Übertrag auch |
13 | ldd tmp,y+3 ;Wert lesen, Byte 3 |
14 | add sum_l,tmp ;Wert aufsummieren |
15 | adc sum_h,null ;evtl. Übertrag auch |
16 | ldd tmp,y+4 ;Wert lesen, Byte 4 |
17 | add sum_l,tmp ;Wert aufsummieren |
18 | adc sum_h,null ;evtl. Übertrag auch |
19 | ldd tmp,y+5 ;Wert lesen, Byte 5 |
20 | add sum_l,tmp ;Wert aufsummieren |
21 | adc sum_h,null ;evtl. Übertrag auch |
22 | ldd tmp,y+6 ;Wert lesen, Byte 6 |
23 | add sum_l,tmp ;Wert aufsummieren |
24 | adc sum_h,null ;evtl. Übertrag auch |
25 | ldd tmp,y+7 ;Wert lesen, Byte 7 |
26 | add sum_l,tmp ;Wert aufsummieren |
27 | adc sum_h,null ;evtl. Übertrag auch |
28 | ldd tmp,y+8 ;Wert lesen, Byte 8 |
29 | add sum_l,tmp ;Wert aufsummieren |
30 | adc sum_h,null ;evtl. Übertrag auch |
31 | ;nun sind alle 8 Werte aufsummiert, eine Schleife dafür hätte mehr |
32 | ;Rechenzeit gekostet |
33 | lsr sum_h ;durch 2 |
34 | ror sum_l ;teilen (2) |
35 | lsr sum_h ;durch 2 |
36 | ror sum_l ;teilen (4) |
37 | lsr sum_h ;durch 2 |
38 | ror sum_l ;teilen (8) |
39 | ;Mittelwert steht nun in sum_l |
40 | std y+0,sum_l ;Mittelwert an Pointerposition speichern |
41 | adiw yh:yl,9 ;Pointer um 9 Byte-Positionen erhöhen |
42 | cpi yl,low(daten + ds*9) ;Auf Ende (Basisadresse Daten + Anzahl |
43 | brne mach_next_mw ;Datensätze * 9 Bytes) prüfen (ungleich, nochmal...) |
44 | cpi yh,high(daten + ds*9) ;Highbyte auch auf Ende |
45 | brne mach_next_mw ;prüfen (ungleich, nochmal...) |
46 | ret ;fertig... |
Der Code ist einfach ungetestet dahingeschrieben und kann noch Fehler enthalten, Du solltest ihn also prüfen. Ich habe in fast jedem Programm ein unteres Register namens "null" das immer den Wert 0 hat. Das erleichtert das Aufaddieren des Carry-Flags (Übertrag). Ich hoffe, ich konnte helfen, Deine Denkblockade zu lösen. ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.