Hallo,
Prozessor Atmega 8.
ich möchte einen den Pin OC1A bei einem Compare Match auf umgehend "0",
also low setzen.
Hierzu wird bei jedem Overflow des Timers, das OCR1A Register mit einem
Compare Wert befüllt, die Compare Match Interrupts aktiviert, und auch
der Compare Output für den Pin. Diese Aktivierung geschieht zunächst
immer in der ISR, da dies später bei einem bestimmten Ereignis aktiviert
werden soll (mir ist klar, dass man das hier immer aktiviert lassen
könnte, das ist aber bewusst so).
Zusätzlich möchte ich die ISR Compare Match A ausführen, in der dann
weniger zeitkritische Dinge weiterhin erledigt werden (hier nur eine LED
ausschalten, sowie die Compare Match Register wieder löschen, sodass
diese nicht beim nächsten Durchlauf wieder auftreten, sondern erst, wenn
wieder ein besagtes Ereignis eintritt, werden diese freigeschaltet).
Aber irgendwie funktioniert das ganze nicht, PB1 wird nie low, sondern
bleibt ständig "high".
1 | #include <stdint.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <inttypes.h>
|
5 |
|
6 | #ifndef F_CPU
|
7 | #define F_CPU 8000000UL // processor clock frequency 8Mhz
|
8 | #endif
|
9 |
|
10 | //Timer1 16-bit Compare Match A Interrupt Service Routine
|
11 | ISR (TIMER1_COMPA_vect){
|
12 | PORB |= (1 << PB3); // LED ausschalten
|
13 | TCCR1A &= ~(1 << COM1A1); // deaktiviert den Compare Match für den Pin OC1A
|
14 | TIMSK &= ~(1 << OCIE1A); // Compare Match A Interrupt deaktivieren
|
15 | }
|
16 |
|
17 | //Timer1 16-bit Overflow Interrupt Service Routine
|
18 |
|
19 | ISR (TIMER1_OVF_vect){
|
20 | PORTB |= (1 << PB1); // PORT OC1A einschalten
|
21 | PORTB &= ~(1 << PB3); // LED einschalten, active low
|
22 | usGesamtzeit = TCNT1+2001; // 2000 Timertakte später bei Compare Match wieder ausschalten
|
23 | OCR1A = usGesamtzeit; // Compare Match Register laden
|
24 | TCCR1A |= (1 << COM1A1); // Compare Match für den Pin OC1A aktivieren, wird bei Compare Match low
|
25 | TIMSK |= (1 << OCIE1A); // Compare Match Interrupt aktivieren
|
26 | }
|
27 |
|
28 | /*Hauptprogramm Aufgaben:
|
29 |
|
30 | Das Hauptprogramm
|
31 | */
|
32 | volatile uint16_t usGesamtzeit = 0;
|
33 |
|
34 | int main(void)
|
35 | {
|
36 | DDRB = 0x00; // Datenrichtungsregister zunächst alle Eingang
|
37 | PORTB &= ~(1 << PB1); // Port OC1A Anfang deaktivieren
|
38 | PORTB |= (1 << PB0) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB5) | (1 << PB6) | (1 << PB7); // Pullups einschalten
|
39 | DDRB |= (1 << DDB1) | (1 << DDB3); // PB1 und PB3 als Ausgang schalten
|
40 |
|
41 | // Timer initialisieren
|
42 | TCCR1B = (1 << CS10) | (1 << CS11); // Prescaler 64
|
43 | TIMSK = (1 << TOIE1); // Overflow enable
|
44 | TCNT1 = 0;
|
45 |
|
46 | sei();
|
47 |
|
48 | while (1){
|
49 | }
|
50 |
|
51 | } // Ende Hauptprogramm
|