Forum: Mikrocontroller und Digitale Elektronik RAM am AT Mega 16 auslesen mittelwerte zusammenfassen


von R--- S. (rene66)


Angehängte Dateien:

Lesenswert?

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.

von obake (Gast)


Lesenswert?

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

von Hannes L. (hannes)


Lesenswert?

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.

...

von obake (Gast)


Lesenswert?

Hallo Hannes,

> ... habe ich im Gegensatz zu obake mitbekommen, dass...

René  schreibt: "Assembler". Du schreibst: Ich bin auf einem Ego-Trip.

von obake (Gast)


Lesenswert?

Entschuldigung; bitte lesen: Beitrag "Umgangston hier"

von R--- S. (rene66)


Lesenswert?

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)

von Hannes L. (hannes)


Lesenswert?

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
Noch kein Account? Hier anmelden.