putint funktioniert auf den klassischen Controllern genau so, wie es
soll. Getestete Conroller waren ATmega328p, ATMega168, ATtiny44 und
ATtiny2313.
Binde ich genau denselben Code nun in der tinyAVR 0/1 series ein
(getestete Controller ATtiny214 und ATtiny1604), dann gibt mir putint
nur Zahlen von 0..9 korrekt aus, bei Werten oberhalb von 10 "spinnt" er
herum zählt einfach die Ascii-Zeichen weiter, die nach Ascii-9 kommen.
Für 10 also den Doppelpunkt, für 11 den Strichpunkt etc.
Wo liegt hier der Hund begraben?
Ich gehe schlicht davon aus, dass in meinem putint etwas "unsauber" ist,
aber ich finde das nicht !
By the way:
die aufgerufene Funktion my_putchar(uint8_ch) funktioniert problemlos,
einzelne Aufrufe in der Art:
Ralph S. schrieb:> Wo liegt hier der Hund begraben?>> Ich gehe schlicht davon aus, dass in meinem putint etwas "unsauber" ist,> aber ich finde das nicht !
MPLABX und ein PICKIT4 oder SNAP zu nehmen und den Code im Singlestep
durchzugehen ist zuviel verlangt?
fchk
Frank K. schrieb:> MPLABX und ein PICKIT4 oder SNAP zu nehmen und den Code im Singlestep> durchzugehen ist zuviel verlangt?
Mir ist der Aufwand für die kleinen tinyAVR series 0/1 zu groß und ich
werde mir hierfür kein PicKit4 zulegen (ich habe nur einen alten PicKit2
für die PIC Controller). MPLAB ist mir, wie ich in einem anderen Thread
schon geschrieben hatte, zu groß und zu "schwerfällig", vor allem, wenn
man sowieso nach guter alter (veralteter) Sitte sich seine Makefiles
selbst zusammen bastelt und das ganze damit auch noch komplett auf der
Konsole lauffähig sein soll.
Im "Normalfall" bin ich eher mit STM32 unterwegs, hier dann mit einen
originalen ST-Link und Debugger.
Von daher erübrigt sich die Frage nach dem zu viel verlangt sein.
Außerdem hoch verrückt: Nach der Installation von avr-gcc 12.2.0 macht
putint das, was es soll. Also laß ich diesen Compiler installiert.
-------------------------------------------------
Peter D. schrieb:> Hier mal die Diskussion zu dem ATTiny26 Bug:> Beitrag "Problem mit ltoa"
Danke Peda (und das Danke meine ich auch uneingeschränkt als Danke).
ltoa habe ich nicht ausprobiert, aber itoa. Witzigerweise funktioniert
das mit der Version 7.3.0 !!!
Aber das Problem hat sich mit der Version 12.2.0 jetzt eh erledigt. Ich
hatte noch nie einen wirklich aktuellen avr-gcc installiert gehabt, weil
ich mir bisher damit dann immer andere Probleme eingefangen hatte.
Dank Peter mit dem Hinweis auf:
Peter D. schrieb:> Beitrag "Problem mit ltoa"
habe ich mir dort den Thread und dem Problem mit der Adressierung sehr
aufmerksam durchgelesen.
Danach habe ich meinen eigenen Code genauer angesehen (und natürlich
wieder verstanden was ich da gemacht habe, auch wenn es nicht
kommentiert ist - ich sollte mehr sprechende Variablennamen verwenden).
Nimmt man das Array zz[] mit den Zehnerpotenzen aus der Funktion heraus
und macht dieses Array global, funktioniert putint wie gewünscht auch
unter avr-gcc 7.3 .
Allerdings darf das Array nicht als static definiert werden, weil auch
dann dieselbe Fehlfunktion auftritt.
Deshalb hier der funktionierende Code:
Ralph S. schrieb:> Nimmt man das Array zz[] mit den Zehnerpotenzen aus der Funktion heraus> und macht dieses Array global, funktioniert putint wie gewünscht auch> unter avr-gcc 7.3 .
Nun, dann wird es im Initcode vor Main geladen.
Innerhalb einer Funktion wird es aber erst direkt beim Eintritt geladen,
d.h bei jedem Eintritt neu.
Man könnte es auch per PROGMEM in den Flash legen, spart dann SRAM ein.
Ein Fehler im Chip ist weiterhin nicht auszuschließen, d.h. eine
Instruktion hat einen Seiteneffekt. Der avr-gcc 12.2.0 könnte diesen
Befehl anders realisiert haben, so daß der Bug sich nicht auswirkt.
Ein Bug im avr-gcc 7.3 erscheint mir unwahrscheinlich, da ja ATmega168
usw. gehen.
Probier doch mal den Code zu minimieren und schau Dir dann mal an was
der Compiler daraus macht. So als Komplettwust wird das niemand
verstehen können.
So als Skizze würde ich das wie folgt machen:
void print_ziffer(int *zahl, const int stelle, int *print_null)
{
int cnt=0;
while (zahl>=stelle) {
cnt=cnt+1;
}
if ((cnt!=0) || (*print_null!=0)) {
my_putchar(cnt+'0');
*print_null=1;
}
}
Das rufst Du dann so auf:
void print_zahl(const int zahl_)
{
int zahl=zahl_;
int print_null=0; //keine führenden Nullen
print_ziffer(&zahl, 10000, &print_null);
print_ziffer(&zahl, 1000, &print_null);
print_null=1; //Ab der "einer"-Stelle führende Nullen
print_ziffer(&zahl, 100, &print_null);
my_putchar('.');
print_ziffer(&zahl, 10, &print_null);
print_ziffer(&zahl, 1, &print_null);
}
Damit hast du das Problem in kleinere Teilprobleme zerlegt und kannst
sehen wo was schief läuft. Nebenbei brauchst Du da auch kein LPM.
Funktionsaufrufe sind auch was, dass der Compiler gut auflösen kann.
Peter D. schrieb:> Nun, dann wird es im Initcode vor Main geladen.> Innerhalb einer Funktion wird es aber erst direkt beim Eintritt geladen,> d.h bei jedem Eintritt neu.
... das war der Sinn, weshalb ich das global gemacht habe.
Peter D. schrieb:> Man könnte es auch per PROGMEM in den Flash legen, spart dann SRAM ein.
Hm, ob sich das rentiert? Das Array belegt im SRAM 8 Byte.
Christian B. schrieb:> Christian B. schrieb:>> void print_ziffer(int *zahl, const int stelle, int *print_null)> ...>> cnt=cnt+1;> *zahl=*zahl-stelle; //Fehlte vorher.>> }
ich werde deine Vorschläge ausprobieren und sehen, wie groß der Code
wird. In einem ATtiny214 hat man nur 2 kByte Speicher, von daher bin ich
da mit der Codegröße extrem geizig.
In jedem Fall werde ich die Variablennamen ändern, damit man die
Funktion besser verstehen kann.
Christian B. schrieb:> Die Option -Os ist dann Dein Freund, die optimiert das auf Größe, und> Compiler sind heute sehr gut darin Dinge zu optimieren.
Die Option -Os ist bei mir standardmäßig gesetzt!
Ralph S. schrieb:> Mir ist der Aufwand für die kleinen tinyAVR series 0/1 zu groß und ich> werde mir hierfür kein PicKit4 zulegen (ich habe nur einen alten PicKit2> für die PIC Controller). MPLAB ist mir, wie ich in einem anderen Thread> schon geschrieben hatte, zu groß und zu "schwerfällig", vor allem, wenn> man sowieso nach guter alter (veralteter) Sitte sich seine Makefiles> selbst zusammen bastelt und das ganze damit auch noch komplett auf der> Konsole lauffähig sein soll.
[...]
> Von daher erübrigt sich die Frage nach dem zu viel verlangt sein.
Professionell ist anders. Aber ok, die Chance, wirklich die Stelle zu
finden, wo das Problem genau ist, hast Du Dir damit genommen. Ist dann
wohl auch nicht so wichtig.
fchk
Frank K. schrieb:> Professionell ist anders. Aber ok, die Chance, wirklich die Stelle zu> finden, wo das Problem genau ist, hast Du Dir damit genommen. Ist dann> wohl auch nicht so wichtig.
Na ja, ich habe die Stelle ja auch so gefunden !
Zugegeben: Mit Debugger ist vieles einfacher, auf STM32 bin ich damit
auch unterwegs. Wirklich immer muß das aber nicht sein.
Außerdem: Ich bin kein professioneller Softwareentwickler