Forum: Mikrocontroller und Digitale Elektronik Ausgangszustand beim Toggle OC0A on Compare Match setzen


von Tim T. (Gast)


Lesenswert?

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?

von Axel S. (a-za-z0-9)


Lesenswert?

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?

von Tim T. (Gast)


Lesenswert?

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...

von Stefan F. (Gast)


Lesenswert?

Vielleicht muss man zuerst OC0A aktivieren, einmal toggeln lassen und 
danach OC0B aktivieren.

von Veit D. (devil-elec)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

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

von Tim T. (Gast)


Lesenswert?

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).

von S. Landolt (Gast)


Lesenswert?

Mir ist unklar, was gegen die Verwendung von FOC spricht; das sind in 
C zwei Befehle, einfacher wird es wohl nicht.

von Tim T. (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

> Das macht so garkeinen Sinn ...

Nanu, bei mir läuft es, auf einem ATtiny85.

von Tim T. (Gast)


Lesenswert?

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...

von Tim T. (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

Probieren Sie das bitte mal auf Ihren ATtiny13 aus und berichten Sie, 
dann sehen wir weiter.

von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

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.

von Tim T. (Gast)


Lesenswert?

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.

von Tim T. (Gast)


Lesenswert?

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^^

von S. Landolt (Gast)


Lesenswert?

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?

von S. Landolt (Gast)


Lesenswert?

Okay, alles klar.

von Tim T. (Gast)


Lesenswert?

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...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von Tim T. (Gast)


Lesenswert?

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.

von Axel S. (a-za-z0-9)


Lesenswert?

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.

von Tim T. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.