Forum: Compiler & IDEs Problem mit zu großen Arrays im EEPROM


von Gerhard L. (Gast)


Lesenswert?

Hallo Forum,

ich bekomme meine Arrays leider nicht in den internen EEprom (mega32) 
unter und suche daher eine gute Möglichkeit wie ich dies anders regeln 
kann.

#include <avr/eeprom.h>

#ifndef EEMEM
#define EEMEM _attribute_ ((section (".eeprom")))
#endif

uint16_t varay1[4096] EEMEM;
uint16_t varay2[4096] EEMEM;
uint16_t varay3[4096] EEMEM;
uint16_t varay4[4096] EEMEM;
uint16_t varay5[4096] EEMEM;

Dies nutze ich derzeit, was ja nicht funktionieren kann.
gibt es einen ähnlich einfachen Weg für externe Speicher?

Gruß Gerhard

von Gast (Gast)


Lesenswert?

Hallo,
> gibt es einen ähnlich einfachen Weg für externe Speicher?
nein, ein Mega32 kennt keinen externen Speicher. Du müsstest die 
Verwaltung also selber übernehmen, da der Compiler hier nicht mithelfen 
kann.

MfG

von Peter D. (peda)


Lesenswert?

Du könntest nen AT24C512 ranpappen.

Aber hast Du Dir erstmal überlegt, wozu Du die 40kB überhaupt brauchst?


Peter

von Gerhard L. (Gast)


Lesenswert?

@Peter, ja ich komm da nicht drumrum. Den 24c512 hab ich mir schon 
angesehen gehabt da ich damit gerechnet hatte.

Gibts dafür keine Lib. oder irgenwas das einem die Arbeit erleichtert, 
ich bin noch recht neu in C und AVR, mir platzt bald der Kopf g

von Peter D. (peda)


Lesenswert?

Gerhard L. wrote:
> @Peter, ja ich komm da nicht drumrum. Den 24c512 hab ich mir schon
> angesehen gehabt da ich damit gerechnet hatte.
>
> Gibts dafür keine Lib.

Hier ist ein Beispiel:

Beitrag "programmierbare 16 Kanal PWM Lightshow"

Du kannst aber nicht direkt auf den EEPROM zugreifen. Du kannst nur 
Daten von und zum SRAM kopieren.


Erzähl dochmal, wozu diese große Menge EEPROM, dann läßt sich bestimmt 
noch einiges optimieren.


Peter

von Gerhard L. (Gast)


Lesenswert?

Das schau ich mir morgen mal genau an.

Mit in SRAM kopieren is nicht schlimm, ich brauch immer nur ein Array 
von den 5.

Ok ich versuch mal zu erklären:
Ich hab nen analogen Sensor am ADC hängen welcher mit 10bit gelesen 
wird.
Nun muß ich als Linearisierung zu allen 10bit nen Wert haben der am DAC 
wieder raus kommt.
Die Arrays erstellt ein PC-Programm welche dann per RS232 in den EEPROM 
übertragen werden müssen.

Wenn noch Fragen offen nur her damit.

von Gast (Gast)


Lesenswert?

Hallo,

eventuell lässt sich die Linearisierung mathematisch über eine Formel 
lösen?

MfG

von Gerhard L. (Gast)


Lesenswert?

Ich denke das ginge aber ich kann mir das nicht so wirklich aussuchen.
Der Witz soll wohl auch eher eine nichtlineare Abweichung sein, ich weiß 
es nicht da ich es nicht erdacht habe.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Ich hab nen analogen Sensor am ADC welcher mit 10bit gelesen wird.
Bist du sicher, dass du effektiv nicht nur 9 Bit hast?
Und damit eine halb so große Tabelle ausreichen würde?

> Der Witz soll wohl auch eher eine nichtlineare Abweichung sein...
Aber doch nicht so, dass jedem benachbarten AD-Wert ein ganz anderer 
Ausgangswert zugeordnet werden muß? So extrem nichtlinear kann doch kein 
Sensor sein. Wie wäre es mit einer Tabelle mit z.B. 200 Werten und einer 
Geradeninterpolation dazwischen?

> ich weiß es nicht da ich es nicht erdacht habe.
Dann geh doch mal zum großen Denker und schlag dem das vor... :-/

von Oliver (Gast)


Lesenswert?

>Mit in SRAM kopieren is nicht schlimm, ich brauch immer nur ein Array
>von den 5.

Du weißt aber schon, das selbst das SRAM der größten Megas nur halb so 
groß wie eins deiner Array ist, oder?

Also brauchst du auch noch externes SRAM, und einen Mega mit passendem 
Interface.

Ich fürchte, das wird so nix. Da muß das ganze Komzept nochmals 
überdacht, oder auf eine andere Plattform umgestellt werden.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller wrote:

>> Der Witz soll wohl auch eher eine nichtlineare Abweichung sein...
> Aber doch nicht so, dass jedem benachbarten AD-Wert ein /ganz anderer/
> Ausgangswert zugeordnet werden muß? So extrem nichtlinear kann doch kein
> Sensor sein. Wie wäre es mit einer Tabelle mit z.B. 200 Werten und einer
> Geradeninterpolation dazwischen?

Andere Möglichkeit:
zwei benachbarte Werte werden sich ja normalerweise nicht grossartig 
unterscheiden. Anstatt also jeden Wert als uint16_t zu speichern, würde 
es ja wahrscheinlich auch ausreichen nur jeden, sagen wir mal 10-ten 
Wert, als 16 Bit Wert zu speichern, und für alle Werte dazwischen nur 
jeweils eine, sagen wir mal 8-Bit, Differenz zum Vorgängerwert.

Anstatt

    100
    101
    103
    103
    104

als jeweils 16 Bit Wert abzulegen, könnte es ja auch genügen

    100     ( 16 Bit Wert )
     +1     ( 8 Bit Differenz )
     +2     ( 8 Bit Differenz )
     +0     ( 8 Bit Differenz )
     +1     ( 8 Bit Differenz )

zu speichern. Anstelle von 5 + 2Byte = 10 Bytes würden in diesem 
Beispiel nur 6 Bytes verbraucht werden.

Früher hat man solche Sachen ins Extrem getrieben um Audio-Samples mit 
den bescheidenen Mitteln die man hatte abspeichern zu können. Alle x 
Bytes wurde der Audiopegel mit den vollen 8-Bit abgelegt. Dazwischen hat 
man nur vermerkt, ob der Pegel steigt oder fällt, hat also für jeden 
dazwischenliegenden Sample nur 1 Bit benutzt. Nannte sich 
Delta-Modulation.

Wege um Speicher zu sparen gibt es viele. Hängt immer von der konkreten 
Aufgabenstellung ab und welche Abweichungen man sich leisten kann.

Ausserdem kann ich mir beim besten Willen nicht vorstellen, dass jemand 
einen Sensor linearisiert, indem er für jeden möglichen Messwert einen 
Ausgabewert vorgibt.
In meiner Sturm und Drang Zeit wollte ich so auch mal die Ausgabe eines 
Farbdruckers linearisieren, der einen üblen Farbstich hatte. Habs aber 
schnell wieder aufgegeben. Solche Umsetzungstabellen sehen in der 
Theorie gut aus, sind aber in der Praxis so gut wie nicht zu gebrauchen, 
solange es keine Formel gibt, um die Werte zu errechnen. Wenn ich aber 
eine Formel habe, dann kann ich die auch gleich benutzen anstatt einer 
Tabelle.

von Gerhard L. (Gast)


Lesenswert?

>effektiv nicht nur 9 Bit

Ähm, ich mach das jetzt seit einem Tag, hab gestern die Unterlagen 
bekommen und bin dabei mich einzulesen.
Ich hatte vorher weder mit C, AVR´s oder groß mit Elektronik zutuen, 
mein Gebiet ist Labview und nix anderes.
Also was sind effektiv 9 Bit?

>einer Geradeninterpolation dazwischen?

Genau dies macht mein PC-Programm, so war meine eigentliche Aufgabe, 
warum ich nun noch gezwungen werde das hier zu machen weiß ich auch 
nicht.
Ich denke aber ich würde mich mehr als schwer tun in der Zeit die mir 
gegeben wurde soweit C zu lernen um auf dem AVR ne Interpolation 
hinzubekommen.

>geh doch mal zum großen Denker

ich denke, genau dieser hat sich das einfallen lassen damit man mir 
nicht grundlos Kündigen brauch...

>Ich fürchte, das wird so nix.

Denke ich auch aber ich hab bald viel Zeit um mich mit sowas zu 
beschäftigen.

Gruß Gerhard

von Karl H. (kbuchegg)


Lesenswert?

Gerhard L. wrote:

>>einer Geradeninterpolation dazwischen?
>
> Genau dies macht mein PC-Programm, so war meine eigentliche Aufgabe,
> warum ich nun noch gezwungen werde das hier zu machen weiß ich auch
> nicht.
> Ich denke aber ich würde mich mehr als schwer tun in der Zeit die mir
> gegeben wurde soweit C zu lernen um auf dem AVR ne Interpolation
> hinzubekommen.

Ehrlich?
Du hast Schwierigkeiten

   Ausgangswert = k * Eingangswert + d;

zu schreiben, und das k bzw. d vorher aus einer Tabelle abhängig vom 
Eingangswert rauszusuchen (ne simple Umrechnung für den Index)

von Oliver (Gast)


Lesenswert?

>Ich denke aber ich würde mich mehr als schwer tun in der Zeit die mir
>gegeben wurde soweit C zu lernen um auf dem AVR ne Interpolation
>hinzubekommen.

Aber einen AVR willst du mit externem EEPROM, SRAM incl. Ansteuerung 
versehen? Vergiß es einfach. Das klingt jetzt vielleicht etwas hart, 
aber ohne ernsthafte Programmierkenntnisse geht das gar nicht.

> warum ich nun noch gezwungen werde das hier zu machen weiß ich auch
> nicht.

Das solltest du mal als erstes klären. Kunden "wollen" machmal seltsame 
Dinge, und meinen doch etwas ganz anderes.

Oliver

von Gerhard L. (Gast)


Lesenswert?

>Ehrlich?

 Ja ehrlich denn bis vor ca. 24h hab ich noch nie länger als eine Minute 
C-Code gesehen.
Aber immerhin hab ich es in dieser Zeit bereits geschaft ein 20x4 
Display zum Anzeigen zu überreden, man könnte also fast behaupten das 
ich recht schnell lernen kann.

>externem EEPROM, SRAM incl. Ansteuerung versehen?

EEPROM seh ich jetzt garnicht mal so kritisch, mit externen SRAM fang 
ich nicht an das würde ich Zeitlich garnicht schaffen.

Mir bleibt momentan nur, meinen Speicherbedarf soweit zu reduzieren um 
es in nen Mega32 und nen 24c512 unterzubringen.

Ich denke mit Interpolation könnte das wohl klappen, am Ende merkts wohl 
nichtmal jemand wenn der AVR nur linear interpoliert und nicht als 
Spline wie mein PC-Programm.

von Karl H. (kbuchegg)


Lesenswert?

Gerhard L. wrote:
>>effektiv nicht nur 9 Bit
>
> Ähm, ich mach das jetzt seit einem Tag, hab gestern die Unterlagen
> bekommen und bin dabei mich einzulesen.
> Ich hatte vorher weder mit C, AVR´s oder groß mit Elektronik zutuen,
> mein Gebiet ist Labview und nix anderes.
> Also was sind effektiv 9 Bit?

Dein ADC liefert zwar 10 Bit.
Aber das kleinste Bit wird im Normalfall wie wild zappeln, so dass du 
nur die 9 höherwertigen Bits (wenn überhaupt) gebrauchen kannst.
Vielleicht kennst du den Spruch: Wer misst, misst viel Mist.

von Karl H. (kbuchegg)


Lesenswert?

Gerhard L. wrote:

> EEPROM seh ich jetzt garnicht mal so kritisch,

Prusst.

Mist. Wer wischt jetzt die Kaffeeflecken von meinem Monitor?

von Karl H. (kbuchegg)


Lesenswert?

Was sind deine Vorgaben?
Wie schnell muss den die Linearisierung sein?

> nicht als Spline wie mein PC-Programm.

AVR sind zwar nicht die schnellsten, wenns ums Floating Point rechnen 
geht. Aber vielleicht reichts ja auch, wenn du den AVR den Spline online 
rechnen lässt.

von Gerhard L. (Gast)


Lesenswert?

>Wie schnell muss den die Linearisierung sein?

Min. 50 mal je Sekunde muß aktualisiert werden können.

Ich denke ich werde das ganze einfach reduzieren auf 8Bit sowohl ADC DAC 
als auch die ganze Rechnerei.
Dazu werd ich das PC-Programm anpassen so das es zwar weiter so 
interpoliert aber am Ende nur 8bit ausgibt.
Damit sollten die meisten Probleme dahin sein, bleibt jedoch noch die 
Geschichte mit dem einspielen per RS232 auf den 24c512.
Oder hab ich noch was übersehen?

von Karl H. (kbuchegg)


Lesenswert?

Gerhard L. wrote:
>>Wie schnell muss den die Linearisierung sein?
>
> Min. 50 mal je Sekunde muß aktualisiert werden können.

Das ist doch für den Mega eine halbe Ewigkeit.

-> Ich würde die Spline-Linearisierung online rechnen.
Wenns dann noch hakt auf Fixpunktarithmetik ausweichen.

von Karl H. (kbuchegg)


Lesenswert?

> bleibt jedoch noch die
> Geschichte mit dem einspielen per RS232 auf den 24c512.

Und du bist sicher, dass du dir das antun willst?
Das dürfte um einiges schwieriger sein, als die Berechnung online zu 
machen. Du musst ein sicheres Protokoll erfinden, musst zwischendurch in 
der Übertragung immer wieder Pausen einlegen, damit der EEPROM 
Schreibcode mit dem Schreiben nachkommt, nach Möglichkeit brauchst du 
eine Übertragungs-Fehler Erkennung incl. Neuanforderung eines 
Datenpakets, etc.

von Gerhard L. (Gast)


Lesenswert?

>Ich würde die Spline-Linearisierung online rechnen.
>Wenns dann noch hakt auf Fixpunktarithmetik ausweichen.

Ich bin nicht der große Mathematiker deshalb würde ich darauf generell 
gern verzichten.

>Und du bist sicher, dass du dir das antun willst?

Genau mit sowas beschäftige ich mich seit 5 Jahren allerdings eben aus 
der anderen Richtung (PC)

Ich hab dann jetzt mal noch ein Problem wo ich grad nicht durchseh 
warums nicht will.

Meine Arrays werden scheinbar korrekt im EEPROM abgelegt, wenn ich nun 
aber mit untenstehendem Code versuche mein Element auszugeben, schreibt 
er mir immer nur 255 als Wert ins Display.

Ich weiß das der Code nicht toll ist was will man nach einem Tag auch 
erwarten...


1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <util/delay.h>
5
#include "lcd-routines.h"
6
#include <avr/eeprom.h>
7
8
#ifndef EEMEM
9
#define EEMEM __attribute__ ((section (".eeprom")))
10
#endif
11
12
uint8_t varaya[256] EEMEM= {
13
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
14
};
15
uint8_t varayb[256] EEMEM= {
16
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
17
};
18
uint8_t varayc[256] EEMEM= {
19
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
20
};
21
22
uint8_t varay[256];
23
24
int main (void) {
25
26
uint8_t bPORTA; /* Taster; Variable anlegen für Port*/
27
bPORTA = PINA; /* Taster; Port wird Register zugewiesen*/
28
29
DDRD  = 0xff; /* LED; Port auf Ausgang setzen */
30
PORTD = 0x00; /* LED; Alle Ausgänge 0 */
31
32
uint8_t TASZ; /* Tastenanschlag-Zähler */
33
TASZ = 0; /* Tastenanschlagzähler auf 0 */
34
35
uint8_t x; /* Schleifenzähler */
36
37
eeprom_read_block(varay,varaya,256); /* vom EEPROM ein Array in SRAM */
38
39
/* Display init  */
40
lcd_init();
41
lcd_home();
42
lcd_clear();
43
44
while(1){
45
46
   if ( PINA & (1<<PINA0) ) /* Register für Portpin 0 lesen und TASZ hochzählen*/
47
    {
48
    TASZ = TASZ +1;
49
    PORTD = 0x0a;
50
    _delay_ms(500);
51
    PORTD = 0x00;
52
    lcd_clear();
53
    char BufferV[20];
54
    itoa (varay[TASZ],BufferV, 10); /* Wert aus Array lesen und formatieren */
55
    lcd_string(BufferV); /* Wert auf Display schreiben */
56
    }
57
58
  if ( PINA & (1<<PINA2) ) /* reset */
59
    {
60
    TASZ = 0;
61
    PORTD = 0x0f;
62
    _delay_ms(500);
63
    PORTD = 0x00;
64
    }
65
66
67
  if ( PINA & (1<<PINA1) ) /* Zähler auf LED ausgeben */
68
    {
69
    for ( x=0; x<TASZ; x=x+1 )
70
    {PORTD = 0x03;
71
    _delay_ms(500);
72
    PORTD = 0x00;
73
    _delay_ms(500);
74
    } 
75
  }
76
77
}
78
return 0;
79
}

von hans (Gast)


Lesenswert?

Hallo Gerhard,

da die Tabellen am Stück geschrieben werden können ist evtl. ein
Data-Flash besser. Da kannst du ganze Seiten mit 1024 Byte auf einen
Rutsch zum Speicher schieben und dann speichern lassen wärend du schon 
die
2 Schreibseite füllst. Für die AT45xxx gibt es hier im Forum und
von Atmel genug Beispiele und Software.

Beim Prozessor geht auch ein Mega644, Gehäuse wie der Mega32 jedoch
4 KByte Ram.

Da in der Tabelle jedoch der AD-Wert die Tabellenposition ist,
brauchst du fast kein Ram. Lesezugriffe auf Flash oder EEProm
gehen ohne Wartezeit, 50/Sekunde ist da lächerlich.
Nur das Schreiben braucht Zeit.

gruß hans

von Gerhard L. (Gast)


Lesenswert?

hmm klingt auch gut, schau ich mir gleich noch an

von Gerhard L. (Gast)


Lesenswert?

Fällt noch jemandem zu dem Code was ein?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Meine Arrays werden scheinbar korrekt im EEPROM abgelegt...
Wie hast du das kontrolliert?
Programmierst du die Daten auch tatsächlich ins EEPROM rein?

von Gerhard L. (Gast)


Lesenswert?

Ich geh davon aus da irgendetwas in der Größenordnung in die .epp 
geschrieben wird welche ich dann per Pony in den EEPROM schreiben lasse.
Lieg ich da falsch?

von Gerhard L. (Gast)


Lesenswert?

Mit einem Array aus 22 Werten geht es scheibar, übersehe ich hier 
irgendeine Größenbeschränkung?

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.