mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR-Timer zählt negativ?


Autor: Johannes Höntsch (serverone)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich muss für ein Projekt den Timer benutzen. Ansich soll die 
ICP-Funktion genutzt werden. Die Register zu laden geht offenbar, nur 
stürzt der Timer nach 9 Durchläufen ab und startet das Hauptprogramm 
neu.

In der Ausgabe äußert sich das so, dass nach 9 Durchläufen wieder mit 
"1" und "2" begonnen wird.

Zum Debuggen habe ich entsprechend Marken bzw. Timer-Ausgaben in den 
Code eingebunden und war dann sehr überrascht, dass auf einmal "-2631" 
ausgegeben wurde. Möglicherweise ist es auch nicht richtig formatiert 
etc., an dem Programm sitze ich schon ein paar Stunden und da kommen 
öfter Fehler rein als raus.

Grundsatzfrage: kann ich das so laufen lassen, wie es aussieht, oder 
muss ich, um das ICP-Ereignis auszuwerten über die ISR gehen?

Was mir auch komisch vorkommt: immer nach 9 Ausgaben bricht er ab und 
startet ja offenbar main neu, da entsprechende Marken wieder erscheinen. 
Hängt das vielleicht mit einem Overflow zusammen? - So weit ich dem 
Datenblatt entnommen habe setzt das den Timer, nicht aber den AVR 
zurück. Auf Overflow zu "warten" hat dann kein Sinn, denn sobald das 
Flag gesetzt wird, startet das Programm neu und damit kann ich wenn das 
TOV1 aus  TIFR1 gelesen wird nichts mehr machen.

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "uart.h"


#define UART_BAUD_RATE      38400


int main(void)
{

uint16_t timerinhalt =0; //fuer ICP-Timer

uint16_t timerinhalt2 =0; //fuer normalen Timer
char timer[6]; //5 Ziffern + \0

// Richtungsdefinitionen:
 DDRB = 0;        // Alles Eingänge, PB0 ist ICP
 PORTB = 0xFF;    // Pullups an Eingängen
 DDRC = 0xFF;     // Port C als Ausgang


 uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU) );
 sei();

 uart_puts("1");

// Timer1-Init:
 TCCR1A = 0x00;                      // normaler Modus
 TCCR1B = (1<<CS12) | (1<<CS10) | (1 << ICES1);    // ICP auf steigende Flanke
 TIMSK1 = (1<<TOIE1) | (1<<ICIE1);   // ICP und Overflow aktivieren

 uart_puts("2");


 for(;;)
 {

    timerinhalt = ICR1L;  //lese vom ICP-Timer
    timerinhalt += (ICR1H<<8);

    timerinhalt2 = TCNT1L; //lese vom normalen timer
    timerinhalt2 += (TCNT1H<<8);

  if (TIFR1 & (1<<ICF1)) // wenn ICP ausgeloest
   {
    uart_puts("3");

    if (timerinhalt > 0) //und Zeit nicht gerade "0"
     {
       uart_puts("6");
     }
    }
  else { itoa(timerinhalt2, timer, 10); //sonst gebe aktuellen Timer-wert aus
         uart_puts(timer);
         uart_putc( "\n");
         _delay_ms(1000);}

 }
}


Autor: maus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du musst definitiv die ISR auch hinschreiben, sonst spingt der irgendwo 
hin beim interrupt

Autor: maus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schau mal hier: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

da sind auch Beispiele zur Verwendung der Interrupt und deren globale 
Variablen/Flags

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu den Interrupts wurde alles Nötige schon gesagt,  Du darfst einen 
Interrupt nur dann erlauben, wenn es eine Routine dafür gibt.  Sonst 
gibt es Reset.

Die negative Zahl ergibt sich aus itoa(), das eine int erwartet.  Du 
aber willst eine unsigned int ausgeben.  3mal darfst Du raten, wie die 
Funktion dann heißt.

Autor: Johannes Höntsch (serverone)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, Danke

ich werde es mal Heute Mittag probieren. Dass er ohne Overflow-ISR 
irgendwo hinspringt könnte denke ich mal eine Erklärung für den 
augenscheinlichen Reset sein.
Gibt es da aber nicht eigentlich eine Standard-Definition für die 
Overflow-ISR?

Autor: Johannes Höntsch (serverone)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hc Zimmerer

Ah, danke, das wusste ich nicht, dass Interrupts explizit definiert 
werden müssen, wenn sie verwendet werden sollen.

Die Funktion ist dann ja natürlich utoa(); -  Je später der Abend, desto 
mehr "einfache" Fehler.

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Gibt es da aber nicht eigentlich eine Standard-Definition für die
>Overflow-ISR?
Wozu? Wenn man den Interrupt nicht braucht schaltet man den nicht an 
(XYZ*IE*-Bits)- der Timer funktioniert ja auch ohne.

hth, Jörg

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt bei avr-gcc durchaus eine, und die führt einen Reset durch.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ah, danke, das wusste ich nicht, dass Interrupts explizit definiert
> werden müssen, wenn sie verwendet werden sollen.

Ach so, was ich vergessen hab: Es ergibt keinen Sinn, einen Interrupt 
verwenden zu wollen, ohne einen dazugehörigen Handler zu schreiben, denn 
der Aufruf dieses Handlers ist ja der Zweck des Interrupts.

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.