Hallo, vor ein paar Tagen wurde das Thema schon mal behandelt, die Situation war dabei allerdings etwas anders. Meine zwei Ansätze: - Hardware: RX direkt am One-Wire Bus, TX über 1k-Widerstand auf den Bus Software: + Empfangen wird wie sonst auch + Gesendet wird eigentlich auch normal, nur muss das gesendete Byte gleich danach aus UDR ausgelesen werden (weil ja RX und TX verbunden sind) Man könnte auch den Receiver vor dem Senden abschalten und nach erfolgreichen Sendevorgang (über Polling oder Interrupt) wieder aktivieren. - Hardware: RX und TX direkt verbinden Software: + Empfangen wird wie sonst auch + Der Transmitter muss hier deaktiviert werden, wenn er nicht gebraucht wird (als Eingang). Vor dem Senden wird er wieder aktiviert, nach erfolgreichem Sendevorgang wieder deaktiviert. Hier nach dem Senden entweder vorher den Receiver deaktivieren und dann wieder aktivieren, oder UDR nach dem Senden gleich auslesen. Was haltet ihr davon, bzw. wie würdet ihr das realisieren? MfG Fabian
Wenn du TXD und RXD nicht über z.B. Dioden entkoppelst, bleibt dir nur der 2. Ansatz, denn des Freigeben des Sendeteil überschreibt die Portfunktion und macht TXD zwangsweise zu einem Ausgang. Zitat aus dem ATMega8 Datenblatt: > When the Transmitter is enabled, the normal port operation of the TxD pin > is overridden by the USART and given the function as the Transmitter’s > serial output. Ein empfangenes Signal würde also mit dem TXD Ausgang kollidieren, der bei inaktivem Sender auf high ist. Wenn du die Aktivierung/Deaktivierung des Senders vermeiden willst, wäre ein möglicher Ansatz, beide RXD Leitungen fast zu verbinden (sind ja immer Eingänge) und die TXDs über Dioden mit auf den 1-wire zu legen. RXD A RXD B O------+---------+----O | | -- -- TXD A \/ \/ | | TXD B O------- -----O
Matthias Sch. schrieb: > Wenn du TXD und RXD nicht über z.B. Dioden entkoppelst, bleibt dir nur > der 2. Ansatz, denn des Freigeben des Sendeteil überschreibt die > Portfunktion und macht TXD zwangsweise zu einem Ausgang. Zitat aus dem > ATMega8 Datenblatt: >> When the Transmitter is enabled, the normal port operation of the TxD pin >> is overridden by the USART and given the function as the Transmitter’s >> serial output. > Ein empfangenes Signal würde also mit dem TXD Ausgang kollidieren, der > bei inaktivem Sender auf high ist. Wirkt der Widerstand am Transmitter im inaktiven Zustand nicht einfach als Pull-Up? > Wenn du die Aktivierung/Deaktivierung des Senders vermeiden willst, wäre > ein möglicher Ansatz, beide RXD Leitungen fast zu verbinden (sind ja > immer Eingänge) und die TXDs über Dioden mit auf den 1-wire zu legen. > > RXD A RXD B > O------+---------+----O > | | > -- -- > TXD A \/ \/ > | | TXD B > O------- -----O Mal angenommen ich realisiere das Ganze mit dem zweiten Ansatz. Ich deaktiviere den Receiver / aktiviere den Transmitter vor jedem Sendevorgang und deaktiviere den Transmitter / aktiviere den Receiver nach erfolgreichem Sendevorgang wieder. Der Transmitter kann dabei direkt nach dem Laden des UDR-Registers deaktiviert werden (TXEN=0), da laut Datenblatt erst nach dem Abschluss des Sendevorgangs Änderungen vom TXEN-Bit berücksichtigt werden. (The disabling of the Transmitter (setting the TXEN to zero) will not become effective until ongoing and pending transmissions are completed, i.e., when the Transmit Shift Register and Transmit Buffer Register do not contain data to be transmitted.) Kann es zu Empfangsproblemen kommen (zu langsam), wenn ich jedesmal den Receiver wieder neu aktiviere (das Aktivieren wird wohl kaum nur drei Taktzyklen brauchen / ldi+sts)?
> Wirkt der Widerstand am Transmitter im inaktiven > Zustand nicht einfach als Pull-Up? Bei ATTiny und ATmega kannst Du Transmitter und Receiver vom UART nicht unabhängig voneinander deaktivieren. Aber wenn Du nicht den integrierten UART verwendest, sondern ihn per Software implementierst, dann hast Du volle Kontrolle über die einzelnen Pins. Bei Xmega Controllern ist der Ausgang separat aktivierbar und standardmäßig inaktiv, soweit ich mich erinnere.
Stefan Frings schrieb: > Bei ATTiny und ATmega kannst Du Transmitter und Receiver vom UART nicht > unabhängig voneinander deaktivieren. So, so, dann wurde RXEN und TXEN von Atmel also nur zum Spaß vorgesehen...
kannst auch den RX ISR dazu nutzen um eine collision zu erkennen ist das gesendete byte == dem empfangene war alles schön und nächstes byte ins UDR ist das empfangene byte != gesendete -- timer setzen zurück zum anfang und erstmal gucken was passiert zum senden brauchst du nur den RX ISR + ein byte zum start senden die senderoutine sendet genau 1 byte .. der rest läuft automatisch ab wenn der buss defekt sein sollte erkennst du das sogar mit .. weil nix emopfangen wird
Fabian K. schrieb: > - Hardware: RX und TX direkt verbinden > Software: + Empfangen wird wie sonst auch > + Der Transmitter muss hier deaktiviert werden, wenn er > nicht gebraucht wird (als Eingang). Vor dem Senden wird er > wieder aktiviert, nach erfolgreichem Sendevorgang wieder > deaktiviert. Genau so habe ich es gemacht. Ich habe sogar den RX während der TX-Phase ausgeschaltet, weil ich das lokale Echo nicht immer rausklauben wollte. Transmitter deaktiveren war etwas trickreich: Pollen von TXC0 in UCSR0A hat nicht richtig geklappt. Habe dann einen IRQ-Handler für USART_TX_vect aufgesetzt, der TX aus und RX einschaltet. Servus Michael
Michael M. schrieb: > Pollen von TXC0 in UCSR0A > hat nicht richtig geklappt. Obwohl das sehr gut klappt - zumindest in unseren Projekten ;-)
Michael M. schrieb: > Habe dann einen IRQ-Handler für > USART_TX_vect aufgesetzt, der TX aus und RX einschaltet. Das kann u.U. schon zu spät sein, wenn der "Slave" unmittelbar und mit hoher Baudrate antwortet. Ehe der Interrupt-Service angesprungen ist, vergehen erstmal 6 Clocks und dann sichert die Service Routine auch erst ein paar Register, bevor Du dann mit Deinem Receiver aktivieren dran bist. Kommt aber auf den Anwendungszweck an. Oder man muss den Slave halt bewusst bremsen.
> So, so, dann wurde RXEN und TXEN von Atmel also nur zum Spaß vorgesehen...
Oh ja, Du hast Recht. Im Datenblatt steht klar drin, dass die normale
Funktion des I/O Pins bei TXEN=0 nicht überschrieben wird.
Der Unterschied zwischen ATmega und Xmega besteht wohl darin, dass man
den Pin beim Xmega als Ausgang konfigurieren muss, auch wenn der
Transmitter schon enabled ist. Beim ATmega spielt das DDR Bit keine
Rolle, wenn TXEN=1 ist.
Na dann steht der Urpsrünglichen Idee des TO ja eigentlich nichts im
Wege, außer eventuell sein Programm-Design.
Danke für die vielen Vorschläge. Ich werds dann wohl so realisieren: Hardware: Rx und Tx direkt verbinden Software: Der Receiver bleibt immer aktiv (damit es sicher keine zeitlichen Probleme gibt). Den Transmitter aktiviere ich vor dem Senden und deaktiviere ihn nach dem Sendevorgang wieder (ist ja ziemlich zeit-unkritisch, außer der Empfänger hat einen Timer für ein Timeout laufen). Die Idee für eine mögliche Kollisionserkennung von gfhf werde ich auch noch in die Rx-ISR packen. Noch ein Auszug aus dem Datenblatt (Atmega168PA / S.181): > The disabling of the Transmitter (setting the TXEN to zero) will not > become effective until ongoing and pending transmissions are completed, > i.e., when the Transmit Shift Register and Transmit Buffer Register do > not contain data to be transmitted. When disabled, the Transmitter will > no longer override the TxDn pin. Mein Englisch ist nicht schlecht, also so versteh ich das: Ich kann den Transmitter direkt nach dem Laden des UDR-Registers wieder deaktivieren (TXEN-Bit löschen), da eine Änderung des TXEN-Bit erst nach dem Abschluss des aktuellen Sendevorgangs wirksam wird. So könnte ich mir auch noch eine eigene ISR bzw. das Polling des TXC-Bit für den Transmitter sparen?
Fabian K. schrieb: > So könnte ich mir auch noch eine eigene ISR bzw. das Polling des TXC-Bit > für den Transmitter sparen? Theoretisch ja, praktisch würde ich immer schauen, ob der Transmitter aktiv ist, bvor du TXEN abschaltest, damit ein evtl. noch folgender Sendevorgang nicht abgebrochen wird. Allerdings erscheint mir der TXC Interrupt als der richtige Platz fürs Abschalten, ich bin allerdings auch ein Fan von ISR. Die Diodenlösung halte ich dann für praktisch, wenn man gleichzeitg den Zustand der Leitungen prüfen möchte und einfach gar nicht Abschalten möchte. Ein z.B. Kurzschluss auf der Leitung würde eben jedem Sender sofort auffallen, wenn kein Echo kommt.
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.