Forum: Mikrocontroller und Digitale Elektronik OC1A Pin bei Compare Match auf Low


von Manuel (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Das geht so nicht.

Ein Pin als Compare Output ist vom PORT-Register abgekoppelt.
Er läßt sich nur durch Auswahl der Set-, Clear- oder Toggle-Funktion 
ändern.
Zum Ändern ohne das ein Compare erfolgt, muß man das 
Force-Output-Compare Bit setzen (es setzt sich sofort selbst zurück).


Peter

von spess53 (Gast)


Lesenswert?

Hi

Das Programm hat sich compilieren lassen?

>  PORB |= (1 << PB3);        // LED ausschalten

MfG Spess

von Manuel (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Das geht so nicht.
>
> Ein Pin als Compare Output ist vom PORT-Register abgekoppelt.
> Er läßt sich nur durch Auswahl der Set-, Clear- oder Toggle-Funktion
> ändern.
> Zum Ändern ohne das ein Compare erfolgt, muß man das
> Force-Output-Compare Bit setzen (es setzt sich sofort selbst zurück).
>
>
> Peter
>
Ok, danke.
D.h. ich müsste das ganze mit toggeln machen
1
TCCR1A |= (1 << COM1A0); // Toggle OC1A on Compare Match
und dann dabei noch diese Zeile
1
PORTB |= (1 << PB1);    // PORT OC1A einschalten
wie folgt abändern:
1
TCCR1A |= (1 << FOC1A); // PORT OC1A durch Force Compare einschalten bzw. toggeln
Dadurch wird durch das Force Compare PB1 getoggelt und demzufolge high 
(da zuvor low) und bei jedem erreichen vom OCR1A Register dann wieder 
low (da getoggelt).
Und in der ISR (TIMER1_COMPA_vect) deaktiviere ich dann wieder wie 
gehabt das Compare Match.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.