Moin Leute, ich habe die Schaltung im Anhang hier aus dem Forum übernommen da ich je nach Bestückung RS232 oder RS485 kommunizieren will. Der RS232 Teil funktioniert wie er soll (D7 gebrückt, ohne R17). Jetzt wollte ich mal den RS485 Teil auf einer anderen Platine testen, das heißt der ganze RS232 Teil ist nicht bestückt genauso wie R17 und D6 da ich vorerst nur senden will. Wie muss der Pegel an der Transmit Leitung sein damit ich senden kann? Sollte die Schaltung denn so funktionieren? Der 75176 ist ein wenig warm. Grüße Christian
Hey, sorry für das Bild auf dem Kopf, kommt nicht wieder vor, ja Masseverbidung ist vorhanden. Die Transmitleitung wird aber noch nicht angesteuert, was muss diese denn für einen Pegel haben wenn ich etwas senden will?
Mein nicht vorhandenes Datenblatt des 75176 sagt die Leitung muß auf high liegen. Etwas warm werden die 176 immer, sie verbrauchen auch gut Strom.
Klopp den 75176 in die Tonne. Der verbrennt 40mA ohne etwas dafuer zu tun. Modernere Chips laufen mit zB 0.4mA.
Stefan schrieb: > spess53 schrieb: >> Hi >> >> Masseverbindung zur Gegenstelle vorhanden? >> >> MfG Spess > > wozu? Damit das Differenzsignal innerhalb des Arbeitsbereiches liegt. Kurt
Kurt B. schrieb: > Damit das Differenzsignal innerhalb des Arbeitsbereiches liegt. > > Kurt Inwiefern hat das Differenzsignal zwischen A und B einen Bezug zur Masse, solange ich mir meine saubere differentielle Übertragung nicht durch den meistens überflüssigen Bias versaue. Stefan
Hi >Inwiefern hat das Differenzsignal zwischen A und B einen Bezug zur >Masse, solange ich mir meine saubere differentielle Übertragung nicht >durch den meistens überflüssigen Bias versaue. Lies dir das https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCQQFjAAahUKEwiOjuqet7jHAhUFPxoKHd0AC_A&url=http%3A%2F%2Fwww.ti.com%2Flit%2Fan%2Fsnla049b%2Fsnla049b.pdf&ei=Vy_WVc6GBYX-aN2BrIAP&usg=AFQjCNFP1T__GMeEkt8jhZLIrR7nFkPXBw mal durch. MfG Spess
So ich melde mich denn mal zurück. Ich habe nun den Schaltplan so umgesetzt bis auf D6. Ist die Diode denn notwendig wenn rein RS232 Receiver verbaut ist? Der Sender sendet nun auch was er soll aber er bekommt was er gesendet hat auch direkt wieder zurück. Da ich einen Atmega162 verwende mit 2 UARTS hab ich in der UART0 Empfangsroutine folgendes stehen:
1 | ISR(USART0_RXC_vect) |
2 | {
|
3 | uint8_t dummy; |
4 | dummy = UDR0; |
5 | UART1_Transmit(dummy); |
6 | }
|
Das heißt alles was an UART0 ankommt wird parallel an UART1 ausgegeben. Und nun bekomme ich im gleichen Moment das zurück was UART0 sendet. Das ist doch nicht normal oder? Weiterhin kann ich nicht empfangen über RS485 liegt das an der fehlenden Diode und R17? Grüße Christian
Chris T. schrieb: > Der Sender sendet nun auch was er soll aber er bekommt was er gesendet > hat auch direkt wieder zurück. Der Empfangsteil des 75176 ist ja auch die ganze Zeit aktiv und liest das zurück, was du auf's Kabel gibst. Wenn du das verhindern möchtest, musst du das TRANSMIT Signal auch an Pin 2 (Rx Enable) des 75176 anschließen -- bei high wird dann der Empfänger abgeschaltet. Das Signal darf erst wieder low werden, wenn das letzte Bit gesendet ist. Sebastian
:
Bearbeitet durch User
Danke für die Ausführung, jetzt weis ich damit schon mal bescheid. Mache Grand meine ersten Gehversuche mit RS485 auf Hardwarelevel.(Sonst war immer ein Konverter dazwischen) Gibt's denn noch Anmerkungen dazu das ich nichts empfangen kann? Woran könnte das liegen? Edit: ICh empfange schon "etwas" aber das hat nicht viel mit den gesendeten Bytes zu tun, manchmal FF, FE, FD ... Sollte ich mal R17 entfernen?
:
Bearbeitet durch User
Wenn du nur RS485 bestückt hast, kannst du Pin 1 vom 75176 direkt mit dem AVR verbinden, D6 wird also überbrückt und kann entfallen. Ich nehme an, das meinst du? Ob R17 vorhanden ist oder nicht sollte dann keine Rolle spielen.
Bitte nicht übel nehmen, aber kann es sein das dir noch nicht bewußt ist das der RS485 so wie im Schaltplan dargestellt eine sogenannte halbduplex Verbindung darstellt. Das bedeutet es kann immer nur eine Sation geben die sendet und alle anderen haben geälligst nicht zu senden. (So wie früher, in der vor Handy zeit beim Funk) Das bedeutet wenn du mit dem Senden fertig bist (und das Letzte Bit die UART verlassen hat) muss die TRANSMIT Leitung wieder auf null gesetzt werden. Wenn mehrere Teilnehmer gleichzeitig den TRANSMIT auf 1 haben geht müll über die Leitung, und der wird auch prompt als solcher empfangen. Ist jetzt einfach mal eine Vermutung weil du sagst RS485 ist für die was neues auf dieser Ebene. Viele Adapter machen das automatisch. Udo
Sind A und B am 75176 richt herum angeschlossen? Sonst geht's auch nicht. Hast du ein Oszilloskop? Ich würde TRANSMIT zum Testen fest auf 0 legen, von einem anderen RS485-Gerät Daten senden und mit dem Oszi die Rx Leitung am 75176 anschauen. Da muessten dann gueltige UART-Frames zu sehen sein. Sebastian
:
Bearbeitet durch User
Hm ich hab jetzt mal die Transmitleitung gemessen, die ist immer high obwohl ich Sie eigentlich auf Low schalte. Jetzt zweifle ich aber auch die anderen Pins auf den Port bleiben high obwohl ich die auf low setze:
1 | DDRC = 0xFF; |
2 | PORTC &= ~(1<<PC4); |
3 | PORTC &= ~(1<<PC5); |
Alle Pins auf Ausgang und Pin4 und 5 auf low... Edit: PIN3 kann ich schalten, 4 und 5 nicht, wird wohl am Prozessor liegen. Ich nehm mal ein anderen Pin für Transmit.
:
Bearbeitet durch User
BINGO, Sebastian, ich hab zwar die Pinbelegung vor mir aber hab nicht auf die alternativen Funktionen der Pins geachtet, man o man, Datenblatt lesen... Also ich kann abwechselnd senden und empfangen aber nur wenn ich den Code ändere, wie lange vor dem Senden muss der Transmit Pin denn high sein? Mit folgendem Code kann ich nur empfangen:
1 | #define TR_DDR DDRC
|
2 | #define TR_PORT PORTC
|
3 | #define TR_PIN 3
|
4 | |
5 | |
6 | int main(void) |
7 | {
|
8 | LED_DDR |= (1<<DDA0); |
9 | LED_DDR |= (1<<DDA1); |
10 | TR_DDR |= (1<<DDC3); |
11 | TR_PORT |= (1<<TR_PIN); |
12 | //Timer konfigurieren
|
13 | //stetige Wertanforderung
|
14 | TCCR1B |= (1<<CS12) | (1<<CS10); // standard = 9 Sekunden |
15 | TCNT1 = 0; //29536; = 5 Sekunden |
16 | |
17 | |
18 | LED_PORT |= (1<<LED1); |
19 | //USART initialisieren
|
20 | |
21 | //USART0
|
22 | UBRR0H = UBRR_VAL_ROTEL >> 8; |
23 | UBRR0L = UBRR_VAL_ROTEL & 0xFF; |
24 | //USART1
|
25 | UBRR1H = UBRR_VAL_KNX >> 8; |
26 | UBRR1L = UBRR_VAL_KNX & 0xFF; |
27 | //USART0
|
28 | UCSR0B |= (1<<TXEN0); // UART TX einschalten |
29 | UCSR0B |= (1<<RXEN0); |
30 | UCSR0B |= (1<<RXCIE0); |
31 | UCSR0C |= (1<<URSEL0)|(1<<UCSZ00)| (1<<UCSZ01); // Asynchron 8N1 |
32 | |
33 | //USART1
|
34 | |
35 | UCSR1B |= (1<<TXEN1); // UART TX einschalten |
36 | UCSR1B |= (1<<RXEN1); |
37 | UCSR1B |= (1<<RXCIE1); |
38 | UCSR1C |= (1<<URSEL1)|(1<<UCSZ10)| (1<<UCSZ11); // Asynchron 8N1 |
39 | USART_Transmit('A'); |
40 | UART1_Transmit('A'); |
41 | |
42 | |
43 | sei(); //activate Interrupts |
44 | TIMSK |= (1<<TOIE1); |
45 | while(1) |
46 | {
|
47 | if(wert_anfordern == 1) //Wertanforderung |
48 | {
|
49 | TR_PORT |= (1<<TR_PIN); |
50 | USART_Transmit('B'); |
51 | USART_Transmit('C'); |
52 | UART1_Transmit('K'); |
53 | wert_anfordern = 0; |
54 | TR_PORT &= ~(1<<TR_PIN); |
55 | }
|
56 | }
|
57 | }
|
Wenn ich TR_PORT &= ~(1<<TR_PIN); auskommentiere dann wird gesendet aber ich kann natürlich nicht mehr empfangen.
:
Bearbeitet durch User
Die Zeit zwischen TRANSMIT high und Senden steht im Datenblatt des 75176, ist auf jeden Fall weniger als 100 ns. Ich denke nicht, dass das hier ein Problem ist. Dein Code ist nicht vollständig. Wo kommt wert_anfordern her? Wann wird es gesetzt? Wass willst du überhaupt erreichen? Was für Geräte hängen am Bus? Wer sendet wann? Siehe Antwort von Udo oben, du musst dir den genauen Ablauf überlegen, wann gesendet und wann Empfangen werden soll. Aus dem Code lässt sich das nicht erkennen, weil der Empfangsteil fehlt. Sebastian
So hier mal der ganze Code: Ich will erstmal nur langsam an den Bus heran. Der atmega senden ca. alle 10 Sekunden ein paar Bytes, zwischen dieser Zeit sollte ich ja auch antworten dürfen. Später gibt es nur einen Master der den Slave zum Daten senden auffordert.
1 | #ifndef F_CPU //define F_CPU if not done
|
2 | #define F_CPU 7372800UL
|
3 | #endif
|
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/interrupt.h> |
7 | #include <util/delay.h> |
8 | #include <stdlib.h> |
9 | #include <string.h> |
10 | |
11 | //#include "lcd-routines.h"
|
12 | |
13 | /* 9600 baud KNX */
|
14 | #define BAUD1 9600UL // Baudrate
|
15 | #define UBRR_VAL_KNX ((F_CPU+BAUD1*8)/(BAUD1*16)-1) // clever runden
|
16 | /* 19200 baud Kessel */
|
17 | #define BAUD2 1200UL // Baudrate
|
18 | #define UBRR_VAL_ROTEL ((F_CPU+BAUD2*8)/(BAUD2*16)-1) // clever runden
|
19 | |
20 | #define LED_DDR DDRA
|
21 | #define LED_PORT PORTA
|
22 | #define TR_DDR DDRC
|
23 | #define TR_PORT PORTC
|
24 | #define TR_PIN 3
|
25 | |
26 | #define LED1 0
|
27 | #define LED2 1
|
28 | //#define TRANSMIT_ON PORTC |= (1<<PC3)
|
29 | //#define TRANSMIT_OFF PORTC &= ~(1<<PC3)
|
30 | //Statusdefinition
|
31 | |
32 | #define INIT 0
|
33 | #define READY 1
|
34 | |
35 | //Variablen
|
36 | volatile uint8_t PTX; //Global Variable |
37 | char itoabuffer[20]; |
38 | volatile uint8_t receive_string[20]; |
39 | volatile uint8_t wert_anfordern = 0; |
40 | |
41 | void USART_Transmit( char data ) |
42 | {
|
43 | /* Wait for empty transmit buffer */
|
44 | while ( !( UCSR0A & (1<<UDRE0)) ) |
45 | ;
|
46 | /* Put data into buffer, sends the data */
|
47 | |
48 | UDR0 = data; |
49 | }
|
50 | |
51 | void UART1_Transmit( char data ) |
52 | {
|
53 | /* Wait for empty transmit buffer */
|
54 | while ( !( UCSR1A & (1<<UDRE1)) ) |
55 | ;
|
56 | /* Put data into buffer, sends the data */
|
57 | UDR1 = data; |
58 | }
|
59 | |
60 | ISR(USART0_RXC_vect) |
61 | {
|
62 | uint8_t dummy; |
63 | dummy = UDR0; |
64 | UART1_Transmit(dummy); |
65 | }
|
66 | |
67 | ISR(USART1_RXC_vect) |
68 | {
|
69 | uint8_t i = 0; |
70 | uint8_t dummy; |
71 | dummy = UDR1; |
72 | }
|
73 | ISR(TIMER0_OVF_vect) |
74 | {
|
75 | |
76 | }
|
77 | ISR(TIMER1_OVF_vect) |
78 | {
|
79 | wert_anfordern = 1; |
80 | |
81 | //receive_complete = 0;
|
82 | |
83 | }
|
84 | |
85 | int main(void) |
86 | {
|
87 | LED_DDR |= (1<<DDA0); |
88 | LED_DDR |= (1<<DDA1); |
89 | TR_DDR |= (1<<DDC3); |
90 | TR_PORT |= (1<<TR_PIN); |
91 | //Timer konfigurieren
|
92 | //stetige Wertanforderung
|
93 | TCCR1B |= (1<<CS12) | (1<<CS10); // standard = 9 Sekunden |
94 | TCNT1 = 0; //29536; = 5 Sekunden |
95 | |
96 | //Timer für senden von Dimmtelegrammen ein Durchlauf ist 0,010s
|
97 | TCCR0 |= (1<<CS02) | (1<<CS00); |
98 | |
99 | TCNT0 = 184; // |
100 | LED_PORT |= (1<<LED1); |
101 | //USART initialisieren
|
102 | |
103 | //USART0
|
104 | UBRR0H = UBRR_VAL_ROTEL >> 8; |
105 | UBRR0L = UBRR_VAL_ROTEL & 0xFF; |
106 | //USART1
|
107 | UBRR1H = UBRR_VAL_KNX >> 8; |
108 | UBRR1L = UBRR_VAL_KNX & 0xFF; |
109 | //USART0
|
110 | UCSR0B |= (1<<TXEN0); // UART TX einschalten |
111 | UCSR0B |= (1<<RXEN0); |
112 | UCSR0B |= (1<<RXCIE0); |
113 | UCSR0C |= (1<<URSEL0)|(1<<UCSZ00)| (1<<UCSZ01); // Asynchron 8N1 |
114 | |
115 | //USART1
|
116 | |
117 | UCSR1B |= (1<<TXEN1); // UART TX einschalten |
118 | UCSR1B |= (1<<RXEN1); |
119 | UCSR1B |= (1<<RXCIE1); |
120 | UCSR1C |= (1<<URSEL1)|(1<<UCSZ10)| (1<<UCSZ11); // Asynchron 8N1 |
121 | USART_Transmit('A'); |
122 | UART1_Transmit('A'); |
123 | |
124 | |
125 | sei(); //activate Interrupts |
126 | TIMSK |= (1<<TOIE1); |
127 | while(1) |
128 | {
|
129 | if(wert_anfordern == 1) //Wertanforderung |
130 | {
|
131 | TR_PORT |= (1<<TR_PIN); |
132 | USART_Transmit('B'); |
133 | USART_Transmit('C'); |
134 | UART1_Transmit('K'); |
135 | wert_anfordern = 0; |
136 | TR_PORT &= ~(1<<TR_PIN); |
137 | }
|
138 | }
|
139 | }
|
UART1_Transmit() wartet bis der Sendepuffer leer ist (Flag UDRE), schreibt dann ein neues Byte in den Sendepuffer und kehrt sofort zurück. Im Hintergrund schickt der UART nun langsam ein Bit nach dem anderen auf die Reise... während dein Programm parallel weiter läuft! Wenn du also sowas schreibst...
1 | UART1_Transmit('K'); |
2 | TR_PORT &= ~(1<<TR_PIN); |
...wird TRANSMIT mitten in der Übertragung abgeschaltet. Du brauchst etwas in dieser Richtung (Register auf deinen unbekannten Prozessor anpassen, ungetestet):
1 | #define TRANSMIT_ON() ... // Setze 75176 Pins 2,3 HIGH
|
2 | #define TRANSMIT_OFF() ... // Setze 75176 Pins 2,3 LOW
|
3 | |
4 | // internal
|
5 | void uart_put(unsigned char c) |
6 | {
|
7 | while (!(UCSRA & (1<<UDRE))); // warte bis Sendepuffer leer |
8 | UDR = c; |
9 | }
|
10 | |
11 | void uart_putc(unsigned char c) |
12 | {
|
13 | TRANSMIT_ON(); |
14 | uart_put(c); |
15 | |
16 | // warte bis kompletter Frame gesendet
|
17 | while (!(UCSRA & (1<<TXC))); |
18 | |
19 | TRANSMIT_OFF(); |
20 | }
|
21 | |
22 | void uart_puts (char *s) |
23 | {
|
24 | //
|
25 | // Fuer vernuenftige Halbduplex-Kommunikation muesste hier
|
26 | // erstmal gepueft werden, ob gerade Daten empfangen werden!
|
27 | // Nur wenn der Bus frei ist darf gesendet werden.
|
28 | //
|
29 | |
30 | // 75176 in Sendemodus
|
31 | TRANSMIT_ON(); |
32 | |
33 | while (*s) |
34 | {
|
35 | uart_put(*s); |
36 | s++; |
37 | }
|
38 | |
39 | // warte bis kompletter Frame gesendet
|
40 | while (!(UCSRA & (1<<TXC))); |
41 | |
42 | // 75176 in Empfangsmodus
|
43 | TRANSMIT_OFF(); |
44 | }
|
:
Bearbeitet durch User
Hi Zum Umschalten kann man auch TXC-Interrupt nutzen. Der wird ausgelöst, wenn das ein Byte vollständig gesendet wurde und im Sendepuffer der U(S)ART kein weiteres Byte vorhanden ist. MfG Spess
Danke an euch hab es jetzt so gelöst, jetzt funktioniert schon mal das senden und empfangen. Bei RS232 musste ich mir nie Gedanken ums senden machen, einfach übergeben und gut wars ;) Naja jetzt kanns endlich weiter gehen. Ich bedanke mich erst mal für die Hilfe hier.
1 | #define TRANSMIT_ON PORTC |= (1<<PC3)
|
2 | #define TRANSMIT_OFF PORTC &= ~(1<<PC3)
|
3 | |
4 | ISR(USART0_TXC_vect) |
5 | {
|
6 | TRANSMIT_OFF; |
7 | UART1_Transmit('V'); |
8 | }
|
9 | void uart_putc(unsigned char c) |
10 | {
|
11 | TRANSMIT_ON; |
12 | USART_Transmit(c); |
13 | }
|
:
Bearbeitet durch User
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.