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.