Forum: Mikrocontroller und Digitale Elektronik einfacher Timer


von Jannik S (Gast)


Lesenswert?

Hi, Ich habe gerade versucht als Anfänger einen Timer zu bauen.
ICh habe einfach vor nach versch. stunden (200,1000,1500 usw) eine
ausgabe über leds zu machen..

Jetzt wollte ich zunnächst einmal etwas im 3sec zum ausführen bringen..

Habe etwas in div. Tutorials gelesen und dabei ist folgendes
herrausgekommen:

.include "m8515def.inc"

.def tmp = r16
.def sregsave = r17

;Timerschritte pro Durchlauf
.equ Timer_z = 48

;Timerstartwert ableiten
.equ Timer_s = 256-Timer_z

.org 0x000

  rjmp main     ;reset
  reti      ;INT0 (unbelegt)
  reti       ;INT1 (unbelegt)
  reti      ;Timer1 Capture (unbelegt)
  reti      ;Timer1 Compare Match (unbelegt)
  reti      ;Timer1 Overflow (unbelegt)
  rjmp timer0ov  ;Timer0 Overflow
  reti       ;UART, RX Complete (unbelegt)
  reti      ;UART, Data register empty (unbelegt)
  reti      ;UART, tx complete (unbelegt)
  reti      ;Analog Comparator (unbelegt)

;Hauptprogramm

main: ;Stack einrichten
  ldi tmp, LOW(RAMEND)
  out SPL, tmp
;PORT A einrichten
  ldi tmp, 0b11111111
  out DDRA, tmp
;Timer 0 auf Startwert setzten
  ldi tmp, Timer_s
  out TCNT0, tmp

;Timer0 programmieren
;Prozessortakt mit Teilerfaktor 64

  ldi tmp, 0b00000011
  out TCCR0, tmp

;Timer0 Overflow INterrupt
;einschalten
  ldi tmp, 0b00000010
  out TIMSK, tmp

;Interrupts global einschalten
  sei

;endlosschleife

schleife: rjmp schleife

timer0ov:   ;ISR
;Timer0 Overflow

;Register sichern
  push tmp
  push sregsave

;SREG sichern
  in sregsave, SREG

;TImer neu programmieren
  ldi tmp, Timer_s
  out TCNT0, tmp

;hier folgen  Befehle die alle 3 sec ausgeführt werden sollen
  ldi tmp, 0b11111111
  out PORTA, tmp

;SREG wiederherstellen
  out SREG, sregsave

;Register wiederherstellen
  pop sregsave
  pop tmp

;Fertig
  reti

Wenn ich das jetzt im simulator austesten möchte, zählt er zwar hoch
bis er voll ist - löschen und neu beginnen tut er auch, aber er setzt
mein port nicht auf high. woran kann das liegen? ich habe echt keine
ahnung.. bin auch nicht wirklich drinn in der materie..

Gruß
Jannik

von A.K. (Gast)


Lesenswert?

SPH hältst du für überflüssig? Das Beispiel stammt wohl vom 2313.

von Magnus Müller (Gast)


Lesenswert?

>> .include "m8515def.inc"

Du compilierst also für den ATmega8515. Hast du dem Simulator auch
gesagt, dass er den mega8515 simulieren soll?

Gruß,
Magnetus

von Karl H. (kbuchegg)


Lesenswert?

Setz mal bei deinen Interrupt Vektoren auf jeden einzelnen
einen Breakpoint :-)

(Irgendwo hast du dich verzählt und einen reti ausgelassen, der
Interrupt landet beim UART-RX-Complete Interrupt)

von Jannik S (Gast)


Lesenswert?

Ja, der Simulator steht auf mega8515. Was ist denn SPH?
Bin wirklich gaaanz am Anfang von dem Ganzen
Wo seh ich das denn, dass er beim UART-RX-Complte landet? müss ich
eigentlich die ganzen interrupts reinschreiben? theoretisch wäre doch
auch einfach nur
........
  rjmp main     ;reset

  rjmp timer0ov  ;Timer0 Overflow


;Hauptprogramm

...........

möglich? oder hat das irgendwelche vor/nachteile?

von Karl H. (kbuchegg)


Lesenswert?

SPH ist das Register, welches das höherwertige Byte des
Stackpointers aufnimmt. Das solltest du auch setzen.

   ldi tmp, HIGH(RAMEND)
  out SPH, tmp

Im AVR Studio Simulator, setzt du den Cursor in die
Zeile mit dem RETI. Dann drückst du F9. Als Bestätigung
erscheint am Zeilenanfang ein roter Knödel. Der symolisiert,
dass in dieser Zeile ein Breakpoint sitzt. Wann immer das
Programm an diese Stelle kommt (egal ob du mit F10 durchsteppst
oder das Pgm mit F5 laufen lässt) unterbricht der Simulator das
Programm und meldet sich bei dir wieder.

Jetzt mach mal in jeder Zeile der Interrupt Vektoren einen
Breakpoint rein und lass das Pgm laufen. Dann siehst du
welcher Interrupt benutzt wird.

von Jannik S (Gast)


Lesenswert?

Ahh alles klar. Davon hatte ich bereits gelesen, mit dem Low und High
register.
Nun sehe ich es auch, dass der Cursor bei UART RX stehen bleibt... aber
wieso? was kann ich da machen? Ich bin da ein wenig ahnungslos wo da das
Problem ist

von Karl H. (kbuchegg)


Lesenswert?

> Nun sehe ich es auch, dass der Cursor bei UART RX stehen bleibt...
> aber wieso? was kann ich da machen? Ich bin da ein wenig ahnungslos
> wo da das Problem ist

Du gehst so vor:
Du nimmst dir dein 8515 Datenblatt, dass du dir von Atmel downgeloadet
hast und schlägst es auf Seite 55 auf.
Dort findet sich die für den 8515 gültige Vektortabelle:
Der Timer0 Overflow Vector ist der 8te Handler.
Und jetzt vergleich wir mal mit deinem Code.
Der 8. Handler ist bei dir der USART Handler.
Da fehlt also einer.
Vergleichen wir nochmal. Die Reihenfolge im Datenblatt ist:

RESET   INT0   INT1   TIMER1_Capture  Timer1_Compare_A

Ah da haben wir es schon, du hast den Timer1 Compare Match B
vergessen. Damit rücken alle weiteren Interrupts eins vor.
Das interessiert aber deinen µC herzlich wenig. Bei einem,
Timer0 Overflow springt der den 8-ten Interrupt an. AUch
wenn dann dort nur ein RETI steht :-)

von Jannik S (Gast)


Lesenswert?

Alles klar, nun funktioniert alles.. muss man sich erstmal zurechtfinden
mit der "logik" der mcu´s... :)
vielen Dank!

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.