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.
| 1 | #include <stdlib.h>
 | 
| 2 | #include <avr/io.h>
 | 
| 3 | #include <avr/interrupt.h>
 | 
| 4 | #include <avr/signal.h>
 | 
| 5 | #include <avr/pgmspace.h>
 | 
| 6 | #include <util/delay.h>
 | 
| 7 | #include "uart.h"
 | 
| 8 | 
 | 
| 9 | 
 | 
| 10 | #define UART_BAUD_RATE      38400
 | 
| 11 | 
 | 
| 12 | 
 | 
| 13 | int main(void)
 | 
| 14 | {
 | 
| 15 | 
 | 
| 16 | uint16_t timerinhalt =0; //fuer ICP-Timer
 | 
| 17 | 
 | 
| 18 | uint16_t timerinhalt2 =0; //fuer normalen Timer
 | 
| 19 | char timer[6]; //5 Ziffern + \0
 | 
| 20 | 
 | 
| 21 | // Richtungsdefinitionen:
 | 
| 22 |  DDRB = 0;        // Alles Eingänge, PB0 ist ICP
 | 
| 23 |  PORTB = 0xFF;    // Pullups an Eingängen
 | 
| 24 |  DDRC = 0xFF;     // Port C als Ausgang
 | 
| 25 | 
 | 
| 26 | 
 | 
| 27 |  uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU) );
 | 
| 28 |  sei();
 | 
| 29 | 
 | 
| 30 |  uart_puts("1");
 | 
| 31 | 
 | 
| 32 | // Timer1-Init:
 | 
| 33 |  TCCR1A = 0x00;                      // normaler Modus
 | 
| 34 |  TCCR1B = (1<<CS12) | (1<<CS10) | (1 << ICES1);    // ICP auf steigende Flanke
 | 
| 35 |  TIMSK1 = (1<<TOIE1) | (1<<ICIE1);   // ICP und Overflow aktivieren
 | 
| 36 | 
 | 
| 37 |  uart_puts("2");
 | 
| 38 | 
 | 
| 39 | 
 | 
| 40 |  for(;;)
 | 
| 41 |  {
 | 
| 42 | 
 | 
| 43 |     timerinhalt = ICR1L;  //lese vom ICP-Timer
 | 
| 44 |     timerinhalt += (ICR1H<<8);
 | 
| 45 | 
 | 
| 46 |     timerinhalt2 = TCNT1L; //lese vom normalen timer
 | 
| 47 |     timerinhalt2 += (TCNT1H<<8);
 | 
| 48 | 
 | 
| 49 |   if (TIFR1 & (1<<ICF1)) // wenn ICP ausgeloest
 | 
| 50 |    {
 | 
| 51 |     uart_puts("3");
 | 
| 52 | 
 | 
| 53 |     if (timerinhalt > 0) //und Zeit nicht gerade "0"
 | 
| 54 |      {
 | 
| 55 |        uart_puts("6");
 | 
| 56 |      }
 | 
| 57 |     }
 | 
| 58 |   else { itoa(timerinhalt2, timer, 10); //sonst gebe aktuellen Timer-wert aus
 | 
| 59 |          uart_puts(timer);
 | 
| 60 |          uart_putc( "\n");
 | 
| 61 |          _delay_ms(1000);}
 | 
| 62 | 
 | 
| 63 |  }
 | 
| 64 | }
 |