Forum: Compiler & IDEs Port-Pin als en und ausgang


von Roland (Gast)


Lesenswert?

Hallo,
ich habe ein paar Probleme einen einzelnen Pin als eingang und ausgang 
zu benutzen für eine RS485.

#define Rs485_BIT       2        //
#define Rs485_PORT        PORTD     //
#define Rs485_DDR        DDRD      //


DDRD = (1<<Rs485_BIT) ;// als ausgang

PORTD |=  (1 << Rs485_BIT);   //zum Senden auf High schalten

PORTD &= ~(1 <<  Rs485_BIT); //zum Empfang auf Low schalten

Leider klappt dies nicht so,
senden geht aber wenn ich auf empfang schalte gehts nicht nur wenn ich 
den Pin(PD2) mit masse verbinde kann ich auch empfangen

Viellecht kann mir einer helfen.
mfg

von Noname (Gast)


Lesenswert?

Poste mal den Schaltplan und einen minimalen Code für die 
Initialisierung und Senden und Empfangen.

So kann kein Mensch mit Deiner Beschreibung was anfangen.

von Noname (Gast)


Lesenswert?

Einen minimalen, aber kompilierbaren und lauffähigen Code meine ich 
natürlich.

von Pako (Gast)


Lesenswert?

Roland schrieb:
> PORTD &= ~(1 <<  Rs485_BIT); //zum Empfang auf Low schalten

Das kann ja nicht gehen.
Wie soll der arme RS485-Transceiver da ein "high" drauflegen, ohne dass 
es zum Kurzschluß kommt?
Zum Empfang mußt Du zumindest den Pin auf Eingang (hochohmig) schalten:
1
DDRD &= ~(1<<Rs485_BIT) ;// als Eingang

von Roland (Gast)


Lesenswert?

Hallo,
Hab ich das jetzt richtig so gemacht mit der Umschaltung zwischen Senden 
und empfang.
Vielleicht kann mir noch einer weiterhelfen
mfg

1
unsigned char c;
2
unsigned char c1;
3
4
5
//mainloop:
6
 for (;;)
7
 {
8
  
9
  //Auf Empfang schalten
10
  DDRD &= ~(1<<PD2); //PD2 auf 0 -> als Eingang    
11
  PORTD &= ~(1<<PD2);    
12
  
13
  c = uart_getchar();                      //Hole Daten vom UART ab
14
15
   if (c==0xA0)                       
16
   {
17
     c1=uart_getchar();
18
     if (c1==41)          // Stimt die Geräte adresse
19
      {
20
       OCR2=uart_getchar();
21
      }   
22
   }
23
24
  //Auf Senden Umschalten
25
  DDRD |=  (1<<PD2); //PD2 auf 1 -> als Ausgang   
26
  PORTD |=  (1<<PD2);
27
28
  uart_putc(41);
29
 }

von Roland (Gast)


Lesenswert?

hallo,
kann mir denn keiner weiterhelfen
mfg

von Stefan E. (sternst)


Lesenswert?

Wieso soll überhaupt dieser ominöse Pin beim Empfangen ein Eingang sein?
Ist das nicht einfach nur der Steuer-Pin für den RS485-Transceiver?

von Roland (Gast)


Lesenswert?

zum Empfang muss doch der pin auf GND Geschaltet werden und zum senden 
dann wieder auf high, aber irgendwie haut das alles nicht hin.
mfg

von STK500-Besitzer (Gast)


Lesenswert?

Roland schrieb:
> zum Empfang muss doch der pin auf GND Geschaltet werden und zum senden
> dann wieder auf high, aber irgendwie haut das alles nicht hin.
> mfg

Zeig mal deinen Schaltplan!

von Klaus Dieter (Gast)


Lesenswert?

Was soll der denn empfangen wenn der Pin auf GND liegt? Mal darüber 
nachgedacht, dass das nicht funktionieren kann?

von Stefan E. (sternst)


Lesenswert?

Roland schrieb:
> zum Empfang muss doch der pin auf GND Geschaltet werden und zum senden
> dann wieder auf high,

Du kannst den Pin aber nicht auf GND schalten, wenn er ein Eingang ist. 
Also den Pin einmal vor der Schleife auf Ausgang schalten, und in der 
Schleife dann zwischen High und Low umschalten.

Pako schrieb:
> Das kann ja nicht gehen.
> Wie soll der arme RS485-Transceiver da ein "high" drauflegen, ohne dass
> es zum Kurzschluß kommt?
> Zum Empfang mußt Du zumindest den Pin auf Eingang (hochohmig) schalten:
Klaus Dieter schrieb:
> Was soll der denn empfangen wenn der Pin auf GND liegt? Mal darüber
> nachgedacht, dass das nicht funktionieren kann?

Mann Leute, das ist der Steuer-Pin, der die Datenrichtung des 
Transceivers umschaltet, nicht irgendein Daten-Pin.

von Roland (Gast)


Lesenswert?

So es geht immer noch nicht,
Beim Master schalte ich auf senden also den pin auf High, nachdem ich 
alles gesendet hab warte ich eine kleine weile und schalte den SteuerPin 
wieder aus,der Slave empfängt auch
Das was gesendet wird.
Nun sollte der Slave etwas zurück senden,Der Master ist ja jetzt wieder 
auf empfang aber es kommt nixx an.
Muss ich denn beim Master den TX-Pin abschalten um etwas zuempfangen.
Interrupst zum senden und empfang werden nicht benutzt.
Kabellänge von master zu slave 10cm.
Vielleicht könnte mir von ihnen jemand ein wenig weiterhelfen.
Mfg

von Stefan E. (sternst)


Lesenswert?

Roland schrieb:
> Beim Master schalte ich auf senden also den pin auf High, nachdem ich
> alles gesendet hab warte ich eine kleine weile und schalte den SteuerPin
> wieder aus,

Eine feste Wartezeit ist schon mal eine schlechte Idee, denn ...

Roland schrieb:
> Muss ich denn beim Master den TX-Pin abschalten um etwas zuempfangen.

Ja, solange der Transceiver auf Senden steht, kann du nichts von der 
Gegenstelle empfangen.

Du musst auf beiden Seiten mit dem Umschalten von Senden auf Empfangen 
genau so lange warten, bis alles "raus" ist. Dazu das TXC-Flag 
verwenden.

Und nach dem Umschalten auf Senden würde ich mit dem tatsächlichen 
Senden etwas warten, denn manche Transceiver brauchen ein bisschen Zeit 
für das Umschalten.

von Roland (Gast)


Lesenswert?

Ich meinte das anders,
Zum senden auf High und zum empfang auf Low den steuerpin schalten.
Muss ich den TX-pin beim atmega8 abschalten zum empfang,(wenn der 
Sendevorgang abgeschlossen ist  kommt da ja nix mehr).
Das wollte ich ja bloß wissen.
Wiegesagt der Slave empängt auch das was vom Master gesendet wird,aber 
ich kann halt vom Slave nix zum Master senden.
Mfg

von Stefan E. (sternst)


Lesenswert?

Roland schrieb:
> Muss ich den TX-pin beim atmega8 abschalten zum empfang,(wenn der
> Sendevorgang abgeschlossen ist  kommt da ja nix mehr).

Nein.

Roland schrieb:
> Wiegesagt der Slave empängt auch das was vom Master gesendet wird,aber
> ich kann halt vom Slave nix zum Master senden.

Aus zweierlei Gründen:

1) Wenn der Master eine feste Wartezeit nach dem Senden hat, bevor er 
auf Empfangen umschaltet, woher weißt du dann, dass dieses Umschalten 
bereits stattgefunden hat, wenn der Slave versucht zu senden?

2) Der Slave wartet nach dem Initiieren des Senden nicht mit dem 
Umschalten, und würgt damit sein eigenes Senden mitten drin ab.

von Peter D. (peda)


Lesenswert?

Roland schrieb:
> ich habe ein paar Probleme einen einzelnen Pin als eingang und ausgang
> zu benutzen für eine RS485.

Kein Wunder, Du brauchst ja auch 3 Pins: RXD, TXD, Senden enable.
Die gehen dann zum MAX485: RO, DI, DE.
/RE legt man auf GND, dann kann man beim Senden mithören und Kollisionen 
feststellen.


Peter

von Peter D. (peda)


Lesenswert?

Stefan Ernst schrieb:
> Und nach dem Umschalten auf Senden würde ich mit dem tatsächlichen
> Senden etwas warten, denn manche Transceiver brauchen ein bisschen Zeit
> für das Umschalten.

Oftmals gibt es ein Kommando, wo der Master für den Slave die minimale 
Wartezeit einstellen kann.
Und für eine maximale Zeit, wonach er nicht mehr antworten darf.


Peter

von Roland (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe mal mein code im Anhang und ein Schltbild wie ichs 
Angeschlossen hab.
vielleicht kann mir einer von ihnen noch weiterhelfen
mfg

von Stefan E. (sternst)


Lesenswert?

In dem gezeigten Code ist gar kein Warten zu sehen, auch nicht das von 
dir oben erwähnte
> nachdem ich
> alles gesendet hab warte ich eine kleine weile und schalte den SteuerPin
> wieder aus,

Roland schrieb:
> vielleicht kann mir einer von ihnen noch weiterhelfen

Eigentlich habe ich längst geschrieben, woran es hapert und was du 
machen musst, aber irgendwie ist das bei dir auf taube Ohren gestoßen.

von Roland (Gast)


Angehängte Dateien:

Lesenswert?

>Eigentlich habe ich längst geschrieben, woran es hapert und was du
>machen musst, aber irgendwie ist das bei dir auf taube Ohren gestoßen.
nein taube ohren hab ich nicht, ich weiss nur nicht wie ich das 
bewerkstelligen muss.


Im Anhang die korregierte Version bei der in setTransmitMode(); gewartet 
wird bevor gesendet wird.



>Eigentlich habe ich längst geschrieben, woran es hapert und was du
>machen musst, aber irgendwie ist das bei dir auf taube Ohren gestoßen.

>2) Der Slave wartet nach dem Initiieren des Senden nicht mit dem
>Umschalten, und würgt damit sein eigenes Senden mitten drin ab.
das versteh ich nicht ganz

ich warte ja hier bies das senden möglich ist,
           while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
           {
           }
            setTransmitMode();
            uart_putc(0xB0);
            setReceiveMode();
aber nachdem der Uart gesndet hat wird doch erst wieder in den 
Empfangsmode zurück geschaltet.
Da ist doch das senden längst abgeschlossen.

von Roland (Gast)


Lesenswert?

Schreube ich das so im slave wird alles korrekt gesendet

//mainloop:
 for (;;)
 {
            setTransmitMode();
            uart_putc(0xB0);
            setReceiveMode();
 }
}

von Stefan E. (sternst)


Lesenswert?

Roland schrieb:
> aber nachdem der Uart gesndet hat wird doch erst wieder in den
> Empfangsmode zurück geschaltet.
> Da ist doch das senden längst abgeschlossen.

Nein, ist es nicht. Wenn du etwas nach UDR schreibst, wird damit das 
Senden eingeleitet, aber der Prozessor wartet nicht von alleine solange, 
bis das Senden fertig ist. Das Senden ist also immer noch im Gange wenn 
der weitere Code (und damit auch das Umschalten in den Empfangsmodus) 
ausgeführt wird.

von Stefan E. (sternst)


Lesenswert?

Roland schrieb:
> Schreube ich das so im slave wird alles korrekt gesendet

Eher durch Zufall, nämlich weil du nach dem Umschalten in den 
Empfangsmodus gleich wieder in den Sendemodus schaltest.

von Roland (Gast)


Lesenswert?

Leider klappt dies auch so nicht:(



//mainloop:
 for (;;)
 {
   c = uart_getc();                      //Hole Daten vom UART ab

    if (c==0xA0)                      //
    {
     setTransmitMode();
     uart_putc(0xB0);
     while ( !( UCSRA & (1<<TXC)) ); // Warten bis das letze draußen ist
     setReceiveMode();
    }

 }
}

von Stefan E. (sternst)


Lesenswert?

Drei Sachen:

1) Du musst das Flag auch löschen, also:
UDR beschreiben
TXC löschen
Warten bis TXC gesetzt

2) Du musst im Datenblatt des von dir verwendenden Transceivers
nachschauen, wie schnell er überhaupt Umschalten kann.

3) Wenn du mit dem Umschalten und Senden sofort nach dem Empfangen
loslegst, wie kannst du dann sicher sein, dass die Gegenseite ihrerseits
mit dem Umschalten bereits fertig ist (und damit empfangsbereit ist)?

von Roland (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Drei Sachen:
>
> 1) Du musst das Flag auch löschen, also:
> UDR beschreiben
> TXC löschen
> Warten bis TXC gesetzt
>

Vielen vielen Dank und Gedult jetzt geht es einwandfrei.
Danke nochmals
mfg

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.