Hallo,
ich möchte zu einer uint16 Variable "sum" zyklisch eine zweite uint16
Variable "Wert" addieren. Jedes mal, wenn bei dieser Addition ein
Übertrag stattfindet möchte ich eine dritte uint8 Variable "cnt"
inkrementieren.
In Assembler würde ich nun einfach nach der Addition das Carry-Flag
prüfen und gegebenenfalls die Inkrementierung auslösen.
Wie kann ich dies am einfachsten in C realisieren. Meine einzige Idee
wäre die Werte der Variablen "sum" vor und nach der Addition zu
vergleichen. Ist die nachher kleiner als vorher, so hat ein Übertrag
stattgefunden. Quasi so:
ISR:
{
...
sum_old=sum;
sum+=wert;
if (sum<sumold) cnt++;
...
}
Geht das nicht einfacher ohne zusätzliche Variable? Oder kann ich nach
der Addition einfach das Carryflag über "bit_is_set" prüfen?
Danke
Gruß
Thomas
So schlimm ist das doch gar nicht, sollten beim ATMega nur 2 Zyklen mehr sein. Daher würde ich den Code portabel lassen, d.h. nicht das Bit 0 im SREG direkt testen. Peter
uint32_t sum; sum += wert. und später: cnt = sum >> 16;
Was Rechenzeit und Speicherbedarf angeht, versuch ich halt immer das beste rauszuholen, sonst bin ich nicht zufrieden. @Peter: Um die 2 Zyklen geht es mir dann doch nicht, war mir nur ein Dorn im Auge, da man es in ASM einfacher haben könnte. Ich dachte, dass es vielleicht auch in C noch ne bessere Möglichkeit gäbe. @A.K. Daran hab ich auch schon gedacht, aber dann hantiere ich ja bei jeder Addition immer (teils unnötig) mit 4 Bytes rum, wobei ich eins nun ganz nutzlos zum Spaß mitschleppe. Danke für eure Meinungen, wenn jemand noch was besseres weiß, darf er das natürlich trotzdem noch mitteilen. Danke Gruß Thomas
Es geht auch ohne zusätzliche Variable:
if((sum+wert)<sum) cnt ++;
sum += wert;
zumindest winavr ist schlau genug, die Summe nicht 'zweimal' zu
berechnen, der Schuß geht aber trotzdem vom Speicher/Rechenzeitbedarf
nach hinten los, siehe angehängte listings, schade.
Cheers
Detlef
00000096 <tttt>:
static UINT16 sum;
static UINT8 cnt;
UINT16 sum_old;
sum_old=sum;
96: 20 91 f6 01 lds r18, 0x01F6
9a: 30 91 f7 01 lds r19, 0x01F7
sum += wert;
9e: 82 0f add r24, r18
a0: 93 1f adc r25, r19
a2: 90 93 f7 01 sts 0x01F7, r25
a6: 80 93 f6 01 sts 0x01F6, r24
if(sum<sum_old) cnt ++;
aa: 82 17 cp r24, r18
ac: 93 07 cpc r25, r19
ae: 28 f4 brcc .+10 ; 0xba
b0: 80 91 f8 01 lds r24, 0x01F8
b4: 8f 5f subi r24, 0xFF ; 255
b6: 80 93 f8 01 sts 0x01F8, r24
ba: 08 95 ret
00000096 <tttt>:
static UINT16 sum;
static UINT8 cnt;
//UINT16 sum_old;
if((sum+wert)<sum) cnt ++;
96: 20 91 f6 01 lds r18, 0x01F6
9a: 30 91 f7 01 lds r19, 0x01F7
9e: a9 01 movw r20, r18
a0: 48 0f add r20, r24
a2: 59 1f adc r21, r25
a4: 42 17 cp r20, r18
a6: 53 07 cpc r21, r19
a8: 28 f4 brcc .+10 ; 0xb4
aa: 80 91 f8 01 lds r24, 0x01F8
ae: 8f 5f subi r24, 0xFF ; 255
b0: 80 93 f8 01 sts 0x01F8, r24
sum += wert;
b4: 50 93 f7 01 sts 0x01F7, r21
b8: 40 93 f6 01 sts 0x01F6, r20
bc: 08 95 ret
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.