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?
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?
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.
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.
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.
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).
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.
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...
S. Landolt schrieb:> Nanu, bei mir läuft es, auf einem ATtiny85.
Wenn du Compare Match Output A UND B auf toggeln stellst und dann den
Match erzwingst, toggeln auch beide und du hast immer noch keinen
Versatz drin.
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.
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.
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^^
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)
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...
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.
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.
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.
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
return0;
Pack ne LED an PB0 und stelle fest das PB0 low ist!