mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer 0 beim Atmega8


Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich habe folgendes Problem(seit Stunden),

Ich habe ein Unterprogramm geschrieben welches den Timer0 benutzt und
beim Überlauf eine Interruptroutine abarbeiten soll.Den Timer habe ich
initialisiert, TCCR0 gesetzt,TIMSK gesetzt,sei() auch eingegeben.
Im AVR-Studio Simmulator zählt der Timer auch hoch,springt aber beim
Erreichen des Endwertes an den Anfang der Main und arbeitet diese
wieder ab. die Interrupt Service Routine wird ignoriert, bringe ich
aber den Quelltext der Routine an das Ende der Quelldatei springt die
ISR weningstens dort hinein, aber nach hochzählen des Timers wieder an
den Anfang der Main! Muß nach abrbeiten der ISR nicht wieder an die
Stelle gesprungen werden von wo sie aufgerufen wurde?
Und warum wird sie manchmal garnicht angesprungen?
ISR (Timer0) oder ISR (Timer0_OVF) falsch?
Danke für eure Hilfe

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du den Code nicht postest, kann Dir hier keiner wirklich helfen,
außer mit schwammigen Vermutungen. Wenn Du mit WINAVR-C programmierst,
dann kann ich Dir wenigstens sagen, dass ISR (Timer0) und ISR
(Timer0_OVF) falsch sind und dass das wahrscheinlich das Problem sein
dürfte, da der Interrupt zwar freigegeben ist, aber der µC keine
gültige ISR zur Bearbeitung hat. Deshalb wird in den Spurious Interrupt
Handler gesprungen, was i.d.R. einen Reset bedeutet. Die richtigen Namen
der Interrupt-Vektoren stehen in der iom8.h. Sie enden alle mit _vect.

Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles klar ich schicke gleich den Quellcode

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier erst das mit den richtigen Interrupt-Vektoren aus! Vielleicht
brauchste dann gar nix mehr zu schicken!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann Dir so viel verraten, dass z.B. der Vektor für den
Overflow-Interrupt von Timer 0 mit TIMER0_OVF_vect definiert ist...

Autor: Andreas 2000 (andreas2000)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Quellcode, vielleicht bin ich ja blind?
Danke

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und initialisiere den Stackpointer, falls du in ASM arbeitest.

...

Autor: J. Ustiz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entweder tatsächlich blind, oder Du kannst nicht lesen. Warum schreib
ich eigentlich den ganzen Scheiß? Kann ich mir dann wohl auch sparen...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@J. Ustiz:
Hä???

@Andreas2000:
Schön, dass Du den Code doch noch schickst, aber einen Fehler hab ich
Dir ja schon mitgeteilt. Abgesehen von dem falschen Vektornamen
bekommst Du wahrscheinlich Probleme mit Variablen, die Du in der ISR
veränderst, wenn Du sie nicht volatile deklarierst.

Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vectornamen habe ich angepasst, Aber trotzdem wird die ISR nicht
angesprungen. Das müsste doch klappen?
Was meinst du mit "volatile"?

Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die ISR wird jetzt aufgerufen.(Ein Zeichen war noch falsch).
Hat denn jemand ne Idee wie man es schaft das der Timer z.B. 5 mal
durchlaufen wird,und dann in die Main zurück springt ?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn eine globale Variable, die in einer Interrupt-Routine verändert
werden soll, nicht volatile deklariert wird, kann es passieren
(vereinfacht gesagt), dass das Hauptprogramm von einer Änderung nichts
mitbekommt. Der Typqualifizierer volatile teilt dem Compiler mit, dass
die betreffende Variable nicht im Rechenregistersatz abgelegt werden
soll, sondern im SRAM, da die vom Programm benutzten Rechenregister am
Anfang der ISR gesichert und am Ende wiederhergestellt werden.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achja, und das mit dem 'Timer 5 mal durchlaufen und dann in die main
zurück' müsstest Du mal näher erläutern. Du willst doch hoffentlich
nicht in der ISR eine Warteschleife einbauen? So was ist nämlich
Pfui...

Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pfui möchte ich natürlich nicht!!
Mein Bemühen ist es ein und Ausschalten eines Ports zu realisieren,
also eine bestimmte Frequenz mit dem Timer zu erzeugen. Diese sollte
aber insgesammt nur 5 Perioden haben(zu Testen).
Später sollen es dann einmal 20 Periden mit einer Frequenz von
41,...kHz werden, um eine US-Transceiver_Schaltung anzusteuern().
Zum erzeugen der Frequenz eignen sich Timer ja gut nur das durchlaufen
des Timers mus irgendwie abzählbar sein!

Autor: Andreas 2000 (andreas2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat denn jemand ne Idee wie man Timerdurchläufe zählbar macht, oder wie
man trotz ISR ein Schleife geschickt einbindet?
Wäre für eine Code Idee dankbar.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Du schreibst in der ISR eine 1 in das Bit TOV0 des Registers TIFR.
Damit setzt Du das Overflow Interrupt-Flag zurück. Dann pollst Du das
Bit TOV0 und wen es wieder gesetzt ist, dann ist wieder ein Overflow
aufgetreten. Bit wieder zurücksetzen und dann wieder pollen (pollen =
abfragen).

Aber ansich ist eine Warteschleife in einer ISR eine Todsünde.

Gruß

Wolfgang
--
www.ibweinmann.de
Brushless Development Kit - Der Weg zum Brushlessregler mit AVR

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm eine globale Variable setze sie auf 10, und zähle bei jedem
Interrupt 1 ab.
Wenn sie 0 erreicht schaltest du das Port-Bit nicht mehr um - fertig.
Jedesmal wenn du wieder erneut ein Signal senden willst setzt du im
Main die Variable wieder auf 10 (oder später auf 40).

Timer_Interrupt:
  if(PeriodCount > 0)
  {
     Port toggeln;
     PeriodCount--;
  }
EndeInterrupt

Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren
AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register
setzt.

Gruss Andi

Autor: Fred (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wie wär's damit:
Die Timer Interrupt Routine (ISR) zählt bei jedem Überlauf eine
Variable um eine Einheit hoch. Jetzt folgt noch die Abfrage, ob diese
Variable schon einen bestimmten Wert erreicht hat (weiteres Bit setzen)
oder nicht (kein Bit setzen g) und es wird ins Hauptprogramm
gesprungen.
Entweder wird jetzt bei jedem Durchlauf des Hauptprogramms dieses Bit
(in irgendeinem beliebigen Register; "privates Statusregister")
abgefragt, oder Du legst es auf einen Pin, der als externer Interrupt
festgelegt ist. Wird aus der ISR zurückgesprungen, wird das Interrupt
enable Bit gesetzt und anschließend sofort die Service Routine für X
Timerdurchläufe ausgeführt.
Gruß

Fred

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren
> AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register
> setzt.

Laut Betreff handelt es sich um den Mega8 und der kann das noch nicht.

...

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>
> Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren
> AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register
> setzt.

Laut Betreff handelt es sich um den Mega8 und der kann das noch nicht.

...
>>
Welches Bit der "neueren" ist das?
Muss ich mir glatt mal ansehen.
PORTTOGGLEBIT oder so?

Wenn man nicht ständig auf dem laufenden bleibt...
AxelR.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Axel:

Bei Mega48/88/168 z.B. bewirkt das Setzen von Bits (Schreiben mit sbi
oder out) in den PIN-Registern (PINB, PINC, PIND) das Toggeln des
zugehörigen Ausgangs. Ist ein nettes Feature, aber dafür wurden etliche
oft gebrauchte I/O-Register (auch Timer) in den Extended-I/O-Space
verlagert, wo sie nicht meht mit IN/OUT (also mit nur einem Takt)
angesprochen werden können.

...

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kapitel 12.2.2 im Datenblatt, habs gefunden.
Danke.
Muss ich für mich aber noch den Nutzen abwägen. kommt man da nicht mit
den Portzuständen komplett durcheineander?
Na egal, danke nochmal

Zu den IN/OUT vs. LD/ST habe ich hier irgentwann mal ein ASM Makro von
der ATMEL Seite gepostet, wo das automatisch berücksichtigt wird.

AxelR.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.