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?