Forum: Mikrocontroller und Digitale Elektronik Kann man mehrere Timer.


von Peter B. (pebez)


Lesenswert?

Hallo,

bin ein Anfänger und hänge bei Timern.
Kann man in einem Programm mehrere Timer initialisieren?

Das Tut hilft mir hier nicht wirklich weiter :-(

diese Meldung bekomme ich
error: Overlap in .cseg: addr=0x9 conflicts with 0x9:0xa

Es geht mir nur um das Verständnis, wie man zwei Timer gleichzeitig
in einem Programm einbinden kann, wobei der eine "dieses" und der
andere "jenes" auslöst.

Hat vielleicht jemand einen Beispielcode???

Gruß  Pebez

von Karl H. (kbuchegg)


Lesenswert?

Peter Bednarz schrieb:
> Hallo,
>
> bin ein Anfänger und hänge bei Timern.
> Kann man in einem Programm mehrere Timer initialisieren?

Sicher kann man.
Die sind völlig unabhägig voneinander (wenn wir von einem AVR reden)

> diese Meldung bekomme ich
> error: Overlap in .cseg: addr=0x9 conflicts with 0x9:0xa

Programm zeigen

von spess53 (Gast)


Lesenswert?

Hi

>Hat vielleicht jemand einen Beispielcode???

Wie wäre es erstmal mit deinem Code?

MfG Spess

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>>Hat vielleicht jemand einen Beispielcode???
> Wie wäre es erstmal mit deinem Code?
Wie wärs erstmal mit dem Prozessor?

Ich würde sagen, dass du von der Interruptadresse erst mal schleunigst 
einen Sprung woandershin machen solltest, dann überlappt sich der Code 
an dieser Stelle nicht mehr... :-o

von spess53 (Gast)


Lesenswert?

Hi

>Ich würde sagen, dass du von der Interruptadresse erst mal schleunigst
>einen Sprung woandershin machen solltest, dann überlappt sich der Code
>an dieser Stelle nicht mehr... :-o

Oder jmp statt rjmp.

MfG Spess

von Peter B. (pebez)


Lesenswert?

Hallo,

mein "Programm" ist eigentlich kein Programm sondern nur ein
Versuch, 2 Timer unabhängig voneinander etwas tun zu lassen.

So hatte ich es mir vorgestellt:

.include "m8def.inc"

.def temp = r18
.def temp1 = r19

.org 0x0000
        rjmp    main

.org OVF0addr
        rjmp    timer0

.org  OC1Aaddr
        rjmp    timer1


main:

        ldi     temp, HIGH(RAMEND)
        out     SPH, temp
        ldi     temp, LOW(RAMEND)
        out     SPL, temp

        ldi     temp, 0xFF
        out     DDRB, temp
 ;******* Timer 0 ***********
        ldi     temp, (1<<CS00)
        out     TCCR0, temp
        ldi     temp, (1<<TOIE0)
        out     TIMSK, temp
 ;******* Timer 1 ***********
        ldi     temp1, high( 1000 )
        out     OCR1AH, temp1
        ldi     temp1, low( 1000 )
        out     OCR1AL, temp1
        ldi     temp1, ( 1 << WGM12 ) |( 1 << CS10 )
        out     TCCR1B, temp
        ldi     temp1, 1 << OCIE1A
        out     TIMSK, temp1

        sei

        ldi r16, 0x01
        ldi r17, 0x02

loop:   rjmp    loop

timer0:
        out     PORTB, r16
        com r16
        nop
        reti

timer1:
  out PORTB, r17
  com r17
  nop
  reti

das hab ich auf die schnelle erstellt, um zu testen wie ich zwei Timer
unabhängig arbeiten lassen kann. Ich möchte nur das Prinzip kennen 
lernen.

Gruß  Pebez

von Michael U. (amiga)


Lesenswert?

Hallo,

such Dir mal die Adressen der Interruptvektoren

OVF0addr
OC1Aaddr

dann mal Dir das ab Adresse 0 (Resetvektor) grob auf ein Blatt Papier 
und schau, wo Deine main landet.

Hinweis: der Assembler übersetzt einfach nacheinander, wenn ihm nicht 
eine .org Anweisung eine neue Adresse verpasst.

Abhilfe: die Vektoren in der Reihenfolge einfügen, die der im AVR 
entspricht,
besser: vor main einfach ein

.org INT_VECTORS_SIZE

einfügen.

Das hat Atmel so in den Includes drin, daß es immer hinter den letzten 
Interruptvektor zeigt.

Gruß aus Berlin
Michael

von Peter B. (pebez)


Lesenswert?

Hallo Michael,

danke für den Tipp. Die Adresse für OVF0addr ist $009 und die für
OC1Aaddr ist $006 (wenn ich es richtig in der m8def.inc gelesen habe).

Also gehört die ini für Timer 1 vor die ini von Timer 0 ??
Das mit dem aufzeichnen auf ein Blatt Papier und dann vom Resetvektor 
aus
aufzeichnen wo meine main landet verstehe ich nicht wirklich.

Für mich als Beginner werden auch sofort neue Fragen aufgeworfen.
Z.B. "org. INT_VECTORS_SIZE" kann ich nirgendwo finden.

Ich denke mal, dass ich einen neuen Thread öffne und nach 
Buchempfehlungen
für Einsteiger frage, die auch etwas taugen, denn mit dem Tut gehts wohl
doch nicht so richtig in die Tiefe, obwohl ich mein bisheriges Wissen
komplett aus dem Tut habe.

Danke nochmals für deinen Tipp.

Gruß  Pebez

von Karl H. (kbuchegg)


Lesenswert?

Peter Bednarz schrieb:
> Hallo Michael,
>
> danke für den Tipp. Die Adresse für OVF0addr ist $009 und die für
> OC1Aaddr ist $006 (wenn ich es richtig in der m8def.inc gelesen habe).
>
> Also gehört die ini für Timer 1 vor die ini von Timer 0 ??

Im Grunde ja (du meinst die Interrupt Vektoren, nicht die 
Initialisierung)
Aber so wie du das hast, ist das ja nicht grundsätzlich falsch.

Aber: .org heist ja nur, das du dem Assembler eine neue Startadresse 
gibst, ab der er die Codes für die Befehle ablegt.

Ich transferiere das mal in unsere Welt.
Du hast ein Buch mit leeren Seiten, dort kannst du reinschreiben


.org 0x0000
        rjmp    main

.org OVF0addr
        rjmp    timer0

.org  OC1Aaddr
        rjmp    timer1


Jetzt sag ich dir:
Schreib auf Seite 0   (0x0000)
   Du blätterst brav bis zur Seite 0 und fängst dort an zu schreiben

Dann sag ich dir:
Schreib weiter auf Seite 9  (OVF0addr)
   Du blätterst zur Seite 9 und fängst dort zu schreiben an

Weiters kommt die Anweisung
Schreib weiter auf Seite 6  (OC1Aaddr)
   Auch das machst du. Du suchst die Seite 6 und fängst dort zu
   schreiben an.

Bis hierher ist noch nichts falsch.
Bis du dann in weiterer Folge die Seiten 6, 7 und 8 voll geschrieben 
hast und zur Seite 9 weiterblätterst. Und da du ein Computer bist, der 
ohne ausdrückliche Anweisung nichts macht, überschreibst du in weiterer 
Folge das was bereits auf Seite 9 steht :-)

Autsch!

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Interrupts#Aufbau_der_Interruptvektortabelle

von spess53 (Gast)


Lesenswert?

Hi

>danke für den Tipp. Die Adresse für OVF0addr ist $009 und die für
>OC1Aaddr ist $006 (wenn ich es richtig in der m8def.inc gelesen habe).

Warum nicht das Datenblatt. Dort ist eine Variante für die 
Interruptvektoren die dieses .org-Gedödel nicht benutzt. Zugegeben etwas 
mehr Schreibarbeit. Solltest du dir zumindest mal ansehen. Vielleicht 
wird es dann etwas klarer.

>Also gehört die ini für Timer 1 vor die ini von Timer 0 ??
>Das mit dem aufzeichnen auf ein Blatt Papier und dann vom Resetvektor
>aus

Die Interruptvektoren haben mit der I/O-Initialisierung nichts zu tun. 
In welcher Reihenfolge die Timer initialisiert werden ist dem AVR 
schlichtweg egal.

MfG Spess

von Reinhard R. (reirawb)


Lesenswert?

spess53 schrieb:
> ...
> Warum nicht das Datenblatt. Dort ist eine Variante für die
> Interruptvektoren die dieses .org-Gedödel nicht benutzt. Zugegeben etwas
> mehr Schreibarbeit. Solltest du dir zumindest mal ansehen. Vielleicht
> wird es dann etwas klarer.
Generell eine gute Idee.
Aber was heisst hier Schreibarbeit? Copy&Paste funktionieren auch auch 
aus den Atmel-PDFs heraus :-)

Reinhard

von spess53 (Gast)


Lesenswert?

Hi

>Aber was heisst hier Schreibarbeit? Copy&Paste funktionieren auch auch
>aus den Atmel-PDFs heraus :-)

Also ich habe etliche, bei denen Kopieren nicht geht. Ist mir persönlich 
egal, da ich mir das, und einiges mehr, direkt aus dem entsprechendn 
Partdescriptionfile generiere.

MfG Spess

von Peter B. (pebez)


Lesenswert?

Hallo Karl Heinz,

danke für diesen mir verständlichen Hinweis :-)

So langsam lichten sich die Nebel bei mir.
Werde jetzt mal die Interrupt Routienen Stück für Stück durchgehen.

Vielen Dank auch an alle Beteiligten für euere Geduld :-)

Gruß  Pebez

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.