Forum: Mikrocontroller und Digitale Elektronik finde nicht das problem dieses timers


von gost (Gast)


Lesenswert?

es ist ein timer mit ctc mode!! ich habe ein 16Mhz clock!!
benutze ein atmega16!

aber finde nicht warum er alle sekunden nicht wiedervon anfang den timer 
laufen lässtund den interrupt nach eine sekunde auslöst und den inerrupt 
programm macht.
;======================================================================= 
==



;programm um ein timer zu benutzen den alle sekunden ein wert auf die 
LED zeigt!!
;----------------------------------------------------------------------- 
---------

.include "m16def.inc"
.device ATmega16            ;Ausgewählter ATmel

.equ CLOCK = 16000000          ;f = 16 MHz


.def temp   = r16          ;TemporärerRegister
.def C    = r17              ;Zähler

.org 0x001            ;Startadresse
          rjmp reset

;Interrupt vom Timer 1  der alle sekunden einschalten soll
;-------------------------------------------------------------------
.org 0x0C        ;für mega16 und mega 8 ist:0x006
      rjmp tabelle  ;Jump wenn 1s fertig ist

;-----------------------------------------------
;Deklarieren von Eingang und Ausgang
;-----------------------------------------------

reset:    ldi  temp,0b11111111  ;Initialisieren der Ausgänge
        out  DDRB,temp
    ldi  temp,0b00000000    ;Initialisieren der Eingänge
    out  DDRD,temp

;-----------------------------------------------------------------------
;Initialisieren des Timers und deklarieren wenn interrupt soll starten
;-----------------------------------------------------------------------
INIT:  ldi temp,0b00000000;Timer 1 normal operation mode einstellen
  out TCCR1A,temp

  ldi temp,0b00001100;Timer 1 normal operation und prescaler 256
  out TCCR1B,temp

        ldi  temp,0b00010000;Interrupt bei Timerüberlauf einschalten
  out TIMSK,temp

  ldi  temp,0b11110100  ;
  out  OCR1AH,temp

  ldi  temp,0b00100100
  out OCR1AL,temp



;---------------------------------------------------------
;Normaler programm der in schleife dreht und nicht macht
;---------------------------------------------------------
      sei                   ;Global Interrupt aktivieren

xloop:    rjmp xloop



;----------------------------------------------------------------------- 
-----------------------------------------
;
;              Programm wenn interrupt von timer gestart wurde
;----------------------------------------------------------------------- 
-----------------------------------------


tabelle: ldi  temp,0x01
  com  temp
  out  PORTB, temp;wert von tabelle auf die LED's zeigen
  rcall DELAY
  ldi  temp,0x02
  com  temp
  out  PORTB, temp  ;wert von tabelle auf die LED's zeigen


  RETI    ;interrupt enden (reti steht für Return interrupt)


DELAY:

      ldi  r19, 0x0F

DELAY_4:

      ldi  r20, 0x37

DELAY_5:

      ldi  r21, 0xC9

DELAY_6:

      dec  r21
      brne DELAY_6
      dec  r20
      brne DELAY_5
      dec  r19
      brne DELAY_4
      ldi  r19, $01

DELAY_7:

      dec  r19
      brne DELAY_7

von johnny.m (Gast)


Lesenswert?

Wenn Du Interrupts und Funktionsaufrufe verwenden willst, musst Du schon 
den Stack Pointer initialisieren. Außerdem solltest Du darauf achten, 
dass Deine Kommentare auch zu dem kommentierten Code passen (Du gibst 
korrekterweise den Compare-Interrupt frei, schreibst aber was von 
Overflow Interrupt; und Du hast den CTC-Modus eingestellt, schreibst 
aber "normal Operation").

von johnny.m (Gast)


Lesenswert?

>.org 0x001            ;Startadresse
>          rjmp reset
...und das ist Blödsinn. Der Reset-Vektor steht an der Adresse 0. Sollte 
mich wundern, wenn da so überhaupt was funktioniert...

von Falk B. (falk)


Lesenswert?

@ johnny.m

>>.org 0x001            ;Startadresse
>>          rjmp reset
>...und das ist Blödsinn. Der Reset-Vektor steht an der Adresse 0. Sollte
>mich wundern, wenn da so überhaupt was funktioniert...

Warum nicht? An Adresse Null steht halt irgendein Befehl (natürlich 
keine Sprungbefehl), der wird ausgeführt und danach wird gesprungen.

MFG
Falk

von johnny.m (Gast)


Lesenswert?

> An Adresse Null steht halt irgendein Befehl
Da müsste eigentlich FFh stehen, und das ist kein gültiger Befehl...

von gost (Gast)


Lesenswert?

Ist so das programm besser! Aber es funktioniert noch nicht!
Habe ich den TCCR1A falsch gesetzt oder was?
;====================================================================




;programm um ein timer zu benutzen den alle sekunden ein wert auf die 
LED zeigt!!
;----------------------------------------------------------------------- 
---------

.include "m16def.inc"
.device ATmega16            ;Ausgewählter ATmel

.equ CLOCK = 16000000          ;f = 16 MHz


.def temp   = r16            ;Temporärer Register
.def C    = r17              ;Zähler

.org 0x001                ;Startadresse
          rjmp reset

;Interrupt vom Timer 1  der alle sekunden einschalten soll
;-------------------------------------------------------------------
.org 0x0C                    ;für mega16 und mega 8 ist:0x006
      rjmp tabelle            ;Jump wenn 1s fertig ist

;-----------------------------------------------
;Deklarieren von Eingang und Ausgang
;-----------------------------------------------

reset:    ldi  temp,0b11111111    ;Initialisieren der Ausgänge
        out  DDRB,temp
      ldi  temp,0b00000000    ;Initialisieren der Eingänge
      out  DDRD,temp

;-----------------------------------------------
;Initialisieren des STACK's
;-----------------------------------------------

      ldi  temp,HIGH(RAMEND)    ;High-RAM initialisieren
      out  SPH,temp
      ldi  temp,LOW(RAMEND)    ;Low-RAM initialisieren
      out  SPL,temp
;-----------------------------------------------------------------------
;Initialisieren des Timers und deklarieren wenn interrupt soll starten
;-----------------------------------------------------------------------
INIT:ldi temp,0b00000000  ;
  out TCCR1A,temp

  ldi temp,0b00001100  ; prescaler 256
  out TCCR1B,temp

  ldi  temp,0b00010000        ;
  out TIMSK,temp

  ldi  temp,0b11110100
  out  OCR1AH,temp

  ldi  temp,0b00100100
  out OCR1AL,temp



;---------------------------------------------------------
;Normaler programm der in schleife dreht und nicht macht
;---------------------------------------------------------
      sei                   ;Global Interrupt aktivieren

xloop:    rjmp xloop



;----------------------------------------------------------------------- 
-----------------------------------------
;
;              Programm wenn interrupt von timer gestart wurde
;----------------------------------------------------------------------- 
-----------------------------------------


tabelle:  ldi  temp,0x01
    com  temp
    out  PORTB, temp  ;wert  auf die LED's zeigen
    rcall DELAY
    ldi  temp,0x02
    com  temp
    out  PORTB, temp ;wert auf die LED's zeigen

    sei
    RETI   ;interrupt enden (reti steht für Return interrupt)


DELAY:

      ldi  r19, 0x0F

DELAY_4:

      ldi  r20, 0x37

DELAY_5:

      ldi  r21, 0xC9

DELAY_6:

      dec  r21
      brne DELAY_6
      dec  r20
      brne DELAY_5
      dec  r19
      brne DELAY_4
      ldi  r19, $01

DELAY_7:

      dec  r19
      brne DELAY_7

von gost (Gast)


Lesenswert?

Habe die adresse am anfang auf 0x00 gesetzt aber es geht noch nicht!!

Warum?
ist da noch etwas!

von johnny.m (Gast)


Lesenswert?

Du hast immer noch die falsche Startadresse drin! Außerdem fehlt am Ende 
der DELAY-Routine ein "ret". Du kommst so nie wieder aus der 
Interrupt-Routine raus. Und das "sei" hat vor dem "reti" nichts zu 
suchen.

von johnny.m (Gast)


Lesenswert?

OK, Überschneidung...

von gost (Gast)


Lesenswert?

Ist wenigstens dieser teil richtig: danke!!




;-----------------------------------------------------------------------
;Initialisieren des Timers und deklarieren wenn interrupt soll starten
;-----------------------------------------------------------------------
INIT:    ldi temp,0b00000000  ;Timer 1 normal operation mode einstellen
      out TCCR1A,temp

      ldi temp,0b00001100    ;Timer prescaler 256
      out TCCR1B,temp

      ldi  temp,0b00010000        ;
      out TIMSK,temp

      ldi  temp,0b11110100
      out  OCR1AH,temp

      ldi  temp,0b00100100
      out OCR1AL,temp

von johnny.m (Gast)


Lesenswert?

...Ach ja, die zweite LED wird dann natürlich auch nie eingeschaltet. 
Alles hinter dem "rcall DELAY" wird nie ausgeführt. Am Ende der 
DELAY-Schleife gehts ins Nirvana (Absturz nennt man das...)

von johnny.m (Gast)


Lesenswert?

> Ist wenigstens dieser teil richtig
Bis auf den immer noch unzutreffenden Kommentar scheint da alles OK zu 
sein.

von gost (Gast)


Lesenswert?

Ist die adresse nicht 0x0000 ??

von gost (Gast)


Lesenswert?

ich habe jetzt nach dem delay ein ret gesetzt!! was soll ich noch 
ändern????

Danke für die hilfe!

von johnny.m (Gast)


Lesenswert?

> Ist die adresse nicht 0x0000 ??
Das spielt keine Rolle, ob 0x00 oder 0x0000. Null bleibt Null...

> was soll ich noch ändern????
Das was ich oben geschrieben habe. Außerdem erschließt sich mir der Sinn 
des Programms nicht wirklich. Wozu verwendest Du einen Timer und dann im 
Interrupt eine Delay-Schleife?

Außerdem täten es ein paar weniger Frage- und Ausrufezeichen auch...

von gost (Gast)


Lesenswert?

es ist gut es geht schon es ware nur sie fehler dies du mir gesagt 
hast!!

Ich hatte diesen programm geschrieben um den timer testen zu können ob 
er alle
sekunden den inerrupt machte!!

Und jetzt funktioniert er!! und kann ihn jetzt in ein anderes programm 
verwenden!!


Danke  johnny.m das war sehr net von dir !!

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.