Hallo Leute, ich sehe mal wieder den Wald vor lauter Bäumen nicht... Also, ich bin schon erfolgreich bei der EIA-232. Einrichten etc unter AVRSTUDIO mit dem AVR-GCC funktioniert einwandfrei. Also sollte die Initialisierung schon mal bei der 485 auch passen. Ich verwende derzeit als Prototypen Umgebung nen STK500 mit angematchten ADM485 von microe.com (bald auf fertiger platine alles komplett!). Senden etc kann ich alles auf dem Oscar sehen. Invertierung klappt einwandfrei. Allerdings bin ich mir bei den Pegeln nicht mehr sicher. Ich habe mehrere Quellen mir dazu durchgelesen, aber jeder schreibt irgendwie was anders. Kann mir einer von euch sagen, welcher Pegel den anliegen sollte? Dann habe ich ein weiteres Problem, wenn ich empfangen möchte. Sobald ich die Empfangsroutine verwende hängt der uC irgendwo im Nirvana rum und reagiert nicht mehr. Meine Vermutung: Es kommen keine Daten zurück.. Aber auch wenn dies so ist(wie ich es dem Oscar wohl entnehme!) sollte dann der uC-Daten-Puffer doch Datenmüll interpretieren. oder ? Achso, verwende als Code den Standard angepaßten Code aus den Datenblätern. Somit nix selbstzusammengebrautes. Es geht ja erstmal um die Hardwareseitige Nutzung. Das Protokoll sei erstmal hinten angestellt. Kann mir einer weiterhelfen. Schonmal besten Dank.
Hi, hups...da fehlte doch glatt der Anhang!
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | #define UART_BAUD 9600UL
|
5 | #define F_CPU 8000000UL
|
6 | #define TESTO_1 0x01
|
7 | #define TESTO_2 0x02
|
8 | #define TESTO_3 0x03
|
9 | #define TESTO_4 0x04
|
10 | #define RESERVE 0x00
|
11 | #define BYTECOUNT 0x02
|
12 | |
13 | |
14 | unsigned char Testo_Send(unsigned char Case,unsigned char Testo_X); |
15 | void set_SS_X(unsigned char bit); |
16 | void unset_SS_X(unsigned char bit); |
17 | void InitUART(); |
18 | unsigned char ReceiveByte(void); |
19 | void TransmitByte(unsigned char data); |
20 | |
21 | |
22 | |
23 | |
24 | void main(void) |
25 | {
|
26 | //set baudrate and enable RX & TX
|
27 | InitUART(); |
28 | |
29 | |
30 | DDRC = 0xff; |
31 | PORTC = 0xff; |
32 | |
33 | DDRE = 0x04; |
34 | |
35 | EICRA = (1<<ISC01)|(1<<ISC11)|((1<<ISC31)); |
36 | EIMSK = (1<<INT0)|(1<<INT1)|(1<<INT3); |
37 | sei(); |
38 | set_SS_X(2); |
39 | |
40 | while(1) |
41 | {
|
42 | // Warte auf Tasteneingabe, dann Aufruf der Funktion
|
43 | }
|
44 | |
45 | }
|
46 | |
47 | unsigned char Testo_Send(unsigned char Case,unsigned char Testo_X) |
48 | {
|
49 | unsigned char Data_send[10],Data_receive[25], i=0; |
50 | unsigned int Checksum=0,Value=0; |
51 | // 1. Frame in String, dann string ausgeben über 485
|
52 | |
53 | Data_send[9] = RESERVE; |
54 | //Data[8] = Checksum;
|
55 | Data_send[7] = Case; |
56 | Data_send[6] = 'P'; // 0x50 |
57 | Data_send[5] = BYTECOUNT; |
58 | Data_send[4] = 0x01; |
59 | Data_send[3] = RESERVE; // im Befehl = Reserve |
60 | Data_send[2] = RESERVE; |
61 | Data_send[1] = RESERVE; |
62 | Data_send[0] = Testo_X; |
63 | |
64 | for (i=0;i<8;i++) |
65 | {
|
66 | Checksum += Data_send[i]; |
67 | }
|
68 | //Bildung ZweierKomplement
|
69 | Checksum = (unsigned char) (0xff ^ Checksum) + 0x01; |
70 | |
71 | Data_send[8] = Checksum; |
72 | |
73 | set_SS_X(2); // High |
74 | |
75 | for (i=0;i<10;i++) |
76 | {
|
77 | TransmitByte(Data_send[i]); |
78 | }
|
79 | |
80 | Value = ReceiveByte(); |
81 | // Do oder for für alle Daten folgt!
|
82 | //Value a) Temperature or b) Serial Number
|
83 | return Value;//Data[8]; |
84 | |
85 | |
86 | |
87 | }
|
88 | |
89 | |
90 | |
91 | ISR (INT0_vect) |
92 | {
|
93 | PORTC = ~Testo_Send( 'U', TESTO_1); |
94 | set_SS_X(2); |
95 | |
96 | }
|
97 | |
98 | ISR (INT1_vect) |
99 | {
|
100 | PORTC = ~Testo_Send( 'U', TESTO_2); |
101 | unset_SS_X(2); |
102 | }
|
103 | |
104 | ISR (INT3_vect) |
105 | {
|
106 | PORTC = 0xBB; |
107 | |
108 | PORTC = ~ReceiveByte(); |
109 | }
|
110 | |
111 | //Funktion zum rücksetzen der SS als Portausgänge an PORTB an Stelle X auf High
|
112 | // PORTB von PB0 - PB4
|
113 | void set_SS_X(unsigned char bit) |
114 | {
|
115 | PORTE |= 1<<bit; |
116 | }
|
117 | |
118 | //Funktion zum setzen der SS als Portausgänge an PORTB an Stelle X auf Low
|
119 | // PORTB von PB0 - PB4
|
120 | void unset_SS_X(unsigned char bit) |
121 | {
|
122 | PORTE &= ~(1<<bit); |
123 | }
|
124 | |
125 | void InitUART() |
126 | {
|
127 | |
128 | UBRR0H = ((F_CPU / (8UL * UART_BAUD)) - 1 )>> 8; |
129 | UBRR0L = ((F_CPU / (8UL * UART_BAUD)) - 1); |
130 | UCSR0A = (1<<RXC0) | (1<<TXC0); |
131 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); |
132 | UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);// Asynchron 8N1 |
133 | |
134 | }
|
135 | |
136 | // --- receive a byte
|
137 | unsigned char ReceiveByte(void) |
138 | {
|
139 | // polls on receive complete
|
140 | while(!(UCSR0A & (1<<RXC0))); |
141 | |
142 | return UDR0; //return data |
143 | |
144 | }
|
145 | |
146 | // --- transmit a byte
|
147 | void TransmitByte(unsigned char data) |
148 | {
|
149 | //polls on data register empty,wann darf ich loslegen?
|
150 | while(!(UCSR0A & (1<<UDRE0))); |
151 | UDR0 = data; //transmit data |
152 | }
|
Du solltest das "SS_X"-Bit auch wieder löschen/zurücksetzen, wenn du fertig mit Senden bist. Dazu musst du erst gucken, ob das UDR leer ist (UDRE), und dann das TXC-Flag überprüfen. Danach dann das RS485-Richtungsbit wieder löschen, damit der Empfang auch wirklich möglich ist. Es dürfte schon diverse Beiträge zu dem Thema geben... >Achso, verwende als Code den Standard angepaßten Code aus den >Datenblätern. Somit nix selbstzusammengebrautes. Selbstgebrautes schmeckt manchmal einfach besser als fertiggekauftes...
Hi, danke für die Tipps... Kann es leider erst am Montag morgen wieder testen :-( Hmm, zurückgesetzt ist es im wahren Code schon... Melde mich, was passiert ist :-) Danke für die Tipps.
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.