So, ihr lieben (frei nach DJ Taucher),
ich hab's jetzt raus, so geht's. Den Fehler mit der
PORTB-Invertierung innerhalb der while-Schleife (Zeile 25/26) habe ich
gesehen, als dieses Posting gerade hier war, löschen kann ich es nicht
und auch nicht im nachhinein ändern. Aber der Tip mit der
Timer-Zählvariablen Initialisierung (TCNT1 = 0;) habe ich noch
nachgelegt und den Prescaler nochmal angepast, die Interruptfreigabe
durch TOIE1 rausgenommen und so läufts. Meßwerte unten drunter!
Ich packe es mal als Beispielcode hier hin, für den Fall, daß
irgendjemand in der Zukunft auch so'n Problem hat. Ich habe gesucht,
gesucht und nix gefunden :( .. und auf die Gefahr, daß es hier auch
wieder verschwindet, weil es ja evtl. doch in die Rubrik Codesammlung
gehört.
1 | #include <stdlib.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 | int main(void)
|
6 | {
|
7 | // Timer Register
|
8 | TCNT1 = 0; // Timer Startwert
|
9 | TCCR1B = (1<<WGM12) | (1<<CS11); // Prescaler = 8
|
10 | OCR1A = 5000; // Timer1 bis 5000 zählen lassen, dann Interrupt
|
11 | TIFR1 = 1<<ICF1;
|
12 | TIMSK1 = 1<<OCIE1A;
|
13 |
|
14 | // Port Register
|
15 | DDRB = 0x07; // Port PB0, PB1, PB2 Output
|
16 | PORTB = 0xFF; // Port PB0....7 aus
|
17 |
|
18 | sei();
|
19 |
|
20 | PORTB = 0xFD; // eine LED einschalten
|
21 | while(1)
|
22 | ;
|
23 |
|
24 | return 0;
|
25 | }
|
26 |
|
27 |
|
28 | ISR(SIG_OUTPUT_COMPARE1A)
|
29 | {
|
30 | PORTB = ~PORTB;
|
31 | }
|
Was passiert ist, daß eine LED an Port B im 50Hz-Takt blinkt. Ok, es
sind nicht exakt 50Hz, es sind (gemessen mit Keithley 2000 Multimeter)
49.99300 Hz (20,00281 ms Periodenzeit), mit einem 4MHz-Quarz an einem
ATmega48. So, feddich.
Danke an euch, endlich ist das Problem gelöst.
- Hegy