Forum: Mikrocontroller und Digitale Elektronik avr (atmega8) 32bit increment


von Daniel R. (h3po)


Lesenswert?

Hallo,
Ich programmiere gerade das erste mal in Assembler, auf einem Asuro mit 
Atmega8. Ich habe mich nach und nach an die Hardwareinitialisierung 
herangetastet, jetzt möchte ich einige der Standardfunktionen der 
C-Library nachimplementieren.
Dazu gehört ein 36kHz timer2-Interrupt, welches das Trägersignal für die 
Infrarotschnittstelle erzeugt und außerdem counter für die Zeitreferenz 
managed. Das Interrupt habe ich schon erfolgreich eingerichtet und ich 
kann Strings aus dem Flash über Infrarot an den Rechner senden.

Folgenden C-Schnipsel möchte ich implementieren:
1
SIGNAL (SIG_OVERFLOW2)
2
{
3
  TCNT2 += 0x25;
4
  count36kHz ++;
5
  if (!count36kHz)
6
    timebase ++;
7
  if (Ovr2IntFunc)
8
    Ovr2IntFunc();
9
}

Jetzt stehe ich etwas auf dem Schlauch bei dem 32-Bit Zähler, der im ram 
liegt.
Wie inkrementiere ich am besten einen 32-Bit Wert im RAM?
Mein jetziger Ansatz sieht so aus, und scheint (im Simulator) auch zu 
funktionieren (habe den fraglichen teil der Einfachheit halber erstmal 
ohne Interrupt implementiert):
1
.include "m8def.inc"
2
3
.def itmp = r24
4
.def itmp1 = r25
5
6
.dseg
7
count36kHz:  .byte 1        ;unsigned int
8
timebase:  .byte 4        ;unsigned long, system time in ms
9
10
.cseg
11
.org 0x000  rjmp reset
12
13
reset:
14
  clr tmp
15
  sts count36kHz, tmp
16
  sts timebase, tmp
17
  sts timebase+1, tmp
18
  sts timebase+2, tmp
19
  sts timebase+3, tmp
20
21
  rjmp main
22
23
main:
24
  /* erstmal ohne timer interrupt
25
  in  itmp1, TCNT2
26
  ldi itmp, 0x25        
27
  add itmp, itmp1
28
  out TCNT2, itmp      ;preload for 36kHz period
29
  */
30
31
  lds itmp, count36kHz
32
  inc itmp
33
  sts count36kHz, itmp    ;increment the interrupt counter
34
35
  brbc 1, main_end    ;skip if not zero
36
37
  lds itmp, timebase
38
  lds itmp1, timebase+1
39
  adiw itmp1:itmp,1
40
  sts timebase, itmp
41
  sts timebase+1, itmp1    ;increment lower word
42
  brbc 1, main_end    ;skip if no overflow
43
  lds itmp, timebase+2
44
  lds itmp1, timebase+3
45
  adiw itmp1:itmp,1
46
  sts timebase+2, itmp
47
  sts timebase+3, itmp1    ;increment upper word
48
49
  nop
50
51
main_end:
52
  rjmp main

Gibt es evtl. eine elegantere Möglichkeit, die Systemzeit mitzuzählen? 
Die beiden anderen Counter werden leider durch andere Funktionen belegt. 
Die krumme Periode macht es nachher ziemlich kompliziert, von den 
Zählern auf Millisekunden umzurechnen... Konnte bisher noch keine avr 
Tutorials für 32-Bit Arithmetik finden, hat da jemand einen Tipp für 
mich?

von Daniel R. (h3po)


Lesenswert?

kleiner Nachtrag: avr-gcc macht zum inkrementieren folgendes:
1
CLR       R1             ;Clear Register
2
[...]
3
LDS       R24,0x0060     ;Load direct from data space
4
LDS       R25,0x0061     ;Load direct from data space
5
LDS       R26,0x0062     ;Load direct from data space
6
LDS       R27,0x0063     ;Load direct from data space
7
ADIW      R24,0x01       ;Add immediate to word
8
ADC       R26,R1         ;Add with carry
9
ADC       R27,R1         ;Add with carry
10
STS       0x0060,R24     ;Store direct to data space
11
STS       0x0061,R25     ;Store direct to data space
12
STS       0x0062,R26     ;Store direct to data space
13
STS       0x0063,R27     ;Store direct to data space

Dagegen kommt mir meine Variante ja schon relativ elegant vor, 2 statt 4 
Register und Operationen auf dem oberen wort nur jeden 2^16. Cycle.

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
Noch kein Account? Hier anmelden.