Array-Manipulation in MCC18

Angenommen, ich habe ein Array:

#define ARRAY_SIZE 576
#pragma udata DATA
float I_1[ARRAY_SIZE]; //My huge array
#pragma udata

Und dass ich so auf mein Array zugreife:

float compute()
{
    float *I_1_ptr = &I_1[0];
    //Somewhere in loop
    I_1_ptr[i] = IL_1 - IO_1 * (exp(Q * V_1/ (NS * N * K * temperature)) - 1.0) - V_1/Rsh;
    //Consider other variables constants.

    return (I_1_ptr[0] + I_1_ptr[1] + I_1_ptr[2] + I_1_ptr[3]);
}

Ich habe in den Suchergebnissen von Google gesehen, dass Microchip es vorzieht, dass man auf das Array zugreift, indem man mit Zeigern auf das erste Element zeigt.

Habe ich das richtig verstanden oder wie greife ich auf mein Array zu I_1?

Aus irgendeinem Grund funktioniert meine Berechnung auf meinem Array nicht und wenn ich durch Null dividiere, bekomme ich NaN.

Danke.

Etwas off-topic: Wo hast du gelesen, dass Pointer zu bevorzugen sind? Alle meine Suchen weisen darauf hin, dass sie vermieden werden sollten, aber soweit ich hier sehen kann, müssen sie aufgrund der Länge des Arrays verwendet werden oder imüssen ganzzahlig sein. Wenn ies sich nicht um eine Ganzzahl handelt, könnten Sie dort Probleme haben, da C18 Zeichen standardmäßig nicht in höhere Typen umwandelt.
Überprüfen Sie auch, ob das #define ARRAY_SIZE 576dort tatsächlich int verwendet. Möglicherweise müssen Sie ein Suffix hinzufügen, um es für alle Fälle int zu machen. Eine andere zu berücksichtigende Sache wäre, die Zeile, in der I_1_ptr berechnet wird, in mehrere aufzuteilen und jede mit dem Debugger zu überprüfen, um zu sehen, was genau passiert.
Wenn ich durch Null dividiere, erhalte ich NaN. Ja, das soll mit den von Ihnen verwendeten Schwimmern passieren.
@AndrejaKo, siehe Beispiele ( electro-tech-online.com/microcontrollers/… oder microchip.com/forums/m470067.aspx ). Ich habe den Link des Tutorials verloren, das ich gesehen habe. Sie verwenden Zeiger, um auf das Array zu verweisen.
@davidcary, das weiß ich. Ich versuche herauszufinden, warum in meinem Array keine Werte vorhanden sind.

Antworten (2)

Ahnung

Ich vermute das Problem liegt hier:

#define ARRAY_SIZE 576
float I_1[ARRAY_SIZE]; //My huge array

Da jedes Float 4 Bytes und jedes Double 8 Bytes verwendet, weist dies ein einzelnes Array zu, das über 2.000 Bytes RAM verwendet.

Der PIC18F4520 verfügt über 1 536 Byte RAM – nicht genug, um das gesamte Array zu speichern, geschweige denn dieses Array plus alle anderen Variablen, die in Ihrem Programm verwendet werden.

Also müssen Sie

  • Upgrade auf eine größere MCU mit mehr On-Chip-RAM, oder
  • irgendwie eine Art Off-Chip-RAM anbringen, oder
  • einen Weg finden, weniger RAM zu verwenden (vielleicht eine kleinere ARRAY_SIZE, oder vielleicht einen 16-Bit- oder 8-Bit-Datentyp zu verwenden, der weniger RAM pro Element im Array benötigt, oder vielleicht irgendwie einige dieser Daten in FLASH oder . ..)

oder eine Kombination der oben genannten.

andere Kommentare

Viele Lehrer der Programmiersprache C verwenden viel Zeit darauf, zu erklären, dass auf Arrays mit Hilfe von Zeigern zugegriffen werden kann . Ähnlich wie viele Chemielehrer viel Zeit damit verbringen, zu erklären, wie Moleküle aus einzelnen Atomen aufgebaut werden können . So wie viele Physiklehrer viel Zeit damit verbringen, zu erklären, wie Atome aus einzelnen Protonen und Neutronen aufgebaut werden können .

Während es auf diese Weise sehr lehrreich sein kann, ist es unnötig kompliziert und es gibt normalerweise einen einfacheren, besseren Weg, um das gewünschte Endergebnis zu erzielen. (Es gibt Fälle, in denen Sie Zeiger verwenden müssen, aber dies scheint keiner davon zu sein).

Eine wichtige Fähigkeit beim Debuggen besteht darin, ein Programm mit einem bekannten Fehler zu nehmen und den genauen Schritt herauszufinden, bei dem etwas schief zu laufen scheint.

Es hört sich so an, als ob Sie glauben, dass das Problem online liegt

I_1_ptr[i] = IL_1 - IO_1 * (exp(Q * V_1/ (NS * N * K * temperature)) - 1.0) - V_1/Rsh;

Diese Linie macht viele Dinge. Für einen Einzelschritt-Debugger ist es schwierig, genau herauszufinden, was in einer so komplizierten Zeile schief läuft. Wenn ich dieses Problem hätte, wäre meine erste Aktion, diese Zeile in eine Reihe kleinerer Zeilen aufzuteilen und dann diese kleineren, einfacheren Zeilen in Einzelschritten durchzugehen, um einzugrenzen, wo das Problem liegt. Vielleicht so etwas wie

float denominator;
float ratio;
float temp1;
float temp2;
//...
denominator = NS * N * K * temperature;
ratio = Q * V_1 / denominator;
temp_1 = exp(ratio) - 1.0;
temp_2 = IL_1 - IO_1 * temp_1 - V_1/Rsh;
I_1[i] = temp2; // normal array access -- pointers not necessary here.

und überprüfen Sie, ob Sie bei jedem Schritt die erwarteten Werte erhalten. Welcher Schritt führt zu unerwarteten Ergebnissen?

Eine wichtige Fähigkeit beim Debuggen besteht darin, ein großes Programm mit einem bekannten Fehler auf ein sehr kleines Programm zu reduzieren, das denselben Fehler aufweist.

Könnten Sie die Teile Ihres Programms vor und nach der Zeile, die etwas Unerwartetes tut, kürzen – vielleicht indem Sie Variablen vor dieser Zeile auf einen konstanten Wert setzen, anstatt eine lange Reihe von Berechnungen durchzuführen –, um uns eine sehr kurze, aber vollständige Beschreibung zu geben Programm, das das unerwartete Verhalten gibt?

I_1danke, das Problem ist, dass MPLAB "Restricted Memory" sagt, wenn ich mein Array "überwache ". Wenn ich nicht weiß, dass dort Daten vorhanden sind, kann ich sie jedoch nicht anzeigen.
Was passiert, wenn Sie "ARRAY_SIZE" auf eine kleine Zahl wie "4" reduzieren?
Ich hatte immer noch "Eingeschränktes Gedächtnis", ich glaube, das liegt daran, dass ich es eingeschaltet hatte udata. Das Entfernen aus udata hilft (bei kleiner Array-Größe, aber wir brauchen das große Array). Alternativ kann ich versuchen, die Lösung ohne Array neu zu konstruieren. :-)

"Eingeschränkter Speicher und Linker-Skripte"

Laut Leuten im Internet a b c verwendet der Compiler normalerweise, wenn Sie den ICD-Debugger verwenden, das spezielle 'i'-Linker-Skript, um sicherzustellen, dass der vom Debugger verwendete RAM nicht mit dem von Ihrem Programm verwendeten RAM kollidiert. Sie weisen den Compiler an, dies zu tun, indem Sie das Pulldown-Menü Debug/Release in der IDE-Symbolleiste auf "Debug" setzen; und dann den Chip umbauen und neu programmieren.

Wenn Sie es falsch eingestellt haben (auf „Release“) und dann versuchen zu debuggen, erhalten Sie eine „Restricted Memory“-Meldung.

"Hinweise"

ps: An anderer Stelle im Internet a b sehe ich jemanden, der die Behauptung wiederholt, dass der Array-Zugriff "durch Zeiger erfolgen muss", gefolgt von jemand anderem, der sagt, dass der normale Array-Zugriff mit dem MC C18-Compiler einwandfrei funktioniert - keine Notwendigkeit, mit Zeigern herumzuspielen .

Ich würde mich an den normalen Standard-C-Array-Zugriff halten, es sei denn, ich wäre gezwungen, einen Compiler zu verwenden, der eine Art Fehler hatte, der mich zwang, eine Problemumgehung zu verwenden. (Ich könnte mir vorstellen, dass eine frühe Version dieses Compilers einen solchen Fehler hatte, aber sie haben ihn vor Jahren behoben – diese alten Problemumgehungen sind jetzt veraltet und kontraproduktiv).

"große Puffer und Linker-Skripte"

"Erstellen Sie einen großen Puffer auf einem pic18f mit dem Microchip c18-Compiler" erwähnt das Bearbeiten eines Linker-Skripts.

Ist es möglich, dass Sie das Linker-Skript versehentlich so geändert haben, dass der von Ihrem Programm verwendete Arbeitsspeicher jetzt mit dem vom Debugger verwendeten Arbeitsspeicher in Konflikt steht?

Ist es möglich, dass Sie das Linker-Skript versehentlich so modifiziert haben, dass Ihr Programm versucht, "RAM"-Speicherorte zu verwenden, die physisch nicht auf Ihrem Chip vorhanden sind?