Ich versuche, einen PIC10f202 mit dem XC8-Compiler zu programmieren, um den Wert eines Timers mit einer Variablen zu vergleichen, die eine Funktion einer Nachschlagetabelle sein wird. Hier ist ein Beispielcode:
#include <xc.h>
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config WDTE = OFF
Init(void){
TRIS=0;
GPIO=0;
TMR0 = 0;
OPTION = 0b00000011;
}
const unsigned char LUT[250] = {
0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000010, 0b00000010,
0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000011,
0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000100,
0b00000100, 0b00000100, 0b00000101, 0b00000101, 0b00000101,
0b00000110, 0b00000110, 0b00000110, 0b00000111, 0b00000111,
0b00001000, 0b00001000, 0b00001001, 0b00001001, 0b00001010,
0b00001010, 0b00001011, 0b00001100, 0b00001100, 0b00001101,
0b00001101, 0b00001110, 0b00001111, 0b00010000, 0b00010000,
0b00010001, 0b00010010, 0b00010011, 0b00010011, 0b00010100,
0b00010101, 0b00010110, 0b00010111, 0b00011000, 0b00011001,
0b00011010, 0b00011011, 0b00011100, 0b00011101, 0b00011110,
0b00011111, 0b00100000, 0b00100001, 0b00100010, 0b00100100,
0b00100101, 0b00100110, 0b00100111, 0b00101001, 0b00101010,
0b00101011, 0b00101100, 0b00101110, 0b00101111, 0b00110000,
0b00110010, 0b00110011, 0b00110101, 0b00110110, 0b00111000,
0b00111001, 0b00111011, 0b00111100, 0b00111110, 0b00111111,
0b01000001, 0b01000010, 0b01000100, 0b01000110, 0b01000111,
0b01001001, 0b01001011, 0b01001100, 0b01001110, 0b01010000,
0b01010001, 0b01010011, 0b01010101, 0b01010111, 0b01011000,
0b01011010, 0b01011100, 0b01011110, 0b01100000, 0b01100001,
0b01100011, 0b01100101, 0b01100111, 0b01101001, 0b01101010,
0b01101100, 0b01101110, 0b01110000, 0b01110010, 0b01110100,
0b01110110, 0b01111000, 0b01111001, 0b01111011, 0b01111101,
0b01111111, 0b10000001, 0b10000011, 0b10000101, 0b10000111,
0b10001000, 0b10001010, 0b10001100, 0b10001110, 0b10010000,
0b10010010, 0b10010100, 0b10010110, 0b10010111, 0b10011001,
0b10011011, 0b10011101, 0b10011111, 0b10100000, 0b10100010,
0b10100100, 0b10100110, 0b10101000, 0b10101001, 0b10101011,
0b10101101, 0b10101111, 0b10110000, 0b10110010, 0b10110100,
0b10110101, 0b10110111, 0b10111001, 0b10111010, 0b10111100,
0b10111110, 0b10111111, 0b11000001, 0b11000010, 0b11000100,
0b11000101, 0b11000111, 0b11001000, 0b11001010, 0b11001011,
0b11001101, 0b11001110, 0b11010000, 0b11010001, 0b11010010,
0b11010100, 0b11010101, 0b11010110, 0b11010111, 0b11011001,
0b11011010, 0b11011011, 0b11011100, 0b11011110, 0b11011111,
0b11100000, 0b11100001, 0b11100010, 0b11100011, 0b11100100,
0b11100101, 0b11100110, 0b11100111, 0b11101000, 0b11101001,
0b11101010, 0b11101011, 0b11101100, 0b11101101, 0b11101101,
0b11101110, 0b11101111, 0b11110000, 0b11110000, 0b11110001,
0b11110010, 0b11110011, 0b11110011, 0b11110100, 0b11110100,
0b11110101, 0b11110110, 0b11110110, 0b11110111, 0b11110111,
0b11111000, 0b11111000, 0b11111001, 0b11111001, 0b11111010,
0b11111010, 0b11111010, 0b11111011, 0b11111011, 0b11111011,
0b11111100, 0b11111100, 0b11111100, 0b11111101, 0b11111101,
0b11111101, 0b11111101, 0b11111101, 0b11111110, 0b11111110,
0b11111110, 0b11111110, 0b11111110, 0b11111110, 0b11111111};
unsigned char cnt1=0;
void main(){
Init();
for(;;){
cnt1 = LUT[100];
while(TMR0 > 100){
GPIO=0b00000001;
}
GPIO=0b00000000;
}
}
Die Nachschlagetabelle hat 250 Zeichen, da dies die maximale Größe ist, die vom Compiler zugelassen wurde, bevor er mir den Fehler „Can’t find x0FF words (x0ff withtotal) for psect „stringtext1“ in class „Entry““ ausgab. Der Code lässt sich gut kompilieren, wobei MPLAB X 55 % Flash-Speichernutzung und 0 % RAM-Nutzung angibt. Wenn ich die Bedingung "while" so ändere:
while(TMR0 > cnt1)
Der Compiler gibt mir wieder einen ähnlichen Fehler: "Kann x0FA-Wörter (x0fa withtotal) für psect "stringtext1" in der Klasse "Entry" nicht finden". Ich verstehe, dass der Compiler nicht genug Speicher finden kann, um den Code zu schreiben, aber ich sehe nicht, dass 45 % freier Speicherplatz für diese Aufgabe nicht ausreichen. Warum kann ich auch kein Array mit 255 Elementen erstellen? Der PIC10f202 hat 512 Worte Speicher, das sollte möglich sein.
Warum gibt der Compiler diese Fehler aus?
Dies ist ein perfektes Beispiel dafür, wie die blinde Verwendung eines Compilers auf einem kleinen System mit begrenzten Ressourcen, ohne die Einschränkungen der Maschine wirklich zu verstehen, Sie in Schwierigkeiten bringen wird.
Sehen Sie sich zunächst an, wie eine Tabelle mit Konstanten im Programmspeicher implementiert werden müsste. Lesen Sie das Datenblatt. Nein, wirklich, geh und lies es. Wie müsste das auch gemacht werden? Sehen Sie eine Möglichkeit, den Programmspeicher zu lesen, wie einen Tabellenlesemechanismus, den einige andere PICs haben? Die einzige Möglichkeit, Konstanten aus dem Programmspeicher zu bekommen, sind Anweisungen, die Literale enthalten. Wie implementiert man damit eine Tabelle? Nein, eigentlich denkendarüber, bevor Sie weiterlesen. Werfen Sie einen Blick auf die Liste der Anweisungen. Die einzige Möglichkeit, eine Nachschlagetabelle zu implementieren, ist die RETLW-Anweisung. Das bedeutet, dass Sie im Grunde einen Subroutinenaufruf an den Tabelleneintrag ausführen, der den Wert für diesen Eintrag in W zurückgibt. Sehen Sie sich nun den Subroutinenaufrufmechanismus an. Nachdem Sie das gelesen haben, was Sie vor dem Schreiben der ersten Codezeile haben sollten, sollte es offensichtlich sein, warum Sie möglicherweise nicht mehr als 256 Tabelleneinträge haben können, wobei einige dieser möglichen Tabelleneinträge für Code verwendet werden müssen.
Zeigen Sie, dass Sie das Datenblatt gelesen haben und ich auf weitere Details eingehen kann.
lp: call retAddr
/ retAddr: btfsc temp,7
/ goto gotValue
/ decfsz temp
/ goto lp
, um alle Stack-Slots auf bekannte retAddr zu zwingen. Das Setzen von Bit 7 von temp
und das Schreiben in PCL würde dann einen Wert in W lesen und zu springen gotValue
. Nicht das, was ich von einem Compiler erwarten würde, aber möglich.Da die Zahlen in der LUT nicht eindeutig sind, die Zahlen monoton ansteigen und die Änderungen tatsächlich ziemlich spärlich aussehen, ist es möglich, eine kleine Funktion zu schreiben, um die LUT zu ersetzen?
zB y= x>=1 + x>=23 + .....
Ich überlasse es Ihnen, herauszufinden, wie viel Speicher, wenn überhaupt, auf diese Weise eingespart werden kann.
Es gibt vielleicht andere Algs, die Sparse-Techniken verwenden, die ebenfalls hilfreich sein könnten, vielleicht das Speichern der eindeutigen unterschiedlichen Werte und der Werte von x, wo die Übergänge auftreten.
PIC10f202 verfügt laut dieser Zusammenfassung von Microchip über 24 Byte RAM und 750 Byte Flash . Wenn es möglich ist, eine Tabelle im Flash zu behalten und auszuführen, können Sie möglicherweise ein kleines Programm unter Verwendung des verbleibenden Programmspeichers anpassen. Aber ich sehe in Ihrer Tabellendeklaration nichts, was wie eine Anweisung zur Verwendung von Flash aussieht, und die Tabelle ist jetzt etwa 12-mal so groß wie der verfügbare RAM, selbst wenn keine anderen Anforderungen an sie gestellt wurden (z. B. Stack ...). .
const
. In einigen C-Compilern für PIC wird die Konstante dadurch in Flash eingefügt. Aber ich weiß nicht, ob dies für XC8 gilt, weil ich es nie benutzt habe.Ich habe nicht alle Einträge in der Tabelle überprüft, aber es scheint, dass sich die Einträge nur um 1 ändern (nach mehreren Einträgen hintereinander, die gleich sind). Ich glaube, Sie könnten stattdessen die Tabelle wie folgt neu organisieren, wobei jede Zahl der Punkt ist, an dem der Wert in der alten Tabelle erhöht wird.
const unsigned char LUT[nn] = {
0, 23, 29, 34, ...
Der Index in der neuen Tabelle ist der Wert, mit dem Sie vorher abgeglichen hätten (jetzt ist es eine Tabellensuche), und der von der Tabelle zurückgegebene Wert ist derselbe wie der Index, der in der alten Tabelle gewesen wäre.
Sollte viel schneller sein, und der Tisch wird viel kürzer sein.
juli059
Benutzer3624