Hallo, ich versuche gerade meine erste UART anwendung in C zu erstellen und habe da ein kleines problem. wenn ich den empfangsbuffer am M16C auslese bekomme ich diesen string: 'Hallo Welt/n' das ganze würde ich gerne am angeschlossenen LCD ausgeben. wenn ich es nun mit sprintf in einen buffer kopiere und ausgebe bekomme ich nur ein "H" am LCD. Wie kann ich den gesamten string ausgeben? mir ist zwar klar das 'Hallo Welt/n' und "Hallo Welt/n" nicht das selbe ist. welches von beiden ist aber jetzt ein character string? lg, looxer
ok, soweit is mir das schon klar gewesen. aber ein character der aus mehreren zeichen besteht, ist das immer noch nur ein character? und vor allem wie mache ich daraus einen string?
es gibt keinen character des aus mehreren Zeichen besteht :) mitdemzaunpfahlwink Aber gut, ich denke das ist dir klar. Ein String ist ja im Grunde genommen nichts andere als eine An-Einanderreihung mehrerer Character (Stichwort Arrays). Du könntest z.B. versuchen deinen Satz aus eben so einem Array Stück für Stück an das Display auszugeben. Beispiel wäre:
1 | int i; |
2 | char der_text[10]; //Character Array mit 10 Stellen |
3 | der_text = "Hallo Welt"; // zufälligerweise genau 10 Stellen ;) |
4 | |
5 | for (i=0;i<=9;i++) { |
6 | sprintf("%c",der_text[i]); |
7 | }
|
obs jetzt funktionieren wird kann ich nicht mit 100%iger Sicherheit sagen - aber probiers einfach mal!
>"der_text = "Hallo Welt"; // zufälligerweise genau 10 Stellen ;) Das sind aber 11 Zeichen (\0) >der_text = "Hallo Welt"; Das geht nicht. Wenn dann
1 | char der_text[] = "Hallo Welt"; |
oder eben mit strcpy.
>sprintf("%c",der_text[i]);
sprintf dient zum "drucken" einer Zeichenkette in ein String. ( int
sprintf ( char * str, const char * format, ... ); )
printf wäre da besser.
Und wegen der Null-Terminierung kann man auch schreiben
1 | i=0; |
2 | while(der_text[i]) |
3 | putchar(der_text[i++]); |
Fürs senden eines Strings oder Char würden für einen AVR die Funktionen z.B. so aussehen:
1 | void uart_putc(char c){ |
2 | while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */ |
3 | |
4 | UDR = c; /* sende Zeichen */ |
5 | }
|
6 | |
7 | void uart_puts (char *s) |
8 | {
|
9 | while (*s){ |
10 | uart_putc(*s); |
11 | s++; |
12 | }
|
13 | }
|
erstmal vielen dank für eure antworten! ich habe beide ansätze probiert, leider funktionieren sie aber nicht. wenn ich den string "Hallo Welt/n" verwende dann klappt ja alles. mit 'Hallo Welt/n' bekomme ich wieder mein H am LCD und dannach irgendwelche wirren zeichen. Ich schätze mal das hier einfach über die array grenze hinaus gelesen wird.
'.' macht eine Zeichenkonstante. Mit der kannste rechnen, wie mit jeder anderen Zahl auch. 'a' ist z.B. gleich 97. "...." ergibt einen Zeiger auf das erste Zeichen (i.S.v. Zeichenkonstante, s.o.) zurück, dem alle weiteren Zeichen zwischen den Gänsefüßchen folgen, mal einfach ausgedrückt.
"wenn ich den string "Hallo Welt/n" verwende dann klappt ja alles" Wenn alles klappt, wo ist jetzt das Problem? "mit'Hallo Welt/n' bekomme ich wieder mein H am LCD" Ist ja klar, ' ' benutzt man ja auch für einzelne Zeichen = Character und nicht für Zeichenketten = String.
schon klar, aber ich bekomme genau das 'Hallo Welt/n' aus meinem UART empfangsregister raus.
Hi >schon klar, aber ich bekomme genau das 'Hallo Welt/n' aus meinem UART >empfangsregister raus. Gar nicht. Das UART-Empfangsregister kann nur ein Zeichen enthalten. Das heisst du musst die einzelnen Zeichen nach Eintreffen aus UDR auslesen und deinen String basteln. Einzelheiten stehen im Datenblatt. Sogar in C. MfG Spess
Ich kenne zwar den "M16C" nicht und weiss auch nicht,wie dein Code aussieht (den du hier ja nicht mitgeliefert hast), aber ein UART-Empfangsregister in einem Mikrocontroller kann immer nur EIN Byte aufnehmen. Du musst dich normalerweise in deinem Code selber darum kümmern, dass du einen FIFO*-Buffer anlegst und diesen auch korrekt füllst und ausliest. Wenn du bloss das Empfangsregister ausliest, bekommst du logischerweise immer nur ein einziges Zeichen angezeigt. *: FIFO: First In, First Out. Das zuerst geschriebene Byte wird auch als erstes aus dem Buffer ausgelesen. Normalerweise sieht das so aus, dass du in der RX-Interrupt-Funktion des UART (=ein einzelnes Zeichen wurde empfangen) das empfangene Zeichen in deinen (von dir per Code angelegten und per Code verwalteten) FIFO schreibst und dabei eine globale Variable (z.B. genannt "rx_count") hochzählst, die dir die Anzahl der empfangenen Zeichen anzeigt. Mit einer ausserhalb des Interrupt verwendeten Funktion "getchar" (die ebenfalls von dir selber angelegt werden muss) holst du dir dann bei Bedarf ein Zeichen nach dem anderen aus deinem FIFO, wobei bei jedem Auslesen eines Zeichens rx_count um eins vermindert wird. Entsprechende funktionsfähige Beispiele gibt es zu hunderten im Netz und normalerweise sind auch entsprechende Funktionen in den Libs des C-Kompilers zu finden. Ob diese Funktionen bei dir schon vorhanden sind (oder ob du sie erst selber schreiben musst) sollte aber in der Dokumentation deines Compilers stehen. Ich würde dir auch empfehlen, erst ein mal Tutorials oder Bücher über C-Programmierung zu lesen. Leider fehlt's bei dir schon an ganz grundlegenden Kenntnissen wie z.B. dem Unterschied zwischen char und string.
ok, ich weis von output eines port sniffers das am uart ein string in dieser form kommt: Hallo Welt\n wenn ich nun den interrupt nur dazu verwende ein flag zu setzen mit dem ich dann an andere stelle das auslesen des uart buffers zu triggern, dann füllt sich der buffer mit lauter "H" auf. hier noch der source: ich stell an den übrigens nicht die anforderung perfekt programmiert zu sein, sondern einfach nur mal mehr als nur das erste zeichen vom uart auszugeben. ich habe ihn vom restlichen programm bereinigt. hoffentlich hab ich nicht zu viel gelöscht. #include "skp_bsp.h" // include SKP board support package #include "stdio.h" #define BAUD_RATE_UART 19200 // Baudrate for UART /* Prototype declarations */ void mcu_init(void); // MCU initialization included in mcu_init.c void uart_init(void); // UART initialization void periph_init(void); // Timers and IRQ's initialization /* global variable declarations */ char U0_in; // declare UART0 receive variable /* Interrupt function declarations */ #pragma INTERRUPT U0rec_ISR // vector modified in sect30_28skp_uart.inc void U0rec_ISR (void); // Interrupt routine for UART0 Receive // DEBUG declarations unsigned char buffer[35]; unsigned char temp[3]; int x; /*********************************************************************** ******* Name : main Parameters : none Returns : nothing Description: Main procedure ************************************************************************ ******/ void main(void) { periph_init(); // Initialize timers, ADC and IRQ's while (1){ while (U0_in) { while (x <= 35) { buffer[x] = (char)u0rb; x++; } U0_in = 0; DisplayString(LCD_LINE2, buffer); x=0; } } } /*********************************************************************** ****** Name: UART0 Receive Interrupt Routine Parameters: none Returns: none Description: Interrupt routine for UART0 receive Reads character received from keyboard and stores U0_in variable ************************************************************************ *****/ void U0rec_ISR(void){ while(ri_u0c1 == 0); // make sure receive is complete U0_in = 1; // read in received data } /*********************************************************************** ****** Name: periph_init Parameters: none Returns: none Description: initualizes all peripherialy for this uC ************************************************************************ *****/ void periph_init(void) { mcu_init(); // Initialize MCU InitDisplay(); // Initialize LCD uart_init(); // Initialize UART } /*********************************************************************** ****** Name: uart_init Parameters: None Returns: None Description: Uart0 initialization - 19200 baud, 8 data bits, 1 stop bit, no parity. ************************************************************************ *****/ void uart_init(void) { u0brg = (unsigned char)(((f1_CLK_SPEED/16)/BAUD_RATE_UART)-1); // set UART0 bit rate generator /* bit rate can be calculated by: bit rate = ((BRG count source / 16)/baud rate) - 1 in this example: BRG count source = f1 (10MHz) baud rate = 19200 bit rate = ((10MHz/16)/19200) - 1 = 31 ** one has to remember that the value of BCLK does not affect BRG count source */ ucon = 0x00; // UART transmit/receive control register 2 /* 00000000; // transmit irq not used ||||||||______UART0 transmit irq cause select bit, U0IRS |||||||_______UART1 transmit irq cause select bit, U1IRS ||||||________UART0 continuous receive mode enable bit, U0RRM - set to 0 in UART mode |||||_________UART1 continuous receive mode enable bit, U1RRM - set to 0 in UART mode ||||__________CLK/CLKS select bit 0, CLKMD0 - set to 0 in UART mode |||___________CLK/CLKS select bit 1, CLKMD1 - set to 0 in UART mode ||____________Separate CTS/RTS bit, RCSP |_____________Reserved, set to 0 */ u0c0 = 0x10; // UART0 transmit/receive control register 1 /* 00010000; // f1 count source, CTS/RTS disabled, CMOS output ||||||||______BRG count source select bit, CLK0 |||||||_______BRG count source select bit, CLK1 ||||||________CTS/RTS function select bit, CRS |||||_________Transmit register empty flag, TXEPT ||||__________CTS/RTS disable bit, CRD |||___________Data output select bit, NCH ||____________CLK polarity select bit, CKPOL - set to 0 in UART mode |_____________Transfer format select bit, UFORM - set to 0 in UART mode */ u0c1 = 0x00; // UART0 transmit/receive control register 1 /* 00000000; // disable transmit and receive ||||||||______Transmit enable bit, TE |||||||_______Transmit buffer empty flag, TI ||||||________Receive enable bit, RE |||||_________Receive complete flag, RI ||||__________Reserved, set to 0 */ u0mr = 0x05; // UART0 transmit/receive mode register /* 00000101; // 8-bit data, internal clock, 1 stop bit, no parity ||||||||______Serial I/O Mode select bit, SMD0 |||||||_______Serial I/O Mode select bit, SMD1 ||||||________Serial I/O Mode select bit, SMD2 |||||_________Internal/External clock select bit, CKDIR ||||__________Stop bit length select bit, STPS |||___________Odd/even parity select bit, PRY ||____________Parity enable bit, PRYE |_____________Reserved, set to 0 */ u0tb = u0rb; // clear UART0 receive buffer by reading u0tb = 0; // clear UART0 transmit buffer DISABLE_IRQ; // disable irqs before setting irq registers s0ric = 0x04; // Enable UART0 receive interrupt, priority level 4 ENABLE_IRQ; // Enable all interrupts u0c1 = 0x05; // UART0 transmit/receive control register 1 /* 00000101; // enable transmit and receive ||||||||______Transmit enable bit, TE |||||||_______Transmit buffer empty flag, TI ||||||________Receive enable bit, RE |||||_________Receive complete flag, RI ||||__________Reserved, set to 0 */ }
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.