www.mikrocontroller.net

Forum: Compiler & IDEs Wie am einfachsten einfachsten einen Übertrag erkennen?


Autor: TOM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint32_t sum;
sum += wert.

und später:

cnt = sum >> 16;

Autor: TOM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Detlef A (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.