Hallo zusammen, vielleicht kann mir jemand helfen. Ich habe ein STK500 und ein Atmega8 da drauf. Eine UART Kommunikation habe ich zum PC hergestellt bzw. schicke ein Zeichen von dem Controller an den PC. Dazu verwende ich bei dem Atmega 1MHz und Baudrate von 4800. Allerdings wenn ich das am Computer lesen möchte, zeigt er mir nur Nullen an bzw. dass er nur Nullen bekommt,egal welches Zeichen ich sende. Am Oszilloskop sehe ich dagegen die unterschiedlichen Signale. Zum Empfangen bzw. Anzeigen der Daten verwende ich das Programm HTerm. Woran könnte das liegen? Hat da jemand eine Idee? Vielen Dank im voraus!
Andrey, hast Du auf dem STK500 die Verbindung vom PortD (Pins PD0 und PD1) zum Anschluss "RS232 SPARE" (STK500-User Guide, Seite 3-5) hergestellt? Steckt Dein RS232-Kabel im Anschluss "RS232 Port for Communication" (STK500-User Guide, Seite 3-1)? Ciao, mare_crisium
Ich muss nachhaken
> zeigt er mir nur Nullen an bzw. dass er nur Nullen bekommt
heißt das, das du in hTerm siehst, das etwas ankommt und dieses etwas
sind lauter binäre 0-en (oder immer der Code für das ASCII Zeichen '0',
was auch ungewöhnlich wäre)
Oder steht im hTerm der Cursor still und nichts rührt sich?
Das ist nicht dasselbe. Im einen Fall kommt tatsächlich ein Empfang zu
Stande, im anderen Fall aber nicht. Letzterer Fall könnte zb dadurch
verursacht werden, dass das verwendete Kabel falsch rum gekreuzt ist.
Ich würde als erstes mal die grundsätzliche physikalische Verbindung
testen.
Dazu nimmst du den µC aus seinem Sockel und brückst mit einem Stück
Draht den Tx-Pin mit dem Rx-Pin direkt im µC-Sockel. Wenn du dann am PC
auf der Tastatur klimperst, muss alles was du tippst auch am Monitor
erscheinen. Gegentest: die Brücke rausnehmen und das Echo muss aufhören.
Wenn du diesen Zustand hast, dann ist damit abgeklärt, dass die
physikalische Verbindung, inklusive Kabel, inklusive aller Jumper auf
dem STK grundsätzlich funktionsfähig ist.
Vielen Dank erstmal für die Antworten! Harald M., ja die Anschlüsse sind richtig verbunden. Karl Heinz Buchegger,in HTerm sehe ich das ein Signal ankommt und diesel Signal wird anscheinend als Null interpretiert, d.h. es kommen laute binäre Nullen. Die physikalische Verbindung werde ich dann wohl wieder nachprüfen und sobald ich es getan habe,hier bescheid geben.
Moment,die Verbindung besteht ja. Ich bekomme das Signal am PC und kann es auch mit einem Oszilloskop abgreifen.
Hier habe ich meinen Quelltext für das Programm. Weiß nicht,ob ich alles richtig gemacht habe. Vielleicht sieht ja jemand von euch den Fehler.
Ich nehme mal an du hast die Initialisierung aus dem Datenblatt abgeschrieben. Hast du im HTerm aber auch zwei Stoppbits eingestellt?
Ja, ich habe es mit unterschiedlicher Konfiguration ausprobiert, es kommen trotzdem immer nur Nullen an.
Quelltext als PNG? (Das ist das dümmste was du tun kannst. Wie soll ich mich denn jetzt mit Cut&Paste auf deinen Quelltext beziehen und daraus Passagen zitieren. Abgesehen davon hast du eine Menge Arbeit damit, das PNG herzustellen. Quelltext postest du ganz einfach als .... tata .... Quelltext. Was für eine Überraschung! Das ist für dich am wenigsten Arbeit und wir können uns problemlos auf Passagen beziehen) USART_transmit( 0x01 ); lass dir zuerst mal etwas senden, was ein sichtbares Zeichen ergibt. Das Bitmuster für 0x01 zu senden und dann mit der Ausgabe kombinieren, dass beim Empfänger IMMER nur ein 0-Byte ankommt, das war nicht sehr hilfreich. Denn die USART braucht nur in der Takfrequenz ein klein wenig daneben sein und schon kommt das einzige 1 Bit im Gesendeten nicht zur richtigen Zeit beim Empfänger an. Und von 'IMMER' kann auch keine Rede sein. USART_transmit( 'A' ); und dann schaun wir mal, was da rauskommt. Wahrscheinlich das übliche. Deine Taktfrequenz ist ein wenig daneben. Die F_CPU Angabe stinkt nach internem RC-Generator. Die geht so genau wie die Messung der Seehöhe durch Messung des Wasserstands in der Donau.
Karl Heinz Buchegger schrieb: > Das > Bitmuster für 0x01 zu senden und dann mit der Ausgabe kombinieren, dass > beim Empfänger IMMER nur ein 0-Byte ankommt, das war nicht sehr > hilfreich. Denn die USART braucht nur in der Takfrequenz ein klein wenig > daneben sein und schon kommt das einzige 1 Bit im Gesendeten nicht zur > richtigen Zeit beim Empfänger an. Damit bei 0x01 am Empfänger eine 0 ankommt, muss der Takt schon gewaltig daneben liegen. Hinweis: es wird LSB-first gesendet. ;-)
also hier der Quelltext nochmal:
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | |
4 | |
5 | #ifndef F_CPU |
6 | #define F_CPU 1000000UL // Systemtakt in Hz - Definition als unsigned long beachten |
7 | // Ohne ergeben sich unten Fehler in der Berechnung |
8 | #endif |
9 | |
10 | |
11 | #define BAUD 9600UL // Baudrate |
12 | #include <util/setbaud.h> |
13 | #define UBRR_VAL ((F_CPU)/(BAUD*16)-1) // clever runden |
14 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate |
15 | #define BAUD_ERROR ((BAUD_REAL)/(BAUD)-1)*100 // Fehler in Promille, 1000 = kein Fehler. |
16 | |
17 | |
18 | #if ((BAUD_ERROR<99) || (BAUD_ERROR>101)) |
19 | #endif |
20 | #include <util/delay.h> |
21 | #include <inttypes.h> |
22 | |
23 | |
24 | |
25 | void USART_Init(void){ |
26 | UBRRH = UBRR_VAL >> 8; |
27 | UBRRL = UBRR_VAL & 0xFF; |
28 | |
29 | UCSRB = (1<<RXEN)|(1<<TXEN); |
30 | UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); |
31 | } |
32 | |
33 | void USART_Transmit(unsigned char data){ |
34 | while(!(UCSRA)&(1<<UDRE)); |
35 | UDR = data; |
36 | } |
37 | |
38 | void USART_TransmitC(unsigned char *s) |
39 | { |
40 | while (*s) |
41 | { // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" |
42 | USART_Transmit(*s); |
43 | s++; |
44 | } |
45 | } |
46 | |
47 | |
48 | |
49 | int main(){ |
50 | |
51 | // Ausgabe von 0123456789 |
52 | char c; |
53 | |
54 | USART_Init(); |
55 | |
56 | /* |
57 | for (uint8_t i=0; i<=9; ++i) { |
58 | c = i + "0"; |
59 | USART_TransmitC(c); |
60 | |
61 | } |
62 | */ |
63 | while (1) { |
64 | DDRC = 0xff; |
65 | PORTC = 0x00; |
66 | _delay_ms(500); |
67 | PORTC = 0xff; |
68 | _delay_ms(500); |
69 | USART_Transmit(0xFF); |
70 | |
71 | } |
72 | |
73 | return 0; // never reached |
74 | |
75 | |
76 | } |
hab das jetzt soweit,dass ich für
1 | USART_Transmitt(0x01); |
eine "129"(dezimal) bekomme. Dementsprechend für
1 | USART_Transmitt(0x00); |
"128" Jetzt weiß ich nicht wo mein Fehler liegt.
Andrey B. schrieb: > hab das jetzt soweit,dass ich für
1 | USART_Transmitt(0x01); |
> eine "129"(dezimal) bekomme. Dementsprechend für
1 | USART_Transmitt(0x00); |
> "128" > Jetzt weiß ich nicht wo mein Fehler liegt. Das bedeutet, dass das Stopp-Bit zu früh kommt. Das dürfte jetzt das schon von Karl Heinz angesprochene "interner RC-Oszillator"-Problem sein.
Was muss ich denn jetzt genau machen,um dieses Problem zu lösen?
Andrey B. schrieb: > Was muss ich denn jetzt genau machen,um dieses Problem zu lösen? Den Mega nicht mit dem internen RC-Oszllator laufen lassen, sondern einen Quarz oder Quarzoszillator aktivieren.
Moment: bei 1 MHZ und 9600 Baud und ohne U2X ist der Fehler schon prinzipiell viel zu groß. Benutze U2X oder 4800 Baud. PS:
1 | #if ((BAUD_ERROR<99) || (BAUD_ERROR>101))
|
2 | #endif
|
War wohl keine so gute Idee, die Zeile dazwischen zu löschen. ;-)
Vielen Dank.so hier der Code, der jetzt auch funktioniert.Das war tatsächlch die Baudrate. Hab die jetzt auf 4800 gestellt.:
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | |
4 | |
5 | #ifndef F_CPU |
6 | #define F_CPU 1000000UL // Systemtakt in Hz - Definition als unsigned long beachten |
7 | // Ohne ergeben sich unten Fehler in der Berechnung |
8 | #endif |
9 | |
10 | |
11 | #define BAUD 4800UL // Baudrate |
12 | #include <util/setbaud.h> |
13 | #define UBRR_VAL ((F_CPU)/(BAUD*16)-1) // clever runden |
14 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate |
15 | #define BAUD_ERROR ((BAUD_REAL)/(BAUD)-1)*100 |
16 | |
17 | |
18 | #if ((BAUD_ERROR<99) || (BAUD_ERROR>101)) |
19 | #endif |
20 | #include <util/delay.h> |
21 | #include <inttypes.h> |
22 | |
23 | |
24 | |
25 | void USART_Init(void){ |
26 | UBRRH = UBRR_VAL >> 8; |
27 | UBRRL = UBRR_VAL & 0xFF; |
28 | |
29 | UCSRB = (1<<RXEN)|(1<<TXEN); |
30 | UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0); |
31 | } |
32 | |
33 | void USART_Transmit(unsigned char data){ |
34 | while(!(UCSRA)&(1<<UDRE)); |
35 | UDR = data; |
36 | } |
37 | |
38 | void USART_TransmitC(unsigned char *s) |
39 | { |
40 | while (*s) |
41 | { // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" |
42 | USART_Transmit(*s); |
43 | s++; |
44 | } |
45 | } |
46 | |
47 | |
48 | |
49 | int main(){ |
50 | |
51 | // Ausgabe von 0123456789 |
52 | char c; |
53 | |
54 | USART_Init(); |
55 | |
56 | /* |
57 | for (uint8_t i=0; i<=9; ++i) { |
58 | c = i + "0"; |
59 | USART_TransmitC(c); |
60 | |
61 | } |
62 | */ |
63 | while (1) { |
64 | DDRC = 0xff; |
65 | PORTC = 0x00; |
66 | _delay_ms(500); |
67 | PORTC = 0xff; |
68 | _delay_ms(500); |
69 | USART_Transmit(0x00); |
70 | |
71 | } |
72 | |
73 | return 0; // never reached |
74 | |
75 | |
76 | } |
Andrey B. schrieb: > #if ((BAUD_ERROR<99) || (BAUD_ERROR>101)) > #endif Ist natürlich auch eine Möglichkeit eine Fehlermeldung zu löschen, die einem gesagt hätte, dass sich das mit den Zahlenwerten nicht vernünftig ausgeht.
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.