Hallo miteinander, ich versuche grad Daten über meine Serielle Schnittstelle mittels printf() zu schicken. Damit er die Daten überhaupt an den Sendebuffer übergibt, musste ich die putchar() überschreiben. Das habe ich wie folgt gemacht: char putchar (char c) { while (!TI); TI = 0; return (SBUF = c); } Mein ganzes Programm sieht so aus: #include <reg515c.h> #include "lcd_c0.c" #include "stdio.h" void main() { TMOD = 0x10; // Timer 1 autoreload TH1 = 0xf5; // reload value for 9600 Baud TR1 = 1; // Timer1 starten SM1=1; //|\__ Serial Channel in mode 1 SM0=0; //|/ lcd_init(); lcd_clr(); while(1) { TI=1; printf("Test"); lcd_clr(); lcd_str("Test"); } } char putchar (char c) { while (!TI); TI = 0; return (SBUF = c); } Nun läuft das Programm bis an die Stelle while(!TI); . Dort bleibt es dann hängen. Kommentiere ich die Schleife aus, schreibt er mir immer den letzten Buchstaben auf die Serielle Schnittstelle. Irgendwie wird das Transmit-Interrupt flag nicht gesetzt. An was kann das liegen?
Hi, "TMOD = 0x10" konfiguriert den Timer 1 auf Mode 1, 16-Bit, nicht auf Mode 2, 8-Bit mit Autoreload. Das muss also 0x20 heissen. Da es sich bei TMOD um ein Register handelt, welches zwei Peripherie-Einheiten bedient (Timer 0 und 1), würde ich dir empfehlen, die Konfiguration so vorzunehmen: TMOD &= 0x0F; //Alle relevanten Flags für Timer 1 löschen TMOD |= 0x20; //Alle nötigen Flags für Timer 1 setzen Das sorgt dafür, dass wenn du irgendwo Timer 0 konfigurieren möchtest, du nicht die Konfiguration für beide in einem Rutsch machen musst. Das halte ich für übersichtlicher, weil dann die Konfiguration immer dort gemacht wird, wo sie gebraucht wird. Ist aber Geschmackssache. Ralf
Hallo Ralf, danke für die Schnelle Antwort, aber das hat mein Problem leider auch nicht behoben. Mein TI wird irgendwie nie gesetzt und mein Programm bleibt in der while-Schleife in putchar() hängen...
Versuchs mal damit: TI Flag in Interrupt zurücksetzen und in putchar warten, bis letztes Byte gesendet wurde. //************ UART Interrupt ************** void receive_Int( void ) interrupt 4 { if(RI==1) // Byte empfangen { lkjafkljaskdfj........ jadsfjaskldf........ RI=0; } // Ende von if RI ==1.. if(TI==1) // Byte gesendet { TI=0; } } // ***************************************** char putchar (char c) { while (TI==1); return (SBUF = c); }
Du darfst TI = 1 nicht in der while(1) Schleife setzen, weil es sein kann, dass der letzte Buchstabe noch nicht gesendet wurde. Das hilft zwar nicht ganz weiter, ist aber trotzdem ein Fehler. Du musst es vor der while Schleife setzen. Dass TI NIE gesetzt wird, glaub ich nicht. Sobald etwas in SBUF geschrieben wird, wird auch etwas über die serielle rausgepustet, und am Ende der Übertragung das TI Flag gesetzt. Woher weisst du denn, dass das Programm genau bei der Abfrage von TI hängenbleibt? Simulator? Oder nur die Zeile auskommentiert und probiert? Was macht denn der Compiler aus der Abfrage, also welche Assembler Befehle kommen denn da raus? Kannst du die mal posten? Ralf
Schau mal ins Handbuch oder auch beispielsweise in Quellcodebeispielen nach. TI wird immer dann gesetzt, wenn das Zeichen gesendet wurde (vor dem Stopp-Bit). Dann musst Du bloß in der ISR das TI rücksetzen und ggf. weitere Zeichen senden. Um auf meinen Vorschreiber bezug zu nehmen... du musst nicht nur ES=1 setzen, sondern auch EAL (enable all interrupts). Die Maskierten sind dabei außen vor...
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.