mikrocontroller.net

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


Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

#ifndef F_CPU
#define F_CPU           8000000UL                   // processor clock frequency 8Mhz
#endif

//Timer1 16-bit Compare Match A Interrupt Service Routine
ISR (TIMER1_COMPA_vect){
  PORB |= (1 << PB3);        // LED ausschalten
  TCCR1A &= ~(1 << COM1A1);      // deaktiviert den Compare Match für den Pin OC1A
  TIMSK &= ~(1 << OCIE1A);      // Compare Match A Interrupt deaktivieren
}

//Timer1 16-bit Overflow Interrupt Service Routine

ISR (TIMER1_OVF_vect){
  PORTB |= (1 << PB1);    // PORT OC1A einschalten
  PORTB &= ~(1 << PB3);    // LED einschalten, active low
  usGesamtzeit = TCNT1+2001;  // 2000 Timertakte später bei Compare Match wieder ausschalten
  OCR1A = usGesamtzeit;    // Compare Match Register laden
  TCCR1A |= (1 << COM1A1);  // Compare Match für den Pin OC1A aktivieren, wird bei Compare Match low
  TIMSK |= (1 << OCIE1A);  // Compare Match Interrupt aktivieren
}

/*Hauptprogramm Aufgaben:

Das Hauptprogramm
*/
volatile uint16_t usGesamtzeit = 0;

int main(void)
{
  DDRB = 0x00;            // Datenrichtungsregister zunächst alle Eingang 
  PORTB &= ~(1 << PB1);        // Port OC1A Anfang deaktivieren
  PORTB |= (1 << PB0) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB5) | (1 << PB6) | (1 << PB7);  // Pullups einschalten
  DDRB |= (1 << DDB1) | (1 << DDB3); // PB1 und PB3 als Ausgang schalten
  
  // Timer initialisieren
  TCCR1B = (1 << CS10) | (1 << CS11);   // Prescaler 64
  TIMSK = (1 << TOIE1);          // Overflow enable
  TCNT1 = 0;  
  
  sei();
  
  while (1){
  }
  
} // Ende Hauptprogramm

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Das Programm hat sich compilieren lassen?

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

MfG Spess

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
TCCR1A |= (1 << COM1A0); // Toggle OC1A on Compare Match
und dann dabei noch diese Zeile
PORTB |= (1 << PB1);    // PORT OC1A einschalten
wie folgt abändern:
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.