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 | }
|