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?
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...
Vielleicht muss man zuerst OC0A aktivieren, einmal toggeln lassen und danach OC0B aktivieren.
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.
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 |
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).
Mir ist unklar, was gegen die Verwendung von FOC spricht; das sind in C zwei Befehle, einfacher wird es wohl nicht.
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.
> Das macht so garkeinen Sinn ...
Nanu, bei mir läuft es, auf einem ATtiny85.
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.
Probieren Sie das bitte mal auf Ihren ATtiny13 aus und berichten Sie, dann sehen wir weiter.
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)
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?
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.
:
Bearbeitet durch User
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 | return 0; |
Pack ne LED an PB0 und stelle fest das PB0 low ist!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.