Ausgangszustand beim Toggle OC0A on Compare Match setzen

Gast #5662129
Nabend,

ich habe da mal eine Frage zum Toggle OC0A on Compare Match beim Attiny 
(Attiny 13a im speziellen):

Ich möchte OC0A und OC0B beim Compare Match toggeln lassen, soweit kein 
Problem, nur sollen die beiden gegenläufig toggeln, also wenn der OC0A 
Pin high ist soll OC0B low sein und umgekehrt.

Gibt es eine "saubere" Möglichkeit den OC0A oder OC0B vorab auf einen 
anderen Zustand zu setzen? Also irgendetwas besseres als z.B. den OC0A 
auf togglen zu setzen TCCR0A |= (1<<COM0A0), dann einenmal den Compare 
Match zu erzwingen TCCR0B |= (1<<FOC0A) und anschließend erst den TCCR0A 
|= (1<<COM0B0) zu aktivieren?
#5662137
Tim T. schrieb:
> Gibt es eine "saubere" Möglichkeit den OC0A oder OC0B vorab auf einen
> anderen Zustand zu setzen?

OC0A und OC0B selber kannst du nicht beeinflussen. Wohl aber die beiden 
Pins, mit denen die verbunden sind. Und jetzt die Preisfrage: wie setzt 
man den Pegel eines Pins, der als Ausgang konfiguriert ist?
Gast #5662141
Auf Seite 63 im Datenblatt ist eine Zeichnung die erklärt, das sobald 
der Pin als OCnx benutzt wird er vom normalen PORT Register abgekoppelt 
wird...
#5662172
Hallo,

die Pins nicht als Hardware-Timer-Ausgänge konfigurieren, sondern als 
normale Ausgänge. Nur den benötigten Interrupt des Timers konfigurieren. 
Eine state Variable konfigurieren. Mit dieser state Variablen im Timer 
Interrupt beide Ausgänge gegenläufig umschalten.
#5662189
Tim T. schrieb:
> Gibt es eine "saubere" Möglichkeit den OC0A oder OC0B vorab auf einen
> anderen Zustand zu setzen? Also irgendetwas besseres als z.B. den OC0A
> auf togglen zu setzen TCCR0A |= (1<<COM0A0), dann einenmal den Compare
> Match zu erzwingen TCCR0B |= (1<<FOC0A) und anschließend erst den TCCR0A
> |= (1<<COM0B0) zu aktivieren?

Nö, das ist der einzige Weg.
(Firma: Vescomp) #5662196
Falk B. schrieb:
> Tim T. schrieb:
>> Gibt es eine "saubere" Möglichkeit den OC0A oder OC0B vorab auf einen
>> anderen Zustand zu setzen? Also irgendetwas besseres als z.B. den OC0A
>> auf togglen zu setzen TCCR0A |= (1<<COM0A0), dann einenmal den Compare
>> Match zu erzwingen TCCR0B |= (1<<FOC0A) und anschließend erst den TCCR0A
>> |= (1<<COM0B0) zu aktivieren?
>
> Nö, das ist der einzige Weg.

 Selbstverständlich nicht.

 Siehe die angehängten Bilder.
Angehängte Dateien:
Gast #5662209
Also ich dachte auch, dass FOC genau dafür gedacht ist. Einen ATtiny13 
habe ich nicht, beim ATtin85 sieht es, in Assembler, so aus:
1
  ldi   tmp0,(1<<COM0A0)|(1<<COM0B0)|(1<<WGM01)
2
  out   TCCR0A,tmp0
3
  ldi   tmp0,(1<<FOC0A)|(1<<CS02)
4
  out   TCCR0B,tmp0
Gast #5662233
Marc V. schrieb:
> Falk B. schrieb:
>> Tim T. schrieb:
>>> Gibt es eine "saubere" Möglichkeit den OC0A oder OC0B vorab auf einen
>>> anderen Zustand zu setzen? Also irgendetwas besseres als z.B. den OC0A
>>> auf togglen zu setzen TCCR0A |= (1<<COM0A0), dann einenmal den Compare
>>> Match zu erzwingen TCCR0B |= (1<<FOC0A) und anschließend erst den TCCR0A
>>> |= (1<<COM0B0) zu aktivieren?
>>
>> Nö, das ist der einzige Weg.
>
>  Selbstverständlich nicht.
>
>  Siehe die angehängten Bilder.

Ja, über den Satz "The design of the Output Compare pin logic allows 
initialization of the OC0x state before the output
is enabled." bin ich auch schon mehrfach gestolpert, und darum ja auch 
meine Frage. Ich gehe aber davon aus das Atmel damit meint, das man den 
OC0x entsprechend setzen kann BEVOR er vom Port abgekoppelt wird, nicht 
den direkten Registerzugriff auf OCnx. Auf besagter Grafik auf Seite 63 
im Datenblatt hängt das Register ja auch garnicht am Datenbus, meine 
Frage zielte dementsprechend darauf ab ob es eine Möglichkeit gibt den 
Waveform Generator irgendwie direkter dazu zu bekommen die Register 
entsprechend zu setzen als die eingangs von mir beschriebene mit dem 
Force Compare Match (ob jetzt in ASM oder C geschrieben ist ja Wurst).
Gast #5662247
S. Landolt schrieb:
> Also ich dachte auch, dass FOC genau dafür gedacht ist. Einen ATtiny13
> habe ich nicht, beim ATtin85 sieht es, in Assembler, so aus:  ldi
> tmp0,(1<<COM0A0)|(1<<COM0B0)|(1<<WGM01)
>   out   TCCR0A,tmp0
>   ldi   tmp0,(1<<FOC0A)|(1<<CS02)
>   out   TCCR0B,tmp0

Das macht so garkeinen Sinn, wenn dann:

ldi   tmp0,(1<<COM0A0)|(1<<WGM01)
out   TCCR0A,tmp0
ldi   tmp0,(1<<FOC0A)|(1<<CS02)
out   TCCR0B,tmp0
ldi   tmp0,(1<<COM0A0)|(1<<COM0B0)|(1<<WGM01)
out   TCCR0A,tmp0

Oder eben so:

LDI       R24,0x42
OUT       0x2F,R24
LDI       R24,0x80
OUT       0x33,R24
IN        R24,0x2F
ORI       R24,0x10
OUT       0x2F,R24

Allerdings ist der Weg ja bereits im 1. Post beschrieben worden.
Gast #5662258
S. Landolt schrieb:
> Mir ist unklar, was gegen die Verwendung von FOC spricht; das sind in
> C zwei Befehle, einfacher wird es wohl nicht.

Naja, wenn du den nur einmalig umschalten willst schon klar, ansonsten 
musst du wenn du zwischendurch umschalten willst eben den Port wieder 
entsprechend setzen, den Port ankoppeln, den Compare Match Output Mode 
entsprechend stellen, den Match erzwingen, den Compare Match Output Mode 
entsprechend und den Port wieder abkoppeln.
Da wirds dann langsam einfacher den TIM0_COMPA_vect zu nehmen...
(Firma: Vescomp) #5662268
Tim T. schrieb:
> den direkten Registerzugriff auf OCnx. Auf besagter Grafik auf Seite 63
> im Datenblatt hängt das Register ja auch garnicht am Datenbus, meine

 Ich glaube doch, siehe Bild.

 Wenn Portbit log.1 ist, dann ist Gatterausgang auf log.1.
 Wenn DDRbit auch noch auf log.1 geht, dann ist OC1x Pin auch auf
 log. 1

 Ich kann es aber erst heute nacht prüfen.
Angehängte Dateien:
Gast #5662271
Marc V. schrieb:
> Ich glaube doch, siehe Bild.
>
>  Wenn Portbit log.1 ist, dann ist Gatterausgang auf log.1.
>  Wenn DDRbit auch noch auf log.1 geht, dann ist OC1x Pin auch auf
>  log. 1
>
>  Ich kann es aber erst heute nacht prüfen.

Und sobald man den OC Mode benutzt wird der Wert aus Ocnx benutzt und 
nicht der aus dem Portregister.
Gast #5662276
S. Landolt schrieb:
> Probieren Sie das bitte mal auf Ihren ATtiny13 aus und berichten Sie,
> dann sehen wir weiter.

Tatsache, es funktioniert, ist im nachhinein ja auch absolut logisch, es 
wird der Match A erzwungen, nicht der Match allgemein. Man, manchmal 
sieht man den Weld vor lauter Bäumen nicht. Demnach sollte für meine 
Zwecke immer ein erzwungener Compare Match A funktionieren.

Danke fürs mit der Nase drauf stoßen^^
Gast #5662278
an Tim T.:

Die Anforderung war doch
> OC0A und OC0B beim Compare Match ... die beiden gegenläufig toggeln
und das macht nachfolgendes Programm (meinem Verständnis nach)
1
.include "tn85def.inc"
2
.def  tmp0  = r16
3

4
  sbi  DDRB,0
5
  sbi  DDRB,1
6
  ldi  tmp0,64
7
  out  OCR0A,tmp0
8
  ldi  tmp0,(1<<COM0A0)|(1<<COM0B0)|(1<<WGM01)
9
  out  TCCR0A,tmp0
10
  ldi  tmp0,(1<<FOC0A)|(1<<CS02)
11
  out  TCCR0B,tmp0
12
  rjmp  pc
Was habe ich falsch verstanden?
Gast #5662287
Ja, es fuktioniert. War nur irgendwie auf dem Trip das der erzwungene 
Compare Match auf beide wirkt, nicht nur auf einen. Aber klar, dafür 
gibts ja FOC0A und FOC0B damit man die einzaln auslösen kann...
Gast #5662381
Marc V. schrieb:
> Tim T. schrieb:
>> Und sobald man den OC Mode benutzt wird der Wert aus Ocnx benutzt und
>> nicht der aus dem Portregister.
>
>  Natürlich ist das nicht so, der Portregister wird in OC Mode einfach
>  nicht benutzt.

Und genau darum eignet sich das setzen des PORTS nicht um den Wert beim 
Togglen über OC0x zu beeinflussen.
Das OCnx Register und der Port sind 2 verschiedene Sachen die nur 
zufällig auf dem gleichen Pin ausgegeben werden, aber immer nur eines 
von beiden und gegenseitig beeinflussen können die sich demnach auch 
nicht.
Also ist es absolut egal was im Port steht wenn man auf OC Mode 
umgeschaltet hat.
#5662456
Tim T. schrieb:
> Marc V. schrieb:
>> Tim T. schrieb:
>>> Und sobald man den OC Mode benutzt wird der Wert aus Ocnx benutzt und
>>> nicht der aus dem Portregister.
>>
>>  Natürlich ist das nicht so, der Portregister wird in OC Mode einfach
>>  nicht benutzt.
>
> Und genau darum eignet sich das setzen des PORTS nicht um den Wert beim
> Togglen über OC0x zu beeinflussen.

So ein Quatsch. Man setzt erst das Bit in PORTx auf den gewünschten 
Anfangswert und schaltet dann die Funktion "Toggle On Compare Match" 
ein. Und schon fluppt das. Nachdem man das Toggeln aktiviert hat, kann 
man den Pin-Zustand natürlich nicht mehr ändern. Muß man aber auch 
nicht.
Gast #5662489
Axel S. schrieb:
> So ein Quatsch. Man setzt erst das Bit in PORTx auf den gewünschten
> Anfangswert und schaltet dann die Funktion "Toggle On Compare Match"
> ein. Und schon fluppt das. Nachdem man das Toggeln aktiviert hat, kann
> man den Pin-Zustand natürlich nicht mehr ändern. Muß man aber auch
> nicht.

Also dann eben ein Minimalbeispiel damit auch du es siehst:
1
 DDRB = (1 << DDB0);
2
 PORTB = (1 << PB0); // Hier geht PB0 auf High
3
 TCCR0A = (1 << COM0A0) | (1 << WGM01); // Und hier geht PB0 wieder auf Low
4
 while(1);
5
 return 0;

Pack ne LED an PB0 und stelle fest das PB0 low ist!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.