Hallo, ich versuche gerade mit meinem Atmega32 und dem STK 500 über USART ein Zeichen auszugeben und es dann mit dem Hyperterminal zu empfangen. Ich habe mal den Code beigefügt und würde erstmal gerne wissen ob der so richtig wäre(habe ihn nach Datenblatt und GCC-Tutorial geschrieben). Mein Problem ist nämlich das ich im HT nichts sehe. Habe die Verbindung so eingestellt: auf 8 Data, 2 Stopbit, keine Parität und keine Flusssteuerung gesetzt. Das ist doch richtig nach dem C-Code oder? Habe auf dem STK500 auch Uart mit dem RS232 Spare verbunden. Muss ich sonst noch was beachten? Danke für eure Hilfen! Gruß Marian
Achso habe noch vergessen zu sagen, das ich den internen Oszi mit 4 MHz verwende. So ich glaube jetzt habe ich alles wichtige erwähnt oder?
> Mein Problem ist nämlich das ich im HT nichts sehe. Nu ja, Hyperterminal ist auch eher berüchtigt. Soweit ich weiß (ich benutze kein Windows), wird Teraterm gern empfohlen. > Habe die Verbindung so eingestellt: auf 8 Data, 2 Stopbit, keine > Parität und keine Flusssteuerung gesetzt. Das ist doch richtig nach > dem C-Code oder? Baudrate? Wenn du sonst nichts geändert hast, müssten das 2400 Bd sein, so wie der Code jetzt geschrieben ist (interner RC-Oszillator mit 1 MHz und UBRR = 25). UBRRH und UCSRC musst du übrigens nicht unbedingt anfassen. Beide haben die entsprechenden Werte (sinnvollerweise) als Defaults.
Danke für den Tipp mit Teraterm, werde ich mal testen. Nun noch eine Frage: Ich hatte leider vergessen zu sagen, dass die Baudrate 9600 beträgt. Daher ja auch die 25 (laut Datenblatt). Wie kommst du denn auf die 2400? Und der interne Oszi ist doch 4 MHz und nicht 1 MHz( Das lege ich doch im Makefile fest) oder?
> Und der interne Oszi ist doch 4 MHz und > nicht 1 MHz( Das lege ich doch im Makefile fest) oder? Was meinst du denn, wie dein Makefile den Oszillator im Chip ändern soll? Nein, sorry. Im Makefile legst du bestenfalls den Makro F_CPU fest, den du dann aber im Code nichtmal benutzt. Sinnvoll wäre natürlich sowas:
1 | UBRRL = F_CPU / (16 * 9600UL) - 1; |
Dann könntest du wenigstens das vom Makefile aus ändern. Lies' dir bitte den Abschnitt über die Fuses im Datenblatt durch. Der Standard-Takt ist halt 1 MHz. Denk auch dran, dass der RC-Oszillator für 1 MHz ab Werk kalibriert ist, nicht aber für die anderen Frequenzen. Du musst daher den OSCCAL-Wert passend setzen. Wenn du avrdude mal im Terminal-Mode startest (-t), dann kannst du "d osccal" eingeben, um die empfohlenen OSCCAL-Werte für 1/2/4/8 MHz (bei 5 V) zu sehen.
Stimmt ja das habe ich ganz vergessen. Ich habe noch nie das "AVRdude gui" benutzt und mich jetzt mal damit beschäftigt. Nun bekomme ich folgende Fehlermeldung: stk500 getsync():not in sync:resp=0x00 was bedeutet das? Wieso soll ich eigentlich avrdude nutzen wenn ich winavr nehmen könnte? Finde das irgendwie angenehmer.
@ Jörg : Nebenbei bemerkt, ich habe den Oscal-wert richtig gesetzt. Im AVR studio setze ich das doch bei advanced fest. Da kann ich doch zw. 1,2,4,8 MHz unterscheiden und ich hab dort 4 MHz eingestellt also habe ich doch dann mit den richtigen Fuses( auch auf 4MHz internen Oszillator) einen 4MHz Takt oder nicht?
> Ich habe noch nie das "AVRdude gui" benutzt und mich jetzt mal damit > beschäftigt. Nun bekomme ich folgende Fehlermeldung: > stk500 getsync():not in sync:resp=0x00 > was bedeutet das? Hmm, STK500 mit Firmware-Version 2. Da brauchst du ein avrdude 5.0 dazu. > Wieso soll ich eigentlich avrdude nutzen wenn ich winavr nehmen > könnte? Das ist eine unsinnige Frage. ;-) So ungefähr wie: ,,Wieso soll ich eigentlich Benzin kaufen, wenn ich doch auch Auto fahren kann?'' (Naja, Vergleiche hinken alle.) avrdude ist Teil von WinAVR. > @ Jörg : Nebenbei bemerkt, ich habe den Oscal-wert richtig > gesetzt. Im AVR studio setze ich das doch bei advanced fest. Da kann > ich doch zw. 1,2,4,8 MHz unterscheiden und ich hab dort 4 MHz > eingestellt also habe ich doch dann mit den richtigen Fuses( auch > auf 4MHz internen Oszillator) einen 4MHz Takt oder nicht? Von AVR Studio habe ich keine Ahnung, sorry. Ist mir zu umständlich zu bedienen, das Teil (außerdem habe ich zu Hause kein Windows, und auf Arbeit mache ich den größtmöglichen Bogen drum). Es gibt zwei Dinge da, einerseits die Fuse, die den Takt einstellt (die hast du offenbar eingestellt -- meine Annahme, dass du mit 1 MHz arbeitest basierte darauf, dass du erstmal so klangst, als hättest du am Controller noch nichts geändert). Andererseits musst du OSCCAL noch passend setzen. Meiner Erinnerung nach bietet dir AVR Studio an, dass es den passenden OSCCAL-Wert in irgendeine EEPROM- oder Flash-Zelle schreiben kann, aber selbst wenn du das gemacht hast, muss deine Applikation sie dort noch auslesen und ,zu Fuß' ins OSCCAL-Register schreiben. Wenn dein 4-MHz-Oszillator zu weit neben der Frequenz liegt, geht die UART-Kommunikation nicht richtig (gar nicht oder nur in einer Richtung oder nicht für alle Zeichen). Ich würde dir empfehlen, erstmal mit 1 MHz anzufangen, dafür ist der Oszillator kalibriert. Ändere UBRRL passend. Empfehlenswert ist es bei 1 MHz, noch U2X in UCSRA zu setzen, um das oversampling von 16fach auf 8fach zu reduzieren, damit verringert sich der Baudratenfehler bei 9600 Bd auf vernünftige Werte. In der obigen Formel musst du dann natürlich die 16 durch eine 8 ersetzen. Ich nehme da sowas wie:
1 | #if F_CPU < 2000000UL
|
2 | UCSRA = (1 << U2X); |
3 | UBRRL = F_CPU / (8 * 9600UL) - 1; |
4 | #else
|
5 | UBRRL = F_CPU / (16 * 9600UL) - 1; |
6 | #endif
|
Ok ich habe jetzt alles auf 1 MHz abgeändert aber auch mit TeraTerm kommt nix raus. Wie schreibe ich den den Osccal-Wert "zu Fuß" ins Register? Soll ich dir nochmal meinen jetzigen Code schicken? Würde dir das bei meinem Problem vielleicht helfen? Ich bin hier schon fast am Verzweifeln. Wieso schreibst du eigentlich 9600>UL< ? ich habe bis jetzt immer nur L gesehen??? Was heißt das L bzw UL eigentlich, denn im Datenblatt steht immernur : UBRR=(fosc/16*Baud)-1
Also ich habe festgestellt das mein Atmega32 jetzt sendet...ob es per UART ist oder nicht weiß ich nich genau aber ich denke schon. Das Problem nun, ich empfange lustige zeichen aber nicht das OK was ich sende. Bei jeder Baudrate die ich am Terminal einstelle kommen andere zeichen. Woran liegt das?
Ich werde mir wohl doch einen externen Quarz besorgen müssen, vielleicht funktioniert es dann. Kann mir noch jemand erklären wie ich "zu fuß" die Osccal-werte ins Osccal-Register schreiben kann? Danke für eure Hilfe :)
> Ok ich habe jetzt alles auf 1 MHz abgeändert aber auch mit TeraTerm > kommt nix raus. Wie schreibe ich den den Osccal-Wert "zu Fuß" ins > Register?
1 | OSCCAL = 0xab; /* oder was auch immer */ |
> Soll ich dir nochmal meinen jetzigen Code schicken? Würde dir das > bei meinem Problem vielleicht helfen? Vielleicht. Mit all dem AVR Studio Vodoo ringsum wäre ich mir natürlich nie wirklich sicher, welchen fuse settings du nun gerade erlegen bist. ;-) Moment mal, AVR Studio gibt doch im Statusfenster die Fuse-Werte hexadezimal an, wenn es diese liest oder schreibt. Die kannst du ja mal mit posten. > Ich bin hier schon fast am Verzweifeln. Wieso schreibst du > eigentlich 9600>UL< ? ich habe bis jetzt immer nur L gesehen??? Was > heißt das L bzw UL eigentlich, ... Die Suffixe von Integer-Zahlenkonstanten sollten in jedem C-Buch erklärt sein. U - unsigned, L - long, UL also unsigned long. C99 hat dann noch zwei Ls zu long long definiert. Groß-/Kleinschreibung der Suffixe ist (ausnahmsweise mal) egal. Bei 9600 muss man das auch wirklich angeben, weil ansonsten der Teilausdruck 9600 * 16 als "int" angenommen wird, aber den Wertebereich von int überlaufen lässt. > Also ich habe festgestellt das mein Atmega32 jetzt sendet...ob es > per UART ist oder nicht weiß ich nich genau aber ich denke > schon. Das Problem nun, ich empfange lustige zeichen aber nicht das > OK was ich sende. Bei jeder Baudrate die ich am Terminal einstelle > kommen andere zeichen. Häng' doch mal ein Oszillofon dran und lass den AVR ein konstantes Bitmuster senden (z. B. nur 0xff-Zeichen, dann hast du nur das Startbit periodisch wiederholend). Damit solltest du zumindest die Bitrate nachmessen können. Wenn du das zurückrechnest, fällt einem dann meistens alles wie Schuppen aus den Haaren... > Ich werde mir wohl doch einen externen Quarz besorgen müssen, > vielleicht funktioniert es dann. Das ist trial&error engineering. Wenn's dann nicht daran liegt, was machst du dann? Der interne 1-MHz-Oszillator hat mir noch nie bei RS-232 irgendwelche Huddeleien verursacht. (Andere Werte als 1 MHz schon, da kalibrieren wir dann gegen einen bekannten Takt.)
Vielen Dank für dein Antwort...ich glaube da könenn wir morgen noch weiter drüber reden. Habe heute leider keine zeit mehr dafür :(. Das mit dem UL is ja doch ganz schön logisch! Hätte ich auch mal drauf kommen können...bin halt noch ein C Anfänger. Also nach einigem probieren und Datenblatt bzw. Manual lesen bin ich jetzt fest der Überzeugung, das mein Takt einfach nicht stimmt. Werde das morgen überprüfen (habe aber leider keine Oszi...) So und mein Code(Hab eigentlich deine Ini verwendet und sonst nix geändert ) gibts auch nochmal, hoffe das er nicht zu "einfach" geschrieben ist. Nochmals DANKE für dein Hilfe Jörg!!! Bis morgen dann...ciao
> Also nach einigem probieren und Datenblatt bzw. Manual lesen bin ich > jetzt fest der Überzeugung, das mein Takt einfach nicht > stimmt. Werde das morgen überprüfen (habe aber leider keine Oszi...) Einen Oszillografen sollte sich wohl irgendwie jeder, der mit Controllern bastelt, zulegen. Für solche Dinge hier genügt einer mit einer eher geringen Grenzfrequenz, das sollte man für'n Appel und 'n Ei bekommen können. Hab' gerade mal bei Ebäh in den beendeten Auktionen gesucht, ein Oszi dieser Klasse bekommst du zwischen 20 und 40 Fragezeichen (+ Versand), neu werden derartige Teile für EUR 80 verramscht (allerdings dürfte ein 30 Jahre altes abgelegtes Teil aus der Industrie mehr taugen als so'n Neuramsch). > So und mein Code(Hab eigentlich deine Ini verwendet und sonst nix > geändert ) gibts auch nochmal, hoffe das er nicht zu "einfach" > geschrieben ist. Zwei Bemerkungen. Die erste ist ein Schönheitsfehler und eine Frage der Standard-Konformität: das Doppelkreuz der Präprozessor-Anweisungen soll immer in der ersten Spalte stehen. Nach dem Doppelkreuz dürfen Leerzeichen stehen. Die meisten Compiler schlucken es auch davor, aber es ist nicht garantiert. Dein eigentlicher Fehler dürfte aber sein, dass du string literals mit character literals verwechselt hast: »"O"« ist etwas anderes als »'O'«. Das erste hat den Typ const char *, das zweite den Typ char.
Hallo Marian, hast Du denn bei Deinem USART-Problem die richtigen Port-Pins und vor allem ein RS232-Treiber-IC eingesetzt (z.B. MAX232 mit 4 oder 5 Kondensatoren) ? Otto
Hi... Ich denke schon das ich das habe, da ich ja mit dem STK500 rumspiele und da ist doch wohl alles drauf oder?` So ich werde mir jetzt mal nen Quarz besorgen gehen und wenns dann imernoch nicht klappt melde ich mich hier wieder. Das kann doch nich so schwer sein ein Zeichen per Uart zu senden. Hat zufällig jemand einen C-Code für das STK500 und einen Atmega32 damit ich meinen mal überprüfen könnte? Kann ja schließlich auch sein, das mein Code, den ich jetzt oft geändert habe, nicht mehr so richtig will. Danke und bis später!
Auf mein Posting hast du nicht geantwortet. Ich denke, dass bis auf den Fehler mit dem char * vs. char mit deinem Code alles OK ist.
Sorry Jörg, wusste nicht das du noch eine Antwort auf dein Post haben wolltest, hatte Freitag auch Probleme mit dem Netzwerk, weswegen ich nicht ins Netz konnte. Ich denke ja auch das mein Code O.K. ist, wollte halt nur sicher gehen. Nach dem Mittag werde ich dann meinen Quarz haben und dann wirds hoffentlich funzen :). Ich hoffe das ich nicht schon zuviel verstellt habe, so daß dann auch der µC mit dem externen Quarz betrieben werden kann. Ich hab auch schon herausgefunden, daß mein Uart genau 1 Zeichen sendet( und wenn ich 2 senden will tut er das auch) aber ankommen tun nur lustige Zeichen. Das ist ja ein Indiz für eine falsche Frequenz oder nicht? Naja nach dem Mittag werden wir mehr wissen. Ciao und bis bald :)
> Ich hab auch schon herausgefunden, daß mein Uart genau 1 Zeichen > sendet( und wenn ich 2 senden will tut er das auch) aber ankommen > tun nur lustige Zeichen. Das ist ja ein Indiz für eine falsche > Frequenz oder nicht? Oder eben dafür, dass man das falsche Zeichen sendet, z. B. einen Zeiger, wenn man ein Zeichen senden will. Du hast mir bislang noch nicht geschrieben, dass du die "O" und "K" durch 'O' und 'K' ersetzt hättest.
Das haette er so sowieso nie durch den Compiler gekriegt. Also wird er's wohl gemacht haben.
Also ich hab das durch den Compiler bekommen ;)...da kam halt nur ne kleine Warnung aber kein Fehler! Ja Jörg ich hab das geändert, sorry das ich dir das nicht gesagt habe.
Ich habe da mal eine ganz klitzekleine (vielleicht dumme) Frage: Wie mache ich dem klar, dass er den Hex-Code für das Zeichen senden soll? Also will ich beispielsweise ein 'A' senden, soll er direkt 0x63 senden. So kann man doch einfacher interpretieren was man empfangen hat. Wie lautet nun die Syntax dafür? '0x63'?
Ne kleine Frage zu dem Thema "Oscal". Jörg, du hast ja gesagt, daß man das im Programm nochmla extra festlegen muss. Z.B. OSCCAL = 0xab; /* oder was auch immer */ Nun meine Frage. Im AVR Studio kann ich ja den Wert des Registers auslesen, meinetwegen 0xB6 für 1MHz. Dann habe ich dort die Möglichkeit, diesen Wert in "Write Adress" einzutragen. Aber in welche Adresse soll ich den denn eintragen? Ihr schreibt den ja einfach ins Osccal-Register aber ohne direkte Adresszuweisung. Hab mal ein Screenshot von meinem Problem gemacht. Wisst ihr jetzt was ich meine und kann mir da jemnad helfen? Danke und Gruß "der sich immer mehr fragende" Marian
Hi Daniel, wie du ja gesehen hast bin ich auch Anfänger auf dem Gebiet, aber ich versuche dir trotzdem zu helfen. Ich denke, der richtige Syntax wäre: Uart_Transmit (0x41); So müsste er dein Hexcode senden. Wenn ich mich irre kann man mich gerne korrigieren :).
Hi Marian. Ich hab gestern 6 Stunden damit verbracht Zeichen per UART mit meinem STK500 zu senden und zu empfangen. Hat zwar gedauert aber jetzt klappt es. Ich hab mir ein kleines programm geschrieben das als echo zum testen fungiert also wenn du was per TelNet eingibst dann erscheint es sofort auf dem Bildschirm das heisst der µC empfängt das Zeichen und sendet es wieder zurück. Man kann die zeichen auch z.B. mit +1 manipullieren so kommt anstatt "1" dann "2" oder statt "a" kommt "b" raus. Ich bin im Moment in der Arbeit und der Code liegt daheim. Ich kann ihn heut Abend gerne online stellen.
Das wäre schön, dann könnte ich deinen Code mal testen um einen Fehler des Programms auszuschließen. Danke
> Also will ich beispielsweise ein 'A' senden, soll er direkt 0x63 > senden. So kann man doch einfacher interpretieren was man empfangen > hat. > > Wie lautet nun die Syntax dafür? '0x63'? Du wirst lachen. Aber das einfachste ist 'A'. Wenn du 'A' schreibst, dann setzt der Compiler das sowieso in die den Code entsprechende (normalerweise ASCII) Zahl um (Im Rechner selbst ist alles eine Zahl. Der Datentyp char ist auch nichts anderes als ein Datentyp fuer kleine Zahlen, der nur waehrend der Ein/Ausgabe etwas anders behandelt wird).
> aber ich versuche dir trotzdem zu helfen. Ich denke, der richtige > Syntax wäre: Uart_Transmit (0x41); machs nicht. Schreib einfach Uart_Transmit( 'A' ); macht genau dasselbe, wenn Dein System, bzw. Compiler, ASCII voraussetzt (*) und ist doch wesentlich einfacher zu lesen und zu verstehen. Im Normalfall gibt es ausser fuer spezielle Zeichen absolut keinen Grund hier mit Hex-Codes um sich zu werfen. Lass das den Compiler machen. (*) ASCII ist sowas wie Standard. Erst wenn Du IBM Grossrechner programmierst kommt EBCDIC ins Spiel.
Na toll, jetzt habe ich immernoch kein Quarz :(...das wird wohl noch dauern. Kann mir denn noch jemand bei dem Oscal-Problem helfen?
"(*) ASCII ist sowas wie Standard. Erst wenn Du IBM Grossrechner programmierst kommt EBCDIC ins Spiel." Die Zeiten sind groesstenteils vorbei.
Juhu es hat geklappt! Ich bekomme endlich meine Uart Kommunikation hin! Danke an alle, besonders an Jörg :)!
> Ne kleine Frage zu dem Thema "Oscal". Jörg, du hast ja gesagt, daß > man das im Programm nochmla extra festlegen muss. Man muss OSCCAL einstellen. Wo auch immer man den passenden Wert dafür hernimmt. > Nun meine Frage. Im AVR Studio kann ich ja den Wert des Registers > auslesen, meinetwegen 0xB6 für 1MHz. Dann habe ich dort die > Möglichkeit, diesen Wert in "Write Adress" einzutragen. Aber in > welche Adresse soll ich den denn eintragen? Damit kannst du ihn nur in eine Flash-ROM- oder EEPROM-Zelle deiner Wahl schreiben lassen. Von da muss ihn deine Applikation dann selbst extrahieren und nach OSCCAL transferieren. Das könnte z. B. so aussehen:
1 | #include <stdint.h> |
2 | #include <avr/eeprom.h> |
3 | #include <avr/io.h> |
4 | |
5 | #define EEPROM_OSCCAL 0 /* |
6 | * EEPROM address where the OSCCAL value has
|
7 | * been copied to.
|
8 | */
|
9 | |
10 | void
|
11 | init(void) |
12 | {
|
13 | OSCCAL = eeprom_read_byte((uint8_t *)EEPRO_OSCCAL); |
14 | }
|
Eine andere Möglichkeit ist es, erst einmal mit Vcc = 5 V und F_CPU = 1 MHz zu arbeiten. Der OSCCAL-Wert für diesen Fall wird durch die Hardware bereits intern eingestellt. Noch eine andere Möglichkeit ist es, den RC-Oszillator gegen einen anderen bekannten Takt zu kalibrieren und OSSCAL dynamisch anzupassen. Sowas macht beispielsweise die AVR Butterfly (gegen den 32-kHzQuarz).
@Markus: Über dein Echo-Programm würde ich mich trotzdem noch freuen, da dies mein nächster Schritt ist und ich somit schnellstmöglich Probleme mit meinem Programm beheben könnte. Danke und Gruß Sich freuender Marian
Danke :) Ich war gestern so voller Freude, daß ich mir selbst schon vorher ein Echo-Programm geschrieben habe. Trotzdem Danke für dein Code! Ich werde ihn mal testen. Gruß an alle, deren Uart funktioniert :) der glückliche Marian
Ui, das ist gar nicht so einfach zu erklären. Ich habe halt viel rumgespielt und getestet. Irgendwann kam dann mal das "OK" am Terminal an. Ich denke, das es am internen Oszillator lag. Nachdem ich nun anscheinend den richtigen Oscal-Wert in das Programm geschrieben hatte kam auch alles vernünftig an. Also wird es wohl, wie gesagt, am internen Takt gelegen haben. Die Einstellung im AVR-Studio haben wohl nicht ausgereicht um den Oscal-Wert auszulesen und ins Register zu schreiben. Naja ich danke euch nochmal allen und wünsche euch noch ein frohes Fest! Gruß Marian
ja ja. kenn das mit usart. hab auch 3 tage gebraucht bis ich geerkt hab dass man mit 4mhz und 9600 baud einfach zuweit daneben liegt. wollte meinen uC mit labView reden lassen. hatte immer timeout - probleme. ich benütze codevision und auch das stk500 mit at90s8515. der wizzard macht immer UBRR=0x19; da die die uart (9600) verträglichste frequenz von 3.68mHz vorausgesetzt wird. is aber nimmer ganz so richtig wenn man 4MHz hat. da buss man dann UBRR=0x17; manuell setzen und schwubb funktionierts
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.