Forum: Mikrocontroller und Digitale Elektronik Probleme bei Timer gesteuertem Pin ein-und ausschalten


von Armin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute
wie im Betreff beschrieben, habe ich ein Problem mit dem Timer0 auf
einem ATMEGA32. Das was ich da versuche soll eigentlich so was
ähnliches wie eine Software UART werden. Da die Hardware UART auf dem
ATMEGA schon als Verbindung zum PC verwendet ist, scheidet diese aus.

Genau genommen möchte ich eine Märklin Digital Eisenbahn ansteuern,
wozu ich das "Motorola 2"-Format emulieren muss. Die Kommuikation
findet dabei nur in Richtung der Lokotive statt, ich brauche daher
keine Software RX. Die Datenübertragung zur Lokomotive funktioniert
dabei so, dass eine Logische1 als 1 High Impuls (ca. 26ns) +  7 Bit Low
(ca.182µs) dargestellt wird, die Null genau invertiert. Start- und
Stoppbits gibts keine. Die Stromversorgung dient gleichzeitig als
Signalträger und wenn keine Informationen gesendet werden ist diese bei
-22V. Wenn Daten gesendet werden, wird ein High-Pegel als 22V
dargestellt und Low als 0V. Letzteres macht nichts, weil die
Steuersequenzen recht kurz sind und nach 9 solchen Bytes schon wieder
fertig sind.

Daher kommt das Timing eigentlich an 38400 Baud ser. Datenübertragung
ran (9 Bytes mit je "1+7"). Allerdings brauche ich keine vollständige
uart, es muss nur ein Ausgang möglichst zeitlich genau ein-und
ausgeschaltet werden - UND DAS KRIEG ICH NICHT HIN...
Ich probier da jetzt schon seit ein paar Tagen rum und ich weiss
einfach nicht, wieso da so komisches Zeug passiert, bzw. warums net
geht.

Wenn also von Euch mir da Tipps geben kann, wie ich es besser machen
kann (in C!), dann nur her damit!

Nun zu meinem Programm:
Der eigentliche Timer ist kein Problem, am Ende meines Programms unter
"Interrupts" stehen die Kommentare "Wunschbetrieb" und
"Testvariante" (zum Testen entweder beide Zeilen mit W... oder T...
komplett auskommentieren). Bei Testvariante habe ich einfach mal
probiert, ob der Timer ansich funktioniert, siehe Toggelbit.jpg.
Allerdings ist es ja nicht dass was ich will, ich will ja Daten
übertragen, und keine PWM oder sowas machen.

Wunschbetrieb soll bedeuten, den Ausgang Timergesteuert ein- und
auszumachen. Im Moment schicke ich einfach über USB (mittels FTDI FT232
USB Chip) eine 8-stellige Bitzahl und möchte sie wieder an PINB4
ausgeben. Wenn ich den "Wunschbetrieb" reinmach, werden aber
komischerweise TCCR0 und TCNT0 völlig ignoriert. Man kann was völlig
anderes Reinschreiben und nix ändert sich. Warum dann dabei das letzte
Bit auch immer kürzer ist als die anderen, verstehe ich auch nicht
(siehe Bitfolge.jpg).

Mein Gedankengang war also so, den Pin in Abhängigkeit der Information
Ein- und Auszumachen und anschliessend den Timer zu starten. Wenn dann
der Overflow0 auftritt, deaktiviert sich wieder und dann kommt das
nächste Bit. (Irgendwie habe ich den Eindruck, das mit sich selbst
deaktivieren geht net - aber wie kann mans dann machen?)
Die zwei Oszi-Screenshots kann man hier anguggen:
www.fh-furtwangen.de/~aschoeb/ATM

Vielen Dank
Armin

von peter dannegger (Gast)


Lesenswert?

Das kriegst Du in Software nie zuverlässig hin.

Was Du nehmen mußt, ist der Clear on Compare Modus und dann einen
PWM-Pin , den Du auf setzen oder löschen on Compare initialisierst.

Im Interrupt werden dann die 62 bzw. 182µs als nächster Comparewert
geladen.


Peter

von Armin (Gast)


Lesenswert?

dann müsste ich da also abwechselnd immer einen anderen Comparewert
laden und gleichzeitig von die initialisieung von setzen nach löschen
on Compare ändern, meinst Du das so?

von peter dannegger (Gast)


Lesenswert?

Ja

von Armin (Gast)


Angehängte Dateien:

Lesenswert?

hab jetzt das mal mit dem Timer so wie du gemeint hast probiert.
Wenn ich es einfach immer nur abwechseln aufrufen lasse, dann gehts
(im Anhang befindlichen Code ist das der auskommentierte Teil).

Sobald ich aber das mit einem empfangenen 8Bit Wort machen will,
geht's nicht.
Es ist stimmt doch, dass das Programm nach einem Ihterrupt (wenn er
abgearbeitet wurde)
dort wieder zurückspringt von wo er ausgelösst wurde?
Ich meine, wenn z.B. "ontime_eins()" aufgerufen wird, dann wird durch
den Interrupt
SIGNAL(SIG_OUTPUT_COMPARE0)  "offtime_eins()" aufrufen. Da dort
offtime=1 gesetzt wird, kann sich
offtime nicht selbst nochmal starten und er müsste dann in der while
schleife in bitshift()
weitermachen. Aber irgendwie gehts halt net...
Warum? Sieht jemand einen Fehler oder ist da ein Denkfehler drin?
Wie müsste ich es ändern mit es funzt?

Danke

von Armin (Gast)


Lesenswert?

Weiß keiner einen Rat?
Gut das mit den on-&offtimes ist etwas schlecht dokumentiert, eine
binäre eins wird 182µs high-Pegel + 26µs low Pegel dargestellt. Eine
binäre hingegen wird durch 26µs high-Pegel + 182µs Low-Pegel
dargestellt. Aber dort scheint meiner Meinung nach das Problem nicht zu
liegen.
Leider kann ich halt ne Hardware Uart oder suart nicht nutzen. Dazu
kommt das eine Steuersequenz aus 9 solchen Bits besteht.

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.