Forum: Mikrocontroller und Digitale Elektronik Bit an GPIO (AVR) präzise getimed ausgeben


von Martin O. (ossi-2)


Lesenswert?

1
ISR(TIMER1_OVF_vect) {
2
  if(theBit){ PORTD |= 0b01000000 ; } else { PORTD &= 0b10111111 ; }
3
  }

Ich möchte ein Bit ausgeben, und zwar in präzisen Zeitabständen. Wenn 
ich das so mache, wie oben, jittert das Bit zum einen weil then-Fall und 
else-Fall in if nicht gleichschnell sind. Zum anderen kommt noch die 
jitternde Interrupt-Latenz dazu.

Hat jemand eine bessere Lösung, z.B. unter Benutzung von PWM oder SPI, 
UART oder sonstigen Hilfen?

von schonwiederohne (Gast)


Lesenswert?

Martin O. schrieb:
>
1
> ISR(TIMER1_OVF_vect) {
2
>   if(theBit){ PORTD |= 0b01000000 ; } else { PORTD &= 0b10111111 ; }
3
>   }
4
>
>
> Ich möchte ein Bit ausgeben, und zwar in präzisen Zeitabständen. Wenn
> ich das so mache, wie oben, jittert das Bit zum einen weil then-Fall und
> else-Fall in if nicht gleichschnell sind. Zum anderen kommt noch die
> jitternde Interrupt-Latenz dazu.
>
> Hat jemand eine bessere Lösung, z.B. unter Benutzung von PWM oder SPI,
> UART oder sonstigen Hilfen?

Statt AVR wäre eine genaue Bezeichnung des µC sinnvoll. In welches 
Datenblatt soll man sonst schauen? Oder benutzt du so etwas nicht?

von Einer K. (Gast)


Lesenswert?

Martin O. schrieb:
> ich das so mache, wie oben, jittert das Bit zum einen weil then-Fall und
> else-Fall in if nicht gleichschnell sind.

Dann:
1
ISR(TIMER1_OVF_vect) 
2
{
3
 PIND = 0b01000000 ;
4
}

Toggelt den Pin, auf allen halbwegs modernen AVR.
Das Datenblatt gibt Auskunft.

Martin O. schrieb:
> z.B. unter Benutzung von PWM

Ja, mach das doch!
Wo ist das Problem?

von Sebastian R. (sebastian_r569)


Lesenswert?

Wenn das Tastverhältnis 50% sein soll, dann kann man den Timer so 
konfigurieren, dass er einen OC-Pin bei einem Match toggled und den 
Timer automatisch neu lädt (CTC)

Mit TCNTxH/L kann man dann die Frequenz des Rechtecksignals vorgeben. 
Das ganze passiert komplett in Hardware, ohne Interrupts und Software.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Timer automatisch neu lädt (CTC)
Eher auf automatisch auf 0 setzt ...

> Mit TCNTxH/L kann man dann die Frequenz des Rechtecksignals vorgeben.
... und das erfolgt im CTC-Modus bei TOP, also OCRnA oder ICRn.

von Martin O. (ossi-2)


Lesenswert?

Die Bits, die jitterfrei auszugeben sind, sind quasi zufällig.

von Jitterfrei (Gast)


Lesenswert?

Der Übliche weg ist, den Pin direkt vom Timer in Hardware toggeln und in 
der ISR nur den Timer für das nächste Intervall setzen.

von Einer K. (Gast)


Lesenswert?

Martin O. schrieb:
> Die Bits, die jitterfrei auszugeben sind, sind quasi zufällig.

KA, was du damit meinst...

von Martin O. (ossi-2)


Lesenswert?

Wers genau wissen will: Die Bits kommen aus einem sigma delta DAC.
Sie sind also ziemlich "unregelmässig".

von Jitterfrei (Gast)


Lesenswert?

Sehe ich das so richtig? Nachdem dein ADC einen Wert eingelesen hat, 
startet er einen Timer. Starten bekommst du ohne Jitter hin. Der Jitter 
entsteht nur, in der ISR nachdem der Timer abgelaufen ist?

von Jim M. (turboj)


Lesenswert?

Martin O. schrieb:
> Wers genau wissen will: Die Bits kommen aus einem sigma delta DAC.
> Sie sind also ziemlich "unregelmässig".

Dafür hätte ich die SPI Einheit missbraucht. Da kommen die Bits synchron 
zum Taktsignal raus.

Moderner µC mit Fifo und/oder DMA für SPI wäre besser geeignet, die 
ollen AVRs haben im SPI Master Mode IIRC eine Verzögerung zwischen den 
Bytes.

Könnte man u.U. im SPI Slave Mode umgehen (Taktquelle wäre dann ein 
Timer im PWM Mode, SCK mit PWM Pin verbunden).

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


Lesenswert?

Martin O. schrieb:
> Ich möchte ein Bit ausgeben, und zwar in präzisen Zeitabständen. Wenn

Martin O. schrieb:
> Wers genau wissen will: Die Bits kommen aus einem sigma delta DAC.
> Sie sind also ziemlich "unregelmässig".

 Wie passt das zusammen ?

 Was ist dein Problem genau ?
 Von welchem Jitter redest du ?

 Verzögerungen bei 1 und 0 sind nicht gleich ?

: Bearbeitet durch User
von Dergute W. (derguteweka)


Lesenswert?

Moin,

Martin O. schrieb:
> Wenn
> ich das so mache, wie oben, jittert das Bit zum einen weil then-Fall und
> else-Fall in if nicht gleichschnell sind.

Das wirst du in C nicht hinkriegen. Da wird nur Assembler und zaehlen 
der Takte helfen.

Gruss
WK

von Martin S. (led_martin)


Lesenswert?

Jim M. schrieb:
> Dafür hätte ich die SPI Einheit missbraucht.

Hallo,

Ich würde dafür, beim AVR, den UART im SPI-Modus verwenden. Durch die 
gepufferte Ausgabe kann man damit unterbrechungsfreie Bit-Folgen 
ausgeben, und das, ohne hohe Timing-Anforderungen an die Software. Mit 
der SPI-Einheit bekommt man grundsätzlich keine unterbrechungsfreie 
Bit-Folgen, da das neue Datenbyte erst geschrieben werden kann, wenn das 
Vorige komplett ausgegeben wurde.

Mit freundlichen Grüßen - Martin

von clocksource (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
>> Die Bits, die jitterfrei auszugeben sind, sind quasi zufällig.

Gibt es die Anforderung auch in realistisch?

von Einer K. (Gast)


Lesenswert?

clocksource schrieb:
> Arduino Fanboy D. schrieb:
>>> Die Bits, die jitterfrei auszugeben sind, sind quasi zufällig.

Von mir nicht!

von Peter D. (peda)


Lesenswert?

Jitterfrei schrieb:
> Der Übliche weg ist, den Pin direkt vom Timer in Hardware toggeln und in
> der ISR nur den Timer für das nächste Intervall setzen.

Genau so macht man es.
Nimm also einen der OC[0..5][A..D] Pins.

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.