Hallo,
hab das Problem das ich über die USART eine ASCII Ziffernfolge (0-9)
bekomme.
Normalerweise liegen die im Bereich von 0 bis 100. Dieser Wert wird dann
entsprechen konvertiert und in einem unsigned char gespeichert.
Bis jetzt habe ich die Umwandlung so gelöst:
1
unsignedcharvalue=0,temp=0;
2
3
temp=UDR;
4
5
if(temp>='0'&&temp<='9')
6
{
7
value*=10;
8
value+=(temp-'0');
9
}
Jetzt gibt es aber einen Ausnahmefall in dem noch eine 4. Ziffer folgt.
Wie kann ich jetzt den Überlauf der Variablen bei der Multiplikation
erkennen?
Kann ich da in C einfach das Carry Flag im SREG abfragen?
Gibt es da eine elegantere bessere Methode? Soweit ich weiß ist eine
solche Abfrage in ANSI C nicht vorgesehen, oder?
Oder lieber die Multiplikation direkt als inline assembler ausführen und
da das Carry Flag abfragen?
Vielen Dank
Peter
Ich glaube zwar, dass die Lösung mit short trotzdem effizienter ist,
aber so sollte es auch gehen:
temp = UDR - '0';
if (temp <= 9)
{
if (value<=25)
{
value *= 10;
value += temp;
if (value>=temp)
{
//alles in Ordnung, kein Overflow
}
}
}
@ frettchen
Ja, da hast wohl recht. Währe aber auch eine Möglichkeit.
@simon
Ja, aber da braucht ich dann eine static Variable wegen ISR und die
belegt dann wieder zusätzlichen SRAM...
Würde das halt gern irgendwie über das Carry Flag lösen, hab halt nur
keine Ahnung wie sich das unter C verhält und ob das überhaupt geht...
Peter wrote:
> @simon> Ja, aber da braucht ich dann eine static Variable wegen ISR und die> belegt dann wieder zusätzlichen SRAM...
Machst du für 1 Byte SRAM jetzt so einen Aufstand?
@simon
Hast ja schon recht. Würde nicht wirklich was ausmachen.
Aber im Moment würde mich einfach nur interessieren wie bzw. ob das mit
dem Carry Flag geht. Finde währe eine recht elegante Lösung...
vergiss es einfach. Du steckst nicht drin, was der Compiler macht.
Selbst wenn du es jetzt hinbekommen würdest (was machst du eigentlich,
wenn tatsächlich ein Überlauf erkannt wird?), kann das schon mit dem
nächsten Compilerupdate hinfällig sein, mit ziemlicher Sicherheit ist es
nach einem Compilerwechsel eine recht potente Fehlerquelle. Schon mit
einem anderen AVR kann das schief gehen (Hardware-Multiplier).
Irgendwelche Hilfskonstrukte, die ausserhalb jeder Norm sind, machen dir
nur Probleme. Und in deinem Fall kann ich nicht mal einen Nutzen
erkennen - wozu also? Was treibt dich? Tatsächlich das eine Byte??
Eine andere Möglichkeit wäre, das du die 4 Ziffern ohne Konvertierung in
ein Array schreibst, und ein Flag setzte.
Außerhalb der Interuptroutine nimmst du bei gesetzem Flag das array und
konvertierst in aller ruhe die Ziffernfolge.
Bei der Variante gibt es die kleinste Interruptdauer und was noch
entscheidender ist, jeder Interruptdurchlauf dauert gleich lang.
Mit IF Bedingungen in der Interruptroutine ist das nicht der Fall.
@crazy horse
Nein eigentlich geht es mir nicht wirklich um das eine Byte. Findet
dieser Überlauf statt soll einfach fix 100 als Wert zugewiesene werden.
Dachte halt das mit dem Carry Flag währe eine recht elegante Sache. Aber
die von Dir angesprochenen Kompatibilitätsprobleme hatte ich auch schon
befürchtet.
@ Ralph
Stimmt schon, aber da in meiner ISR aber eh eine state machine läuft,
und dies eh einer der kleineren Teile ist, würde eine zusätzliche if
Abfrage auch nichts ausmachen.
Werde das jetzt denke ich ähnlich machen wie frettchen vorgeschlagen hat
(if Abfragen). Denke das macht so in diesem Fall am meisten Sinn.
Vielen Danke an alle,
Gruß
Hans