Mehr Speicherplatz im Controller zuweisen

Chip: PIC18f26j50
Compiler: C18

Mein Ziel ist es, über Strukturen Werte in einer Tabelle im RAM- Speicher abzulegen und die recht großen Werte einzuspeisen.

#include <p18F46J53.h>

 struct table
    { 
      float temp;
      float humidity;
      float pressure;

    }entry[300];

Dies ist mein Beispielcode und ich muss solche Mitglieder im Speicher des Controllers speichern. Dies dient dem Zweck, die Umgebungsdaten der Atmosphäre zu überwachen. Und später diese Daten in EEPROM ablegen.

Aber ich habe Probleme beim Erstellen des Codes, da es den folgenden Fehler gibt:

Fehler - Abschnitt '.udata_main.o' passt nicht in den Abschnitt. Abschnitt „.udata_main.o“ Länge=0x000013ec

Ich habe versucht, Google nach der Behebung dieses udata-Fehlers zu durchsuchen, und bin bei How to Create Objects Larger than 256 Bytes with Microchip's MPLAB C18 gelandet .

Aber dies zeigt, wie jede Variable gespeichert wird. Wie kann ich structs in C18 speichern? Oder ist es unmöglich?

Ich werde versuchen, genauer zu sein. Ich habe diese Methode gefunden, um Daten mit mehr als 255 Byte zu speichern.

#pragma udata large_udata
unsigned char big_buff1[300];
unsigned char big_buff2[350];
#pragma udata

Wie kann ich größere Strukturen speichern, sodass ich nur 3000 Bytes für die Tabellenvorbereitung benötige?

Ich würde es vorziehen zu verwenden, aber ich kann mich mit / floatbegnügen .intchar

Ich hoffe, das macht die Sache klarer.

Antworten (2)

BEARBEITEN: Es gibt zwei Probleme - das Strukturarray ist zu groß für den Speicher, und der Compiler kann keine Variablen erstellen, die größer als 256 Byte sind

Problem 1: Struktur zu groß für RAM

Der von Ihnen verwendete Chip hat eine RAM-Größe von 3776 Bytes (1) und der Fehler besagt, dass er 5100 Bytes benötigt.

Sie benötigen entweder einen neuen Chip mit mehr RAM oder Sie müssen die Größe Ihrer Tabelle reduzieren. Ich schlage vor, Ihre Werte als vorzeichenlose Ganzzahlen (2 Bytes) zu speichern. Wenn Sie die Nachkommastellen benötigen, multiplizieren Sie einfach mit 10 hoch der Anzahl der Stellen. ZB 3.157 wird 3157.

Warum brauchen Sie 300 Werte? Vielleicht können Sie öfter ins EEPROM speichern und diese Zahl reduzieren. Wenn Sie nur eine große Anzahl zu mitteln haben, sollten Sie stattdessen eine Akkumulatorvariable hinzufügen.

Z.B

TempAccum += temp;

Dann nach 300 Lesungen

TempTotal = TempAccum / 300;
TempAccum = 0;

Problem 2: Keine Variablen größer als 256 Bytes:

Eine Lösung wurde im Link in der Frage gepostet, aber das war für Variablen. Verwenden Sie anstelle einer Struktur einzelne Variablen:

float temp[300];
float humidity[300];
float pressure[300];

Um auf die Variablen (laut Link) zuzugreifen, müssen Sie Zeiger verwenden. z.B

float *tempPtr;
tempPtr = temp;
tempPtr[100] = some_value;
Nun, ich habe Probleme, mehr als 255 Bytes unterzubringen. Ich habe ein Beispiel gesehen, um so für Variablen zu speichern. Aber was kann ich tun, um mehr für Strukturen zu speichern?
Vielleicht möchten Sie den moderneren XC8-Compiler ausprobieren, der mit großen zusammenhängenden RAM-Zuweisungen besser umzugehen scheint als C18. Aber Sie müssen immer noch die Menge reduzieren, die Sie speichern möchten.
Was ist die Menge an RAM-Speicherplatz, die ich verwenden kann, um den Code richtig zu handhaben? Kann ich annehmen, dass ich die verfügbaren 2000 Bytes von 3,6 KB verwenden kann?

Float verwendet 4-Byte-Speicher. Wenn Sie sogar die Hälfte der genutzten Fläche können, wäre das viel besser für Sie. Vielleicht wird es in der Programmierung kompliziert, aber es löst Ihr Problem.

Denken wir an die Temperatur. In 1-Byte können Sie Werte zwischen -128 und 127 speichern. Wenn Sie mehr Details benötigen, können Sie 1 weiteres Byte für den Wert nach dem Punkt verwenden. Anstelle von Float können Sie also 2-Byte-Variablen für die Temperatur definieren, und sie wird halbiert. Wenn Sie die Bitebene verwenden, können Sie sie alle auch in 1 Byte unterbringen. Aber das kann es komplexer machen.

Wenn Sie die gleichen Überlegungen für die beiden anderen Felder anstellen, indem Sie über ihre möglichen Wertebereiche nachdenken, können Sie Ihr Problem meiner Meinung nach lösen.

--- EFFIZIENTE ART, SPEICHER ZU VERWENDEN --- (Dies wird später hinzugefügt)

Ihr Array ist zu groß, aber Sie verwenden es nur zum Speichern von Daten. Es erfolgt keine Berechnung, bis Sie seinen Inhalt in das EEPROM schreiben. Wenn dies der Fall ist, verkleinern Sie das Array. Sagen wir 50 Artikel.

entry[50]

Insgesamt würden Sie 300 benötigen. Sie können also einen Zähler erstellen, um zu wissen, an welchem ​​​​Teil dieser 300 Sie sich befinden.

int counter = 1;

Nachdem das Array entrymit 50 Elementen gefüllt ist, berechnen Sie den Offset-Wert für EEPROM.

int offset = 50 * counter;

Schreiben Sie dann den Inhalt dieses Arrays in das EEPROM, indem Sie mit dieser Offset-Adresse beginnen. Erhöhen Sie schließlich den Wert von Zähler um 1.counter += 1;

Da EEPROMs einen begrenzten Schreibzyklus haben, können Sie die Anzahl der Schreibvorgänge verringern, indem Sie diese 50 erhöhen, solange es in den Speicher passt.

Gibt es eine Möglichkeit, den Datentyp beizubehalten und mehr Speicherplatz zuzuweisen?: Oder ich sollte das Software-Design richtig überdenken.
Selbst wenn es sich um Char handelt, bräuchte ich immer noch einen großen Eintrag '300'. Das würde es immer noch schwierig machen.
Warum 300? Wenn Sie es uns mitteilen, können wir vielleicht kreative Möglichkeiten vorschlagen, dies zu umgehen.
OK. Ich muss Temperaturen, Feuchtigkeit und Druck für einen Tag speichern, das sind 300-mal am Tag [insgesamt s/w 24 Stunden]. Ich kann die Summe auf maximal 100 oder so reduzieren. Aber ich möchte wissen, was das ist beschränken, diese Struktur so zu verwenden, dass es zu keinen möglichen Konflikten oder Fehlern kommt.
Ich wollte Strukturen folgen, weil es eine beeindruckende Lösung zum Speichern von Tabellen ist. Ich hätte gerne Ihre Vorschläge dazu.
AFAIK, Sie können verschiedene Teile des EEPROM direkt schreiben. Sie können also die Anzahl der Elemente dieses Arrays reduzieren und eine Integer-Variable definieren, die als Zähler verwendet werden soll. Sobald dieses Array gefüllt ist, berechnen Sie den Offset-Wert unter Verwendung dieses Zählers und geben Sie das Array in das EEPROM aus, indem Sie bei dieser Offset-Adresse beginnen und den Zähler um eins erhöhen.