Hallo zusammen,
ich wollte via µC (z.B. Atmel 324P,... mit 8 MHz Quarz) ein Signal über
den Pin-Interrupt detektieren. Der Pin soll fallende und steigende
Flanken erfassen und einen Interrupt erzeugen.
Es handelt sich um das 1-Wire Protokoll:
0-Signale und Reset/Presence-Signale werden detektiert. Das Problem sind
die 1-Signale, da dort die fallende und steigende Flanke unmittelbar
aufeinander folgen.
Also konkret:
Ich lege über ein Dallas-Demoboard einen Search-Algorithmus auf die
Leitung; ist es das Reset/Presence-Signal oder eine '0', wird dies auch
erkannt.
Aber das 1-Signal, welches maximal 1 us (in meinen Fall) anliegt, wird
nicht detektiert. (Das Signal ist inklusive der Flanken 1 µs lang)
Ich vermute, dass der µC zu langsam ist, die fallende und steigende
Flanke innerhalb einer µs zu erfassen.
Daher meine Frage: Wäre es möglich, das Signal um 4-5 µs zu verlängern,
so dass der µC ausreichend Zeit hat dies zu detektieren? Vielleicht in
Form einer Hardware (diese müsste natürlich entsprechend schnell sein)?
Ich habe da an einen Baustein gedacht, der bei Auftreten einer fallenden
Flanke einen Timer startet und 4-5 µs die Leitung auf Low zieht. Gibt es
so etwas?
Vielen Dank für eure Hilfe.
Mit freundlichen Grüßen
Embrio
Einen 1-wire Master macht man üblicher Weise mit Delays. Das Datenbit
wird etwa 10µs nach der 1-0 Flanke eingelesen:
1-0 Flanke
Delay 1µs
0-1 Flanke
Delay 9µs
Einlesen
Delay 50µs
Peter
Oh, vielen Dank für die Antwort.
Ich programmiere aber keinen Master, sondern versuche einen Slave zu
implementieren. Das habe ich noch vergessen zu erwähnen. Entschuldigung.
Und daher kommt dann auch das Problem, wenn die 1-0 Flanke auftritt und
dann die 0-1 Flanke, dann sind gerade mal ~1µs vergangen. So wie es mir
scheint, reicht die Zeit aber nicht aus, um den Interrupt aufzurufen und
den Pin-Interrupt zu deaktiveren, dass die daruffolgende steigende
Flanke nicht detektiert wird.
Ich hoff, ich habe nicht noch mehr vergessen.
Auf jeden Fall danke für die weitere Hilfe.
Mit freundlichen Grüßen
Embrio
Embrio schrieb:> Ich habe da an einen Baustein gedacht, der bei Auftreten einer fallenden> Flanke einen Timer startet und 4-5 µs die Leitung auf Low zieht. Gibt es> so etwas?
Monostabiler Multivibrator
74 .. 121
Gruß
Joachim
Hallo Embrio,
der ganze Ansatz, alle Flanken per Interrupt zu detektieren, ist falsch.
Denke mal in folgende Richtung:
- Erste 1-0 Flanke per interrupt detektieren
- Dann interrupt sperren und das 1-wire Signal im Polling Modus abtasten
- Immer wieder Plausibilität der Signale testen, um festzustellen, ob
man mit dem ersten 1-0 interrupt auch wirklich den Anfang eines 1-wire
Telgramms erwischt hat. Falls nicht, polling abbrechen und Interrupt
wieder scharf machen.
- Wenn komplettes Telegramm empfangen, dann das Telegramm auswerten.
gruss
gatsby
gatsby schrieb:> Hallo Embrio,>> der ganze Ansatz, alle Flanken per Interrupt zu detektieren, ist falsch.> Denke mal in folgende Richtung:> - Erste 1-0 Flanke per interrupt detektieren> - Dann interrupt sperren und das 1-wire Signal im Polling Modus abtasten> - Immer wieder Plausibilität der Signale testen, um festzustellen, ob> man mit dem ersten 1-0 interrupt auch wirklich den Anfang eines 1-wire> Telgramms erwischt hat. Falls nicht, polling abbrechen und Interrupt> wieder scharf machen.> - Wenn komplettes Telegramm empfangen, dann das Telegramm auswerten.>>> gruss> gatsby
Danke für die Info. Nur damit ich dich richtig verstehe:
Ich detektiere die 1-0 Flanke per ISR, dann ISRs deaktivieren und warten
bis sich das Signal am Pin geändert hat. Je nachdem wie lange gewartet
wurde, wurde ein Reset-Signal erkannt und man kann die weiteren Bits
abwarten, ansonsten wieder die ISR aktivieren
- ist das so richtig?
JoachimB schrieb:> Monostabiler Multivibrator> 74 .. 121
Danke für die Info. Den werde ich mir mal anschauen.
Viele Grüße
Embrio
Embrio schrieb:> Ich programmiere aber keinen Master, sondern versuche einen Slave zu> implementieren. Das habe ich noch vergessen zu erwähnen. Entschuldigung.
Auch kein Problem.
Der Master sendet eine 0 für >=60µs, eine 1 nach dem 1µs 0-Puls für
>=59µs.
Das Bit ist also mindestens 59µs gültig.
Interrupt 1-0 Flanke
Delay 30µs
Bit einlesen.
Peter
Das zeitkritischste Problem besteht, wenn der Slave eine "0" senden
möchte.
Der Master legt zuerst den Bus auf GND. Ein Dallas-Slave legt dann
innerhalb einer µs ebenfalls den Bus auf GND.
Eine Softwarelösung dafür ist schwierig zu erreichen (s.o.).
Da der Master den Bus dabei jedoch für mindestens 6µs auf GND legt und
es ausreicht, wenn ein Busteilnehmer den Bus auf GND legt, muss der
Slave nicht innerhalb einer µs agieren. Der Slave kann sich etwas mehr
Zeit lassen und muss nicht so schnell sein, wie der Dallas-Slave.
Gruß
Joachim
Peter Dannegger schrieb:> Auch kein Problem.> Der Master sendet eine 0 für >=60µs, eine 1 nach dem 1µs 0-Puls für> >=59µs.> Das Bit ist also mindestens 59µs gültig.>> Interrupt 1-0 Flanke> Delay 30µs> Bit einlesen.
Danke für die Hilfe.
Ok, die 59 µs sind ja auch nicht das Problem, sondern den kurzen 1µs
Puls zu detektieren. Ich habe den Pin-Interrupt auf Pinchange gestellt,
also fallende und steigende Flanke.
Da ja die fallende Flanke kommt und direkt hinterher die steigende,
scheint der erste Interrupt noch nicht richtig aufgerufen worden zu
sein, was dann zu Fehlern führt. Kann das sein?
So wie es aussieht, muss ich wohl auf den INT0..2 Interrupt umsteigen
und nur fallende Flanken detektieren und in speziellen Fällen dann die
steigende.
JoachimB schrieb:> Das zeitkritischste Problem besteht, wenn der Slave eine "0" senden> möchte.>> Der Master legt zuerst den Bus auf GND. Ein Dallas-Slave legt dann> innerhalb einer µs ebenfalls den Bus auf GND.> Eine Softwarelösung dafür ist schwierig zu erreichen (s.o.).>> Da der Master den Bus dabei jedoch für mindestens 6µs auf GND legt und> es ausreicht, wenn ein Busteilnehmer den Bus auf GND legt, muss der> Slave nicht innerhalb einer µs agieren. Der Slave kann sich etwas mehr> Zeit lassen und muss nicht so schnell sein, wie der Dallas-Slave.
Was passiert, wenn kein anderer Slave vorhanden ist? Dann müsste ich
hier auch wieder mein oben genanntes Problem haben, vermute ich mal.
Auf jeden Fall danke für die vielen Tipps.
Viele Grüße
Embrio
Hallo Embrio,
nehmen wir mal an, der Bus ist im Ruhezustand (Dauersignal = 1).
Nun kommt eine 1-0 Flanke, die den Interrupt auslöst.
Es gibt nun 3 Möglichkeiten, wie dein signal aussehen könnte.
- Es ist ein "1" bit.
Dann ist der Signalpegel für ca. 15usec auf 0 und für mindestens 45usec
auf 1.
- Es ist ein "0" bit.
Dann ist der Signalpegel für ca. 60usec auf 0 und für mindestens 1usec
auf 1.
- Es ist ein "Reset"
Dann ist der Signalpegel für ca. 480usec auf 0.
Also, wenn der Interrupt kommt, wartet man mal 30usec und polled dann
das 1-wire-bus Signal. Ist es auf high, dann ist das empfangene bit eine
"1". Ist es auf low, wartet man wieder 30usec. Dann polled man wieder.
Ist das Signal nun auf high, dann ist das empfangene bit eine "0". Ist
das Signal nun aber auf low, dann muss das Signal ein "Reset" Signal
sein.
Das setzt natürlich voraus, dass sich der Master an dieses timing hält.
Falls er davon abweicht müssen natürlich die Wartezyklen darauf
angepasst werden.
Wenn nun beim pollen irgendetwas von diesem Schema abweicht, verwirft
man alles, wartet 480usec (minus der bereits empfangenen bit Zeiten
n*60usec) und schaltet den Interrupt wieder scharf.
Viel Erfolg
gatsby
gatsby schrieb:> Also, wenn der Interrupt kommt, wartet man mal 30usec und polled dann> das 1-wire-bus Signal. Ist es auf high, dann ist das empfangene bit eine> "1". Ist es auf low, wartet man wieder 30usec. Dann polled man wieder.> Ist das Signal nun auf high, dann ist das empfangene bit eine "0". Ist> das Signal nun aber auf low, dann muss das Signal ein "Reset" Signal> sein.> Das setzt natürlich voraus, dass sich der Master an dieses timing hält.> Falls er davon abweicht müssen natürlich die Wartezyklen darauf> angepasst werden.> Wenn nun beim pollen irgendetwas von diesem Schema abweicht, verwirft> man alles, wartet 480usec (minus der bereits empfangenen bit Zeiten> n*60usec) und schaltet den Interrupt wieder scharf.
Danke für die Hilfe. Ich werde es mal in Betracht ziehen, wobei ich
keinen Master habe, der bestimmte Timings voraussetzt; soll heißen, es
könnten heute die Standardtimings sein und morgen ein wenig abweichend.
Da muss ich mir dann noch mal was einfallen lassen.
Uwe Bonnes schrieb:> OWI Signale ueber UART auswerten:> http://www.maxim-ic.com/appnotes.cfm/an_pk/214>> Dann ist nichts mehr zeitkritisches im Programmpfad...
Daran habe ich auch schon gedacht. Aber das kann ich mir noch nicht so
ganz vorstellen.
Vielen Dank dafür.
Viele Grüße
Embrio
Embrio schrieb:> Danke für die Hilfe. Ich werde es mal in Betracht ziehen, wobei ich> keinen Master habe, der bestimmte Timings voraussetzt; soll heißen, es> könnten heute die Standardtimings sein und morgen ein wenig abweichend.
Wenn Du nicht an Maxims 1-wire gebunden bist, es gibt noch mehrere
Möglichkeiten, mit einem Draht auszukommen, z.B.:
Beitrag "mehrere MC seriell über Datenbus verbinden (1Draht)"
Der Vorteil ist, daß alles im Hintergrund im Interrupt abgehandelt wird.
Peter
Peter Dannegger schrieb:> Wenn Du nicht an Maxims 1-wire gebunden bist, es gibt noch mehrere> Möglichkeiten, mit einem Draht auszukommen, z.B.:>> Beitrag "mehrere MC seriell über Datenbus verbinden (1Draht)">> Der Vorteil ist, daß alles im Hintergrund im Interrupt abgehandelt wird.
Hey,
danke für die Antwort.
Ich bin leider an den Timings vom Dallas 1-wire gebunden, die können ja
einige Toleranzen haben, was ich bisher so in den Application Notes
gelesen habe.
60-120 µs kann ein Bit lang sein, usw. .
Daher meinte ich ,dass die Variante mit dem Pollen evtl. noch
modifiziert werden muss.
Aber deine Entwicklung habe ich auch schon gesehen, ist leider nur nicht
passend. Vielen Dank!
Viele liebe Grüße
Embrio
Guten Morgen zusammen,
ich habe mich jetzt mal ein wenig mit dem UART beschäftigt und denke,
dass das darüber nicht so einfach möglich ist, zumindest nicht als
Slave.
Würde ich als Slave eine Datenrate einstellen, so dass ein Byte 60 µs
benötigt, könnte ich dann überhaupt einen Reset detektieren? Schließlich
benötigt der UART ja ein Start- und Stopbit.
Wenn also ein Reset anliegt, würde der UART kein Stopp erfassen können,
da die Leitung ja immer noch auf Low liegt oder irre ich mich da? Und
ein Reset kann ja jederzeit auftreten.
Als Master ist die Methode natürlich super, da initiiert man ja selbst
den Reset und das bedeutet, dass man dann die Baudrate umstellen kann,
um diesen Reset zu übertragen.
Aber als Slave sehe ich da ein großes Problem.
Ich hoffe, ich habe da nichts übersehen. Vielleicht kann mir jemand mit
mehr Erfahrung auf die Sprünge helfen. Vielen Dank für eure Hilfe.
Viele Grüße
Embrio
Man könnte als Slave einen ATtiny mit USI nehmen.
Im letzten I2C-Mode wird der SCL-Pin nach der 1-0 Flanke auf low
gehalten, bis das Interruptbit gelöscht wird.
Mit dem USIWMO schaltet man dann um (1 oder 0 senden).
Peter
Hallo Embrio,
wenn du wechselnde Master mit unterschiedlichen timing Verhalten hast,
kannst du folgendes tun.
Wie JoachimB bereits schrieb, ist das Erkennen des "0" bits das
kritische bit.
Beim "1" bit ist das 1-wire Signal nach Ablauf von 30usec bereits auf
high und du kannst davon ausgehen, wenn keine Störungen auf dem bus
sind, dass das Signal für mindestens die nächsten 30usec auf high
bleibt.
Beim "0" bit könnte der Master zu langsam sein und nach Ablauf der
zweiten 30usec das 1-wire Signal noch nicht auf high gelegt haben.
Lösung:
Du wartest nur 20usec und pollst dann das 1-wire Signal. Das sollte nun
auf low sein (bei "0" bit). Nun schickst du den Slave in eine
Zählschleife, die einen Zähler hochzählt und das 1-wire Signal abfragt.
Die Zählschleife wird verlassen, wenn das 1-wire Signal high wird oder
wenn ein maximaler Zählerstand erreicht ist (bis max. 120usec
verstrichen sind). Jetzt wertest du den Zählerstand aus.
Ist der Maximalwert erreicht -- "Reset" erkannt
Ist der Wert kleiner -- "0" bit erkannt
Viel Erfolg
gatsby
Peter Dannegger schrieb:> Man könnte als Slave einen ATtiny mit USI nehmen.>> Im letzten I2C-Mode wird der SCL-Pin nach der 1-0 Flanke auf low> gehalten, bis das Interruptbit gelöscht wird.> Mit dem USIWMO schaltet man dann um (1 oder 0 senden).
Das hört sich sehr gut an. Vielen Dank.
Gibt es USI auch für die ATmega Versionen?
gatsby schrieb:> wenn du wechselnde Master mit unterschiedlichen timing Verhalten hast,> kannst du folgendes tun.> Wie JoachimB bereits schrieb, ist das Erkennen des "0" bits das> kritische bit.>> Beim "1" bit ist das 1-wire Signal nach Ablauf von 30usec bereits auf> high und du kannst davon ausgehen, wenn keine Störungen auf dem bus> sind, dass das Signal für mindestens die nächsten 30usec auf high> bleibt.>> Beim "0" bit könnte der Master zu langsam sein und nach Ablauf der> zweiten 30usec das 1-wire Signal noch nicht auf high gelegt haben.>> Lösung:> Du wartest nur 20usec und pollst dann das 1-wire Signal. Das sollte nun> auf low sein (bei "0" bit). Nun schickst du den Slave in eine> Zählschleife, die einen Zähler hochzählt und das 1-wire Signal abfragt.> Die Zählschleife wird verlassen, wenn das 1-wire Signal high wird oder> wenn ein maximaler Zählerstand erreicht ist (bis max. 120usec> verstrichen sind). Jetzt wertest du den Zählerstand aus.> Ist der Maximalwert erreicht -- "Reset" erkannt> Ist der Wert kleiner -- "0" bit erkannt
Vielen Dank. Auch diese Lösung werde ich weiter verfolgen. So ähnlich
habe ich es mir auch eigentlich vorgestellt.
Nochmals vielen Dank für die ganzen Hilfestellungen
Viele Grüße
Embrio
Embrio schrieb:> Gibt es USI auch für die ATmega Versionen?
Der 1-wire ist ja nicht auf große Datenmengen optimiert. Daher sollte es
ausreichen, wenn der Slave-AVR nur 8 .. 20 Pins hat.
Peter
Peter Dannegger schrieb:> Der 1-wire ist ja nicht auf große Datenmengen optimiert. Daher sollte es> ausreichen, wenn der Slave-AVR nur 8 .. 20 Pins hat.
Danke sehr. Ich entnehme deiner Antwort, dass es für den ATMega keinen
USI gibt. Dann wird wohl der Tiny genügen müssen :-)
Viele Grüße
Embrio