HI Leute, ich habe ein Problem mit meiner seriellen Schnittstelle. Ich kann mein Board über die serielle Schnittstelle programmieren. Jedoch kann ich keine Daten über meine serielle Schnittstelle mit meinem Rechner austauschen. Im Debugger hat alles soweit problemlos funktioniert. Ich stell mal meinen Quelltext rein - über konstruktive Kritik und eure Hilfe würde ich mich freuen. Programm besteht aus Unterprogrammen für das übertragen und das Empfangen der Zeichen. Die globale Freigabe erfolgt in der Main-Routine. #include "at89c51cc03.h" #include "stdio.h" #include "MyVariable.h" extern void LCD(void); //---------------------------------------------------------------------- ---------------------------------- void UART_Init(void) { SCON |= 0xD8; //9-bit UART; REN = 1; TB8: 0=logic 0 in 9th bit 1=logic 1 in 9th bit (Transmitter Bit) //RB8: cleared by hardware if 9th bit received is logic 0 SBUF = 0x00; //Speicher leeren TMOD |= 0x20; //Timer1 in Mode 2 = 8-bit auto reload TH1 = 0xF3; //Zähler mit Baudrate 9600/4800 = 243 TL1 = 0xF3; //Zähler mit Baudrate 9600/4800 = 243 ES = 1; //Enable Serial Interrupt } //---------------------------------------------------------------------- ---------------------------------- void UART_Senden(unsigned char DatenS) { SBUF = DatenS; //Schreiben der Daten in SBUF while (TI != 1); //TI wird von Hardware nach Übertragungsende gesetzt TI = 0; } //---------------------------------------------------------------------- ---------------------------------- void UART_Empfangen(void) { BefehlvPC = SBUF; if ((BefehlvPC > 0x20) && (BefehlvPC < 0x7F)) //Nur Zeichen aus Alphabet { Aktualisieren = 1; //Ausgabe LCD } } //------------Interrupt Routine für UART--------------------------------------------------- void interrupt(void) interrupt 4 { if (RI == 1) //Wenn Daten von UART empfangen { UART_Empfangen(); RI = 0; } }
Du verwendest für den Empfang den Interrupt und fürs Senden Polling, das geht so nicht. Du musst entweder beides über Polling oder im Interrupt machen, weil der serielle Interrupt eigentlich zwei Interrupts in einem beinhaltet, nämlich senden und empfangen. Und man kann das nur paarweise aktivieren. Wenn du das Senden über Interrupt machen willst, dann definiere ein Bit, welches der Senderoutine anzeigt, dass wieder gesendet werden darf. Ausserdem solltest du darauf verzichten, die LCD-Ausgabe u.ä. im Interrupt zu machen, weil du sonst u.a. Timing-Probleme bekommst. Auch hier wieder ein Bit, welches anzeigt, dass etwas ausgegeben werden soll, und das Ausgeben in der main machen. Ralf
Ups, sehe gerade, dass im Interrupt "Aktualisieren = 1" steht, hab zu schnell gelesen, sorry. Aber den Mischbetrieb Polling/Interrupt musst du trotzdem vermeiden. Ralf
Und wenn wir schon dabei sind: - wo wird der Timer gestartet? - wo wird EA (globale Interrupt-Freigabe) aktiviert? Ralf
Beides geschieht in meiner Main nachdem ich alle Initialisierungen durchgegangen bin. Ich soll also TI in der ISR zurücksetzen und nicht schon in meiner Funktion UART_Senden? MfG & danke schon mal für deine Hilfe
> Beides geschieht in meiner Main nachdem ich alle Initialisierungen > durchgegangen bin. Ah, okay... > Ich soll also TI in der ISR zurücksetzen und nicht schon in meiner > Funktion UART_Senden? Ja, genau. Und dafür setzt du in der ISR ein Bit, welches der UART_Senden erlaubt, das Zeichen in SBUF zu schreiben. Du machst also die Abfrage "Schreiben in SBUF erlaubt", wenn ja, dann SBUF beschreiben und Bit löschen. Solange es eben gelöscht ist, darf in SBUF nicht geschrieben werden. Ralf
Hi Leute, ich schreib euch nochmals wegen meiner Seriellen Schnittstelle. Ich betreibe meinen µC mit 24MHZ. Ich bekomme jetzt zwar eine Übertragung zustande - jedoch kommt entweder nur Müll an an meinem Hyperterminal oder ich sehe gar nichts. Hat jemand schon Erfahrungen mit 24MHz und serieller Datenübertragung? (Timerwerte usw.) Wäre nett wenn Ihr mir weiterhelfen könnt. Kann es sein dass die 24MHz nicht am besten geeignet sind für die serielle Übertragung? Der Fehler der beim Auf- bzw. Abrunden entsteht ist doch schon relativ groß. Hab mir die Tabelle mal runter geladen für UART und da wäre am besten der Quarz mit 22,1184MHz geeignet. Danke schon mal für eure Hilfe! MfG
Hi, > Hat jemand schon Erfahrungen mit 24MHz und serieller Datenübertragung? > (Timerwerte usw.) Du fragst jetzt aber nicht nach, ob wir bereits selber gerechnet haben? :) Nein, ernsthaft, die ATMEL-Datenblätter sind etwas bescheiden geschrieben. Guckst du hier: http://www.atmel.com/dyn/resources/prod_documents/doc4316.pdf Solltest du dir gleich speichern. Aber beachte, dass nicht alle dort aufgeführten Features für deinen Controller gelten, sondern dass das nur ein Manual für die ganze Familie ist (ATMEL-spezifisch, natürlich)! Auf Seite 99 findest du, was du suchst. Und bevor du fragst, 11.0592 ist die Hälfte von 22.1184 grins > Hab mir die Tabelle mal runter geladen für UART und da wäre am besten > der Quarz mit 22,1184MHz geeignet. Korrekt, das ist ein sog. Baudratenquarz, d.h. damit bekommst du die üblichen Baudraten fehlerfrei hin. Übrigens, auch mit einem solchen Quarz ist es möglich, Timer-Interrupts zu generieren, die exakt z.B. 1ms Takt haben (falls das an anderer Stelle deiner Applikation notwendig sein sollte, RTC o.ä.) Ralf
Natürlich hab ich schon selber gerechnet - aber wie gesagt - hab bis jetzt keine Baudrate gefunden mit der die serielle Übertragung funktioniert. g Ich schreib mal meinen Code mit dem ich die serielle Schnittstelle teste. Das komische ist dass ich ein Zeichen im SBUF empfange - jedoch empfange ich definif nicht das Zeichen auf dem Mikrocontroller das ich aus dem Hyperterminal sende. Das komische daran ist dass wenn ich das gesendete Zeichen zurückschicke - das Zeichen wieder korrekt dargestellt wird. Allerdings kann ich keine Großbuchstaben über Hyperterminal senden - die werden nicht erkannt. (komisch) In dem Code frage ich erst einmal ab ob überhaupt ein Zeichen in SBUF geschrieben wird. Dann habe ich versucht ob das Zeichen korrekt gesendet wird - was allerdings nicht der Fall ist. Hab dann noch versucht ein kleines 'a' == 0x61 zu senden. Jedoch kommt dies auch nicht richtig an. Daher gehe ich davon aus dass ich irgendwelche Timing-Probleme habe. Code: #include "at89c51cc03.h" char uart_data = 0x00; void main (void) { SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */ TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */ TH1 = 0xF6; /* 38400 Bds at 24MHz */ TL1 = 0xF6; ES = 1; /* Enable serial interrupt*/ EA = 1; /* Enable global interrupt */ TR1 = 1; /* Timer 1 run */ P2 = 0xFE; while(1) { if (uart_data != 0x00) { if (uart_data == 0x61) { P2 = 0x00; } SBUF = 0x61; /* Send back same data on uart*/ uart_data = 0x00; } } } void serial_IT(void) interrupt 4 { if (RI == 1) { uart_data = SBUF; RI = 0; /* clear reception flag for next reception */ } else TI = 0; /* if emission occur */ } /* clear emission flag for next emission*/
Hi, na dann gucken wir uns doch die Sache mal gemeinsam an :) Ich empfehl dir, den Anhang ausgiebig zu lesen, der ist allemal besser als der Scheiss, den Atmel Datenblatt nennt. Ich gehe davon aus, das im Hyperterminal 38400, 8n1 und kein Handshake eingestellt ist. Desweiteren nehme ich an, dass der X2-Mode deaktiviert ist, und das Bit SMOD in Register PCON nicht gesetzt ist. Diese beiden Einstellungen beeinflussen nämlich den Clock, den der UART bekommt. > Das komische ist dass ich ein Zeichen im SBUF empfange - jedoch > empfange ich definif nicht das Zeichen auf dem Mikrocontroller das ich > aus dem Hyperterminal sende. Wie erkennst du das? Ausgabe aufs Display, oder wie? > Das komische daran ist dass wenn ich das gesendete Zeichen zurückschicke - > das Zeichen wieder korrekt dargestellt wird. Das ist aus deinem Code aber nicht ersichtlich. Dort schickst du bei jedem Zeichen ein 'a' zurück. > Allerdings kann ich keine Großbuchstaben über Hyperterminal senden > - die werden nicht erkannt. (komisch) Ja, komisch... Kann ich mir grad nicht erklären, aber hängt sicherlich mit den anderen Problemen zusammen, kriegen wir schon hin... > Hab dann noch versucht ein kleines 'a' == 0x61 zu senden. Jedoch kommt > dies auch nicht richtig an. Jetzt blick ich es sowieso nicht mehr, weil einmal sagst du, dass das, was du sendest, wieder korrekt zurückkommt, Großbuchstaben wiederum gehen aber trotzdem nicht, und das Senden eines festen Wertes geht gar nicht. Was denn nun? Also, mal der Reihe nach: fOsc = 24 MHz Baudrate = 38400 BRG: Timer 1, 8-Bit Autoreload Nach der Formel: Baudrate = ((2^SMOD) / 32) * (fOsc / (12 * (256 - TH1)) ergibt sich: Baudrate = 1 / 32 * 24000000 / (12 * (256 - 246) = 6250 Das deckt sich nicht mal ansatzweise mit deinen gewünschten 38400 (vorbehaltlich, dass ich mich nicht verrechnet habe :) Wenn ich TH1 mit 253 ansetze, komme ich auf etwa 20000 Baud, bei 254 komme ich auf 31250 Baud. Selbst mit gesetztem SMOD Bit kommst du auf Werte, die die 3%-Toleranz der Baudrate sprengen, wenn die Geschwindigkeit so hoch angesetzt ist. Setz die Baudrate mal wie in der Tabelle angegeben auf 4800 Baud, d.h. angegebener Reloadwert für 12MHz verwenden, und mit 9600(!) Baud im HyperTerminal arbeiten, weil du ja nicht 12, sondern 24 MHz hast. Eine weitere Alternative wäre, den Timer 2 anstatt Timer 1 zu verwenden, damit bekommst du es vielleicht hin. Ralf
Und nochwas: Wenn Variablen sowohl in der normalen Applikation als auch in Interrupts verwendet werden, sollten sie in C als "volatile" deklariert sein!!! Ralf
Hi Ralf, dann antworte ich mal. :-) Die EInstellungen die Du aufgezählt hast stimmen mit denen überein die ich eingestellt habe. Zu deiner ersten Frage: - Ich bekomme das Zeichen definitiv nicht das ich erstens einmal probiert habe das Zeichen auf einem LCD auszugeben. Dies geschieht aber nicht - stattdessen kommt ein nicht definiertes Zeichen an. Display habe ich zuvor ausprobiert mit einem fest eingestellten Zeichen und habe dies auch ausgegeben. Zweitens habe ich dann probiert dass wenn ein bestimmtes Zeichen empfangen wird ein Pin freigegeben wird an dem eine LED anfängt zu leuchten. Auch dies hat nicht funktioniert. Zu deiner zweiten Frage: - Ist aus diesem Code nicht ersichtlich - habe es aber zuvor ausprobiert und über RS232 und USB getestet. Beides mal kam am Hyperterminal das gesendete Zeichen zurück. Jedoch nur bei den oben genannten EInstellungen. Sobald ich eine andere Baudrate beim Hyperterminal eingestellt habe kam entweder nur "Müll" oder gar nichts mehr an. Zu deinen deiner 3. und 4. Frage: - Ist wie schon gesagt nicht ersichtlich aus dem Code den ich eingestellt habe. Habe aber diverse Versuche schon gestartet um den Problem auf die Schliche zu kommen. Den Wert für den Timer habe ich aus einer Tabelle - die hat sich aber wie ich herausgefunden habe als falsch erwiesen. Die Formel habe ich aus meinem Skript schon gekannt. Habe es ja auch schon mit diesen Werten versucht - jedoch kam ich so auch nicht weiter. Auf die oben genannten Einstellungen bin ich eher zufällig gestossen. Werde ja daraus auch nicht schlau. Deswegen bin ich ja froh dass ich mich hier mit einem User austauschen kann der sich die Zeit mir mit meinen Problemen zu helfen. :-) Werde es jetzt mal versuchen mit deinen Einstellungen zu senden. Mal schauen ob ich in meine Hochschule noch reinkomme. Schon einmal ein großes Dankeschön für deine Hilfe!! MfG Stefan0784
Hi, zu der Displaysache kann ich so im Moment nix sagen, da müsste ich die Software dazu sehen, weil ich nicht weiss, ob man direkt die ASCII-Werte der Zeichen angeben kann, oder einen Offset abziehen muss, das ist immer Display-spezifisch. > Zu deiner zweiten Frage: > - Ist aus diesem Code nicht ersichtlich - habe es aber zuvor ausprobiert > und über RS232 und USB getestet. Beides mal kam am Hyperterminal das > gesendete Zeichen zurück. Jedoch nur bei den oben genannten > EInstellungen. Sobald ich eine andere Baudrate beim Hyperterminal > eingestellt habe kam entweder nur "Müll" oder gar nichts mehr an. Der letzte Satz macht mich stutzig, du hast dann hoffentlich auch im Controller den Reloadwert auf die neue Baudrate angepasst? Sonst wird das nix, beide Teilnehmer müssen vorab bereits wissen, wie schnell kommuniziert wird. Du kannst mit dem Controller auch eine automatische Baudratenerkennung machen, aber soweit habe ich dich noch nicht ;) > Werde ja daraus auch nicht schlau. Deswegen bin ich ja froh dass ich > mich hier mit einem User austauschen kann der sich die Zeit mir mit > meinen Problemen zu helfen. :-) > Werde es jetzt mal versuchen mit deinen Einstellungen zu senden. > Mal schauen ob ich in meine Hochschule noch reinkomme. > Schon einmal ein großes Dankeschön für deine Hilfe!! Kein Problem, ich helfe gern. Kannst ja mal schreiben, wie weit du bist bzw. ob es was gebracht hat. Ralf
Beim Display muss ich keinen Offset-Wert abziehen. Man kann direkt ein ASCI-Zeichen ausgeben. Zu den Einstellungen - ich habe nach jetzt fast einwöchigem Testen und lesen der PDF-Dokumentation einfach mal probiert mit verschiedenen Werten im Timer und im Hyperterminal. Stutzig war ich auch - das darfst Du mir glauben. g Ich stell dann mal meinen neuen Code ein. Habe den Timer mit dem Wert für 4800 Baud geladen, beim Hyperterminal habe ich 9600 eingestellt. Es wird aber leider immer noch nichts gesendet. Kann jetzt leider nur von Hyperterminal über USB den Controller testen - die Profs haben das Kabel weggeschlossen. *D'oh* Funktionieren tut es leider immer noch nicht - Daten werden auf jeden FAll gesendet - haben an den TxD und RxD Leitungen kleine LEDs installiert. Es wird weder der Port2 freigegeben noch wird das Zeichen zurückgeschickt. #include "at89c51cc03.h" volatile char uart_data = 0x00; /** * FUNCTION_PURPOSE: This file set up uart in mode 1 (8 bits uart) with * timer 1 in mode 2 (8 bits auto reload timer). * FUNCTION_INPUTS: void * FUNCTION_OUTPUTS: void */ void main (void) { SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */ TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */ TH1 = 0xF3; /* 9600 Bds at 24MHz */ TL1 = 0xF3; ES = 1; /* Enable serial interrupt*/ EA = 1; /* Enable global interrupt */ TR1 = 1; /* Timer 1 run */ P2 = 0xFF; while(1) { if (uart_data == 0x61) { P2 = 0x00; SBUF = 0x61; /* Send back same data on uart*/ uart_data = 0x00; } } } void serial_IT(void) interrupt 4 { if (RI == 1) { uart_data = SBUF; RI = 0; /* clear reception flag for next reception */ } else TI = 0; /* if emission occur */ }
Hab jetzt mal noch folgendes probiert: . . . while(1) { if (uart_data != 0x00) { P2 = 0x00; SBUF = 0x61; /* Send back same data on uart*/ uart_data = 0x00; . . . Port 2 wird jetzt ausgeschaltet - jedoch wird kein Zeichen zruückgeschickt. Sobald ich jedoch ein spezielles Zeichen abfrage funktioniert es allerdings nicht mehr. Also gehe ich immer noch davon aus dass ich ein Timing-Problem habe. MfG Stefan
Du musst die letzte Spalte der Baudratentabelle beachten, SMOD-Bit in PCON-Register muss 1 sein. Sorry, hatte ich vergessen zu erwähnen. D.h. du arbeitest momentan wirklich mit 4800 Baud. Sorry. Also noch in die Initialisierung rein: PCON |= 0x80 Alternativ wirklich 4800 im HyperTerminal einstellen ;) In deinem vorletzten Posting fragst du aber nur 'a' ab. Alles andere wird ignoriert. Mach mal das: while(1) { if (uart_data != 0x00) { P2++; SBUF = uart_data; /* Send back same data on uart*/ uart_data = 0x00; } } Somit wird erstmal eine Echo-Funktion implementiert. Desweiteren wird Port2 bei jedem empfangenen Zeichen inkrementiert (falls du LEDs dran hast, kannste ja mitzählen :) Ralf
So - hab mir jetzt mal nen Quarz mit 22,1184 MHz besorgt. Hab aber genau die gleichen Probleme. Setz jetzt mal meinen Code für 19200 Baud rein. Im Anhang gibts nen Shortcut vom Hyperterminal. Hab da einfach mal das Alphabet eingetippt. Das Echo vom µC siehst Du ja auf dem Bild. So langsam hab ich die Befürchtung dass es nicht an meinem Quarz oder Timing liegt sondern an nem Bauteil meiner Platine. Code 19200: #include "at89c51cc03.h" volatile char uart_data = 0x00; void main (void) { SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */ TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */ TH1 = 0xFD; /* Baudrate 19200 @ 22,1184 MHz */ TL1 = 0xFD; ES = 1; /* Enable serial interrupt*/ EA = 1; /* Enable global interrupt */ TR1 = 1; /* Timer 1 run */ //PCON |= 0x80; // PCON ist gerade ausgeschaltet P2 = 0xFF; while(1) { if (uart_data != 0x00) { P2 = 0x01; SBUF = uart_data; /* Send back same data on uart*/ uart_data = 0x00; } } } void serial_IT(void) interrupt 4 { if (RI == 1) { uart_data = SBUF; RI = 0; /* clear reception flag for next reception */ } else TI = 0; /* if emission occur */ }
Hab jetzt dann auch mal noch nen Test gemacht mit der doppelten Baudrate. WIe vorher gibts im Anhang das Echo vom Hyperterminal. Ich kann zwar kleine Buchstaben senden - empfange diese auch wieder zurück - allerdings kann ich keine Großbuchstaben senden. Wenn ich dann meine Code dahingehend verändere dass ich ein bestimmtes Zeichen abfrage funktioniert das ganze nicht mehr. So langsam bin ich mit meinem Latein am Ende. Code für Baudrate 38400: #include "at89c51cc03.h" volatile char uart_data = 0x00; void main (void) { SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */ TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */ TH1 = 0xFD; /* Baudrate 19200 @ 22,1184 MHz */ TL1 = 0xFD; ES = 1; /* Enable serial interrupt*/ EA = 1; /* Enable global interrupt */ TR1 = 1; /* Timer 1 run */ PCON |= 0x80; // Baudrate wird verdoppelt P2 = 0xFF; while(1) { if (uart_data != 0x00) { P2 = 0x01; SBUF = uart_data; /* Send back same data on uart*/ uart_data = 0x00; } } } void serial_IT(void) interrupt 4 { if (RI == 1) { uart_data = SBUF; RI = 0; /* clear reception flag for next reception */ } else TI = 0; /* if emission occur */ }
Hallo, ich wäre etwas vorsichtig mit der Zeile zur Baudraten-Verdopplung: PCON |= 0x80; // Baudrate wird verdoppelt Manche 8051er können das, aber ob der CC03er das kann, geht aus dem Datenblatt NICHT eindeutig hervor: (Neueste Version 09_08): auf S.15 gibt es zwar die Bit SMOD1 und SMOD0. Bei der konkreten Beschreibung des SFRs PCON auf S.36 gibt es diese Bits nicht mehr !! Dort sind es auf einmal reservierte Bits, die nicht beschrieben werden dürfen.
Also laut meinem Datenblatt das ich bei Atmel runtergeladen habe steht im PCON Register ganz klar das SMOD1 Bit. Beschreibung: Set to select double baud rate in mode 1, 2 or 3. Trotzdem danke für den Hinweis.
Hallo Stefan, schau mal auf S.36 nach, wo díe Power-Down-Funktion beschrieben wird. Eindeutig ist das alles nicht.
Wenn mal auf Seite 67 schaust steht es ein wenig anders - gehört aber zu dem UART - Kapitel.
Dass der zweite Versuch mit der doppelten Baudrate funktioniert, ist klar, weil du ja nach wie vor das SMOD-Bit setzt. Nach der Tabelle im Hardware Manual sind bei einem Reloadwert von 0xFD und einer Frequenz von 11,0592 MHz sowie gesetztem SMOD-Bit 19200 Baud eingestellt. Du hast aber die doppelte Quarzfrequenz, also dann auch 38400 Baud(!). Das heisst, das einzige Problem ist jetzt noch die Sache mit den Grossbuchstaben, richtig? Gib mal das empfangene Zeichen am P2 aus. Also P2 = uart_data; Nach jedem Zeichen mal die Portbits messen, welchen Zustand sie haben und mit dem Hexwert vergleichen. @Gast: > Manche 8051er können das, aber ob der CC03er das kann, geht aus dem > Datenblatt NICHT eindeutig hervor: Nein, nicht manche, sondern alle können das. Weil der Kern ein 8051 ist, und das ist eine Kernfunktion. Sonst wäre der CC03 kein richtiges 8051-Familienmitglied. > Bei der konkreten Beschreibung des SFRs PCON auf S.36 gibt es diese Bits > nicht mehr !! Bei der konkreten Beschreibung in Table 29, S.67 gibt es das aber wiederum. Deswegen sage ich auch, dass Atmel Datenblätter scheisse sind, weil die Typen einfach immer aus anderen Datenblättern zusammenkopieren, aber nicht anpassen. Die sind einfach faul! Ralf
Hab das Testprogramm quickndirrty mal probiert. Dasselbe Problem wie ursprünglich - funktioniert weder mit 24 MHz noch mit 22,1184. Hab jeweils immer die Einstellungen bei den Timern und im Hyperterminal geändert. Kann leider das gesendete Byte nicht an einem Port anzeigen lassen da ich keinen kompletten zur Verfügung habe. Hab nur 2 Pins am Port 2 frei an denen ich die LEDs habe. IM Anhang häng ich mal unser Schaltbild von unserer Seriellen Schnittstelle rein. Über Pin 2.0 schalten wir zwischen USB und RS232. Ich probier jetzt mal noch ein anderes Testboard von nem Kollegen - die haben nur die RS232 Schnittstelle drauf und nicht wie wir USB und RS232. Dann kann die HardwareSeite mal abchecken - nicht dass ein Bauteil auf unserer Platine nicht mitmacht! Danke schon mal für euer reges Interesse und eure zahlreichen Tipps und Tricks.
Stefan, dann hast du ein Hardwareproblem. Versuch es mal mit teraterm. http://hp.vector.co.jp/authors/VA002416/teraterm.html Das was du ins Terminal Fenster eingibst muß zurückkommen (echo).
> Hab nur 2 Pins am Port 2 frei an denen ich die LEDs habe. > IM Anhang häng ich mal unser Schaltbild von unserer Seriellen > Schnittstelle rein. Über Pin 2.0 schalten wir zwischen USB und RS232. Wenn du munter P2 komplett beschreibst, dann brauchst du dich nicht wundern. Ersetz das Schreiben vom Port 2 mal durch: P2_x = z; //1. freies Bit mit Zustand z beschreiben P2_y = z; //2. freies Bit mit Zustand z beschreiben Ralf
Deswegen hab ich ja auch immer darauf geachtet dass mein Pin 2.0 nicht verändert wird. Oder ändert sich bei P2 = 0xFE bzw. P2 = 0x00 was an Pin 2.0 ???
>> Oder ändert sich bei P2 = 0xFE bzw. P2 = 0x00 was an Pin 2.0 ???
wie meinen :-))
Hi Leute, hab jetzt nochmals was ausprobiert. Hab jetzt einfach mal den Multiplexer überbrückt. Somit kann ich über RS232 von einem Rechner senden und das Signal im µC empfangen und gleich wieder zurück an meinen anderen Rechner senden. Hab jetzt die Timer mit dem Wert für Baud 19200 geladen. Die gleichen Einstellungen hab ich auch ins Hyperterminal vorgenommen. Siehe da - ich kann jetzt korrekt schreiben - heißt - am 2. Rechner kommen die Buchstaben an die ich im ersten ins Hyperterminal eingebe. (Sogar groß und klein) Jetzt die schlechte Nachricht. Wenn ich einen Buchstaben mehrmals hintereinander tippe dann kommt beim 2. mal immer ein falsches Zeichen an. ( Egal ob Groß- oder Kleinschreibung) Wenn ich das Programm dahingehend verändere dass ich ein bestimmtes Zeichen abfrage funktioniert es auch noch nicht. Vielleicht hat einer von euch ja nochmals einen Tipp.
TL1 = 0xFD; warum ? war so nicht in meinem Beispiel. laß das mal weg und dann in main nur while (1); dann muß es zunächst gehen. TeraTerm... ich hatte dir einen Link gesendet und TTerm hat eine Funktion SendFile... damit kannst Du einen kompletten Text Versenden (so schnell kannst Du garnicht Tippen) und es funktioniert.
TL1 ist doch der Reload Wert für TH1??? Mir ist jetzt gerade aufgefallen dass beim weiterleiten sozusagen auch wieder das Signal an den ersten Rechner laufen müsste - dies ist aber nicht der Fall. Habs gerade ausprobiert indem ich in das NullMOdemKabel ein Käbelchen zwischen RxD und TxD gesteckt habe. Also muss ich da mal suchen - evtl. ist da auch noch ein Fehler auf der Platine. Dein Programm hab ich erhalten und auch gezogen - allerdings kann ich es auf den Hochschulrechern nicht installieren da ich kein AdminRechte besitze. Auf meinem Laptop funktioniert es nicht da das Programm nur bis COM4 geht und mein USB an COM 12 hängt.
Schau Dir mal die Grundlagen zu den Timern an. http://www.8052.com/tutser.phtml#Serial%20Mode Das kann doch nicht so schwer sein. Nullmodem Kabel an den MC (verwende mal einen Rechner, nicht 2) und dann sollte es gehen. Ansonsten den MC aus dem Sockel befördern und RXD, TXD verbinden und die Hardware ist bis zum MC getestet.
Genau das will ich nachher auch noch probieren. Danach kommt dann noch das TestProgrämmchen TeraTex. Ich meld mich sobald ich wieder an meine Wissensgrenze stosse.
Hi Leute. Hab das Problem jetzt lösen können. Ich weiß zwar nicht wie es zusammen hängt - aber funktionieren tuts jetzt!!! Bei meinen Versuchen zuvor hatte ich nie den T2CON initialisiert. Der müsste zwar standardmässig auf 0x00 sein - jedoch funktioniert die Serielle Übertragung erst wenn ich es bei mir mit 0x00 initialisiere! Im Anhang findet Ihr nochmals meine Datei für die serielle Übertragung! (Die Kommentare stimmen nicht immer überein mit den Einstellungen) Danke für eure Hilfe - vielleicht hilft es einem anderen mal weiter wenn er diesen Beitrag hier liest!
> Bei meinen Versuchen zuvor hatte ich nie den T2CON initialisiert. > Der müsste zwar standardmässig auf 0x00 sein. Da wär ich nicht so sicher, dazu müsstest du aber wirklich alles hier rein stellen, also auch das, was der Controller in der durch den C-Compiler vorgegebenen Initialisierung macht! Ralf
Bei der Galvanischen Trennung hast du ein VCC VCC_SER Problem beim zweiten Koppler von unten. Und die beiden oberen Verstehe ich garnicht was die sollen.
Also funktionieren tut jetzt alles - Hardware war bzw. ist definitiv nicht das Problem. Könnte aber sein dass auf dem Schaltbild dass ich oben eingestellt habe noch ein Fehler ist denn wir aber in der jetzigen Version ausgemerzt haben. :-)
> Du meinst die Header-Datei die Initialisiert wird?
Nein, Header werden nicht "initialisierst". Die werden verwendet, um dem
Compiler mitzuteilen, welches SFR an welcher Adresse liegt, oder um
Einstellungen machen zu können, z.B. Puffergrößen usw.
Was ich meine ist, dass jeder C-Compiler für einen Controller
üblicherweise eine Initialisierung durchführt, die noch vor der
main()-Funktion liegt. Dort wird dann üblicherweise das RAM gelöscht,
usw.
Wenn dort was mit deinem TCON passiert, dann ist der beim Aufruf deiner
main()-Funktion nicht mehr (wie erwartet) 0x00 (oder genauer gesagt =
dem Wert nach dem Reset).
Welchen Compiler verwendest du? Keil C51? Dort heisst die Datei
STARTUP.A51 und sollte im Projekt-Verzeichnis liegen (bei
Projekterstellung wird gefragt, ob sie ins Verzeichnis kopiert werden
soll). Du müsstest sie auch im Projektfenster in µVision sehen können.
Ralf
Jou - benutze den Keil C51 Compiler. Ich schau mal nach - wie dieser den T2CON initialisiert. Was mir halt so komisch vorkommt ist, dass ich den Timer2 eigentlich gar nicht verwende - und der Timer für die Baudrate ist ja eigentlich der Timer1.
Ja, aber Timer 2 kann die Baudrate ebenfalls generieren, wenn TCLK oder RCLK (entsprechend für Rx und Tx) in T2CON gesetzt sind. Somit wäre es z.B. möglich, entweder komplett mit Timer 2 zu arbeiten, oder für den Empfang und das Senden mit unterschiedlichen Baudraten zu arbeiten. Ralf
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.