Forum: Mikrocontroller und Digitale Elektronik Timer und Interrupt


von Bernd S. (kurtel)


Lesenswert?

Hallo,

hab ein großes Problem mit Timer und Interrupt.
Ich hab ein Programm zur Temperaturmessung mit Speicherung in EEPROM.
Alle 10 min. wird gespeichert.
Jetzt will ich die Temp. auch auf LCD ausgeben.Jedes für sich läuft.
Wenn ich jetzt beides in mainloop nehme, wird logischerweise auch 
d.Anzeige nur aller 10 min. erneuert. Nun hat jemand gesagt ich soll das 
mit 2 Timern machen. Leuchtet mir auch ein, aber wie das geht 
...................
Hab mal probiert nur die LCD mit 1 Timer laufen zu lassen, da blinkt die 
Anzeige u. nach einer gewissen Zeit kommt nichts mehr. Da ist bestimmt 
in meine Code alles verkehrt. Könnte vielleicht jemand das Code mal 
anschauen?
Danke!!!!!

begin:  rjmp  main  ; 1 POWER ON RESET
  reti    ; 2 Int0-Interrupt
  reti    ; 3 Int1-Interrupt
  reti    ; 4 TC2 Compare Match
  reti    ; 5 TC2 Overflow
  reti    ; 6 TC1 Capture
  reti    ; 7 TC1 Compare Match A
  reti    ; 8 TC1 Compare Match B
  rjmp  onTimer1Ov  ; 9 Timer1 Interrupt bei Überlauf
  reti    ;10 TC0 Overflow
  reti    ;11 SPI, STC Serial Transfer Complete
  reti    ;12 UART Rx Complete
  reti    ;13 UART Data Register Empty
  reti    ;14 UART Tx Complete
  reti    ;15 ADC Conversion Complete
  reti    ;16 EEPROM Ready
  reti    ;17 Analog Comparator
  reti    ;18 TWI (I²C) Serial Interface
  reti    ;19 Store Program Memory Ready
;----------------------------------------------------------------------- 
-
; Initialisierungen
;----------------------------------------------------------------------- 
-
main:
;--- Stack Initialisierung ---
  ldi  r16,hi8(RAMEND)
  out  SPH,r16
  ldi  r16,lo8(RAMEND)
  out  SPL,r16
.equ  TWI_ADR,(0b10010000|0b00000000) ; Feste und Variable (per Jumper) 
Adresse
  rcall  lcdInit
  rcall  twiInitMaster
;Config = NoShutdown,ComperatorMode,ActiveLow,FaultQueue=0
  ldi  r16,0
  ldi  r17,0
  ldi  r18,REG_CONFIG
  rcall  lm75SetRegister


;--- Timer 1 initialisieren ---
  ldi  r16,0b00000101  ; Teiler 1/1
  out  TCCR1B,r16  ; Teiler+Modus schreiben
  in  r16,TIMSK  ; Interrupt bei Überlauf
  ori  r16,0b00000100
  out  TIMSK,r16
;--- Interrupts erlauben ---
  sei
;----------------------------------------------------------------------- 
-
; Hauptprogramm-Schleife
;----------------------------------------------------------------------- 
-
mainloop:  wdr
  rcall  onTimer1Ov
  rjmp  mainloop  ; Sprung zum Beginn der Hauptprogrammschleife
;----------------------------------------------------------------------- 
-
onTimer1Ov:
; Hier beginnt die Interrupt-Service-Routine
  PUSH  R16  ; Benutztes Register auf den Stapel
  IN  R16,SREG  ; Statusregister Zustand einlesen
  PUSH  R16  ; ebenfalls auf den Stapel ablegen
  rjmp  Ausgabe

  POP  R16  ; alten Inhalt von SREG vom Stapel holen
  OUT  SREG,R16  ; und Statusregister wiederherstellen
  POP  R16  ; alten Inhalt von R16 wiederherstellen
  reti    ;Rücksprung
;----------------------------------------------------------------------- 
-
Ausgabe:  wdr
;---Temperatur -> r22:r21
  rcall  lm75GetTemp
;--- Ausgabe
  mov  r16,r22
  rcall  lcdZahl
  ldi  r16,0xDF
  rcall  lcdData
  ldi  r16,'C'
  rcall  lcdData
  rcall  lcdLine1
  ldi  R16,'I'
  rcall  lcdData
  ldi  R16,'T'
  rcall  lcdData
  ldi  r16,''
  rcall  lcdData

von ARM-Fan (Gast)


Lesenswert?

>wird logischerweise auch d.Anzeige nur aller 10 min. erneuert

Wenn du es so programmiert hast, dann ja. "Logisch" ist das aber nicht.

>Nun hat jemand gesagt ich soll das mit 2 Timern machen.

Das ist Käse.

Ein Timer(interrupt) reicht aus, um die meißten zeitlich gesteuerten
Dinge auszulösen.

Laß den Timerinterrupt mit der höchsten von deiner Applikation 
benötigten
Frequenz laufen. Alle anderen leitest du durch Zählen/Teilen davon ab.

von Bernd S. (kurtel)


Lesenswert?

Danke f. Antwort.

"Laß den Timerinterrupt mit der höchsten von deiner Applikation
benötigten
Frequenz laufen. Alle anderen leitest du durch Zählen/Teilen davon ab."

Und das is das was ich nicht bringe. Geht in meine alte Birne nicht mehr 
rein.
Wenn ich einmal ein Codebeispiel hätte, käme ich dann mit ausprobieren, 
umstellen und so, auch weiter.

von Roman (Gast)


Lesenswert?

Du springst in der Interruptschleife mit rjmp  Ausgabe raus, das geht 
nicht weil der IRQ dann nicht beendet wird.
Du kannst anstatt rjmp RCALL verwenden.

von Bernd S. (kurtel)


Lesenswert?

Hab ich jetzt mit rcall probiert.
Sieht in der Ausgabe dann so aus.
IT 20 °C dann
IT 20 °C C C dann
IT 20 °C CC°  dann
IT 20° C CC21° usw.
 Komisch, muss was nicht stimmen

von spess53 (Gast)


Lesenswert?

Hi

>mainloop:  wdr
>  rcall  onTimer1Ov   -> Was soll der Aufruf???
>  rjmp  mainloop  ; Sprung

Du musst dich schon entscheiden, ob du mit Interrupt oder Unterprogramm 
arbeiten willst.

1.Dein Timerinterrupt ist viel zu schnell. Für deine Anwendung würde 1s 
reichen. Und das lässt sich im CTC-Modus besser erreichen.

2. In der Interruproutine werden deine Funktionen nur vorbereitet. 
Einmal wird ein Flag(Register oder im RAM) für die LCDAusgabe gesetzt 
(0->1).

3. Für die EEPROM-Speicherung zählst du eine Variable herunter. Wenn die 
0 wird setzt du ein weiteres Flag und setzt die Variable wieder auf den 
Startwert.

4. Im Hauptprogramm testest du die Flags auf <>0. Wenn das zutrifft 
führst du die entsprechnde Routine (Anzeige oder EEPROM) aus und setzt 
das Flag wieder auf 0.

MfG Spess

von Sinusgeek (Gast)


Lesenswert?

> Wenn ich einmal ein Codebeispiel hätte, käme ich dann mit ausprobieren,
> umstellen und so, auch weiter.

Beitrag "Kleiner Funktionsgenerator mit Tiny2313"

Sieh Dir die Abfrage von Drehgeber und Drehgebertaste an, die werden vom 
selben Timer-Interrupt synchronisiert. Das Prinzip müsste daran 
erkennbar sein.

~

von Bernd S. (kurtel)


Lesenswert?

Danke erstmal an alle!!!!!!
Werd versuchen das Beste draus zumachen.

Allen einen Guten Rutsch

von Bernd S. (kurtel)


Lesenswert?

Hi, ich wieder
erstmal allen alles Gute im Neuen Jahr.
Das mit CTC Modus klingt gut. Hab nun auch alles versucht, es zu 
begreifen, komm aber nicht klar damit.
Nun ganz einfach meine Frage:

Kann mir jemand konkret aufschreiben wie das aussieht. Ich hab 
"Workpadplus"
als Programm und die ganzen Beispielcodes sind ja anders.
Das einzige was ich weiß ist,daß in

main: rjmp   TIM1_COMPA   ; Timer1 CompareA Handler

eingestellt werden müsste. Kann aber auch schon wieder falsch sein.
Mit Timer 1 siehts ja so aus:

;--- Timer 1 initialisieren ---
  ldi  r16,0b00000101  ; Teiler entspricht ca.15 sek.
  out  TCCR1B,r16  ; Teiler+Modus schreiben
  in  r16,TIMSK  ; Interrupt bei Überlauf
  ori  r16,0b00000100  ;
  out  TIMSK,r16
aber wie sieht sowas mit CTC aus? Mit den Tipps weiß ich nichts 
anzufangen.

>2. In der Interruproutine werden deine Funktionen nur vorbereitet.
>Einmal wird ein Flag(Register oder im RAM) für die LCDAusgabe gesetzt
>(0->1).

>3. Für die EEPROM-Speicherung zählst du eine Variable herunter. Wenn die
>0 wird setzt du ein weiteres Flag und setzt die Variable wieder auf den
>Startwert.

>4. Im Hauptprogramm testest du die Flags auf <>0. Wenn das zutrifft
>führst du die entsprechnde Routine (Anzeige oder EEPROM) aus und setzt
>das Flag wieder auf 0.

Das ist keine Bequemlichkeit von mir, aber ich grieg das einfach nicht 
hin.
Ich möchte eigentlich nur das dieses eine Projekt läuft um meine 
Heizugsanlage auszuwerten. Weitere Projekte hab ich gar nicht vor.
Bin einfach zu alt, um mich da noch reinzufinden.
Für einen kompletten CTC Code wäre ich sehr dankbar!!!
Gruss kurtel

von Sinusgeek (Gast)


Lesenswert?

Ich finde die Stelle nicht, in der Du den verwendeten AVR-Typ nennst. 
Daher kann ich Dir auch nichts zum CTC-Modus sagen. Denn die Timer der 
unterschiedlichen AVRs sind unterschiedlich mit Features ausgestattet. 
Bei einigen AVRs gibt es tatsächlich ein CTC-Bit im Steuerregister der 
Timer, bei anderen AVRs geht das in den WGM-Bits unter, da eben neben 
CTC noch etliche andere Modi möglich sind. Zu alt bist Du vermutlich 
nicht, ich bin auch schon lange keine Fuffzich mehr und Programmieren 
ist nicht mein Beruf.

~

von Katapulski (Gast)


Lesenswert?

Je älter der Programmierer, desto schwerer fällt ihm das Pushen und erst 
recht das Poppen!

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Tippe auf ATMega8. Habe dir mal auf die Schnelle die Initialisierung 
gemacht (ohne Gewähr). Im Datenblatt ist ist eine Tabelle mit den 
verschiedenen Timermodes.

MfG Spess

von Bernd S. (kurtel)


Lesenswert?

Hallo  Sinusgeek,
danke f. d.Antwort.
Ich hatte mir das "TWI-Projekt" bei MyAVR gekauft. Da war alles dazu.
LCD, EEpromm, Tempsensor und Programmer.
Als Controller ist d. Atmega 8 dazu.Das Grundgerüst sieht so aus.
;Reset and Interruptvectoren  ;VNr.  Beschreibung
begin:
  rjmp  main  ; 1    POWER ON RESET
  reti    ; 2    Int0-Interrupt
  reti    ; 3    Int1-Interrupt
  reti    ; 4    TC2 Compare Match
  reti    ; 5    TC2 Overflow
  reti    ; 6    TC1 Capture
  reti    ; 7    TC1 Compare Match A
  reti    ; 8    TC1 Compare Match B
  reti    ; 9    TC1 Overflow
  reti    ;10    TC0 Overflow
  reti    ;11    SPI, STC Serial Transfer Complete
  reti    ;12    UART Rx Complete
  reti    ;13    UART Data Register Empty
  reti    ;14    UART Tx Complete
  reti    ;15    ADC Conversion Complete
  reti    ;16    EEPROM Ready
  reti    ;17    Analog Comperator
  reti    ;18    TWI (I²C) Serial Interface
  reti    ;19    Strore Program Memory Ready

Übrigens, Hut ab, wenn du alles noch kappierst in d. Alter.
Ganz blöd bin ich ja auch nicht, aber irgendwie macht´s noch nicht 
Klick.
Wenn ich etwas fertiges habe, kann ich mich dann einfach besser hinein 
versetzen.

kurtel

von Sinusgeek (Gast)


Lesenswert?

> Wenn ich etwas fertiges habe, kann ich mich dann einfach besser hinein
> versetzen.

Das ist bei mir umgekehrt, wenn ich was Eigenes mache, dann kann ich es 
an meine Wünsche anpassen... ;-)

Mega8...

Das Datenblatt des Mega8 zeigt in Tabelle 39 die verschiedenen 
Betriebsarten des 16-Bit-Timer1. Mode 4 wird CTC genannt, der Zählumfang 
gehört dabei in OCR1A (Spalte TOP). In den Spalten weiter links sind die 
WGM-Bits und ihre Bitwerte aufgelistet, die in die zuständigen 
Steuerregister eingetragen werden müssen.

In dieser Betriebsart klappert der Timer von 0 bis zu dem Wert in OCR1A, 
löst dann den Compare1A-Interrupt aus und beginnt wieder bei 0 mit der 
Zählerei. Das ist also die "Sorglos-Betriebsart", man gibt dem Timer 
einmalig seinen Zählumfang, schaltet ihn ein (Vorteiler), gibt seinen 
Interrupt frei (TIMSK und SEI), und schon wird in regelmäßigen 
Zeitabständen ohne weiteres Zutun die ISR aufgerufen. In dieser können 
dann kleinere (schnelle) Aufgaben erledigt werden oder Merker für 
größere Aufgaben gesetzt werden, die das Hauptprogramm dann prüft und 
deren Jobs abarbeitet (die dann den Merker auch wieder löschen, da die 
Arbeit ja getan ist).

@Katpaulski: Dein Katapult ist ja wieder mal mit scharfer Munition 
geladen... ;-)

~

von Bernd S. (kurtel)


Lesenswert?

Danke an alle.
Werd es gleich mal versuchen.

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.