Hallo Leute, ich hab einen ATMEGA 8535 und ein Problem mit dem USART! Wenn ich im C-Programm folgendes reinschreib: usart_transmit(4); dann kommt im Hyperterminal ein schwarzes Karo an. --> Das ist der ASCII Code für die Zahl 4. Wenn ich im C-Programm folgendes reinschreib: usart_transmit("4"); 1) Dann kommt im Hyperterminal auch eine 4 an. So hätt ichs gern. In meinem Programmablauf möchte ich nun eine Zahl, die in ticks steht und größer als 256 ist über usart_transmit senden. Quellcode: 2) unsigned char *p = (unsigend char*) & ticks; unsigned char low_byte = p[0]; unsigned char high_byte = p[1]; usart_transmit(low_byte); usart_tranmist(high_byte); Wenn ich das jetzt so ins C-Programm schreib, kommen im Hyperterminal wieder diese ASCII Steuer- zeichen an. Ich möchte aber gerne die Zahlen sehen. Frage: Kann man irgendwie den Code 2) so umformen, dass er dem Code 1) entspricht???? sodass ich im HyperTerminal auch die Zahlen empfange??? Ich brauch dringend eure Hilfe, komm einfahc nicht mehr weiter.... gruß beni
"dann kommt im Hyperterminal ein schwarzes Karo an. --> Das ist der ASCII Code für die Zahl 4." Nö, das ist kein ASCII. "Wenn ich im C-Programm folgendes reinschreib: usart_transmit("4"); 1) Dann kommt im Hyperterminal auch eine 4 an. So hätt ichs gern." Das ist dann ASCII. Programmiertechnisch ist das am einfachsten mit printf() zu erledigen, kannst es aber auch "zu Fuss" machen, braucht dann wesentlich weniger Code. Dazu die Zahl in bis zu 5 einzelne chars aufteilen (10.000er, 1000er, 100er, 10er, 1er), zu jedem Wert noch 0x30 addieren, fertig.
Vieeeelen Dank für die Antwort. Aber ich bin in C net so fit! Wenn das so wenig Code ist, könntest du mir den vielleicht noch ins Forum schreiben??? Also wie ich die Zahl in 5 einzelne Chars aufteile. Wär nett, danke gruß bnei
#include <stdio.h> . . . printf ("\r\n%u",deine_zahl); //sendet deine_Zahl als ASCII-String mit vorangestelltem Zeilenvorschub (\r\n\) als Trennzeichen. Formatsteuerung %u gibt an, das das Argument als vorzeichenlose Dezimalzahl ausgegeben wird.
Hä? muss das dann so heißen: unsigned char *p = (unsigned char *) & ticks; unsigned char low_byte = p[0]; unsigned char high_byte = p[1]; usart_transmit(printf ("\r\n%u",low_byte))); usart_transmit(printf ("\r\n%u",high_byte))); geht aber net, beim ersten Aufruf kommen nur Leerzeichen und bei jedem weiteren kommen nur Häuschen an... gruß beni
Hallo Beni, im Anhang liegt eine Assemblerdatei für AVR-GCC (WinAVR) die eine Binärzahl in ein ASCII-Zeichen umwandelt. Ein kleines Beispiel: char buf[4]; bin2ascii8(1, buf, 1); // String "1" bin2ascii8(1, buf, 2); // String "01" bin2ascii8(199, buf, 3); // String "199" Gruß Fiffi
Für die Umwandlung von int nach String gibt es beim WinAVR fertige Routinen ! Siehe auf AVR-Libc Manual #include <stdlib.h> char buffer[7]; int num=134; /* convert interger into string */ itoa( num , buffer, 10); -> Konvertiert Wert 137 in String "137"
Hallo Peter, >Für die Umwandlung von int nach String gibt es beim WinAVR fertige >Routinen ! Siehe auf AVR-Libc Manual Das weiß ich ... 1. itoa verbracht ~160 Byte Code, meine Routine verbraucht ~62 Byte Code. 2. itoa arbeitet mit "int" und überschreibt immer 4 Zeichen in dem Puffer. Meine Routine arbeitet zwar nur mit "char", dafür kann man die Breite aber einstellen ... Meiner Meinung nach ist itoa nicht oft zu gebrachen ... Gruß Fiffi
Erstmal vielen Dank für eure Hilfe. @ Fiffi: Ich kann doch in mein C Programm keine Assembler Datei miteinbinden. Der Compiler bringt nur Fehler!!!! Deswegen hab ich die zweite Methode mit itoa versucht: Da kommt aber nie das raus, was ich gern hät: Wenn ich die Zahl 134 versenden möchte: char buffer[7]; unsigned int ticks=134; usart_transmit(itoa( ticks2, buffer, 10)); Im HyperTerminal kommt aber nur 0 an!!! Wenn ich die Zahl 3 versenden möchte: char buffer[7]; unsigned int ticks=3; usart_transmit(itoa( ticks, buffer, 10)); kommt im HyperTerminal auch nur ne 0 an!!! Wenn ich diesen Code eingebe: unsigned int ticks = 5321; char buffer[7]; unsigned char *p = (unsigned char *) & ticks; unsigned char low_byte = p[0]; unsigned char high_byte = p[1]; usart_transmit(itoa( low_byte , buffer, 10)); usart_transmit(itoa( high_byte , buffer, 10)); Kommen im Hyperterminal: HH an!!! Was mach ich denn immer noch falsch??? Ach ja, die Zahl die ich senden möchte beträgt maximal 65536! Mit usart_transmit kann ich nur ein Byte senden. Deswegen die Aufteilung im letzten Quellcode! Um wieder auf 5321 zu kommen muss ich dann am Computer diese Formel ausrechnen: 5321 = erste_Zahl + zweite_Zahl * 256 Ich bitte nochmals um Hilfe gruß beni
wenn du noch nicht so fit bist, dann nimm doch erstmal die einfachste Variante! unsigned int ticks = 5321; printf ("%u",ticks); Ja, es gibt codeeffizientere Methoden, aber was soll das hier??
Hallo crazy horse, also ich hab jetzt deine einfachste Methode benützt. --> unsigned int ticks = 5; usart_transmit(printf ("%u",ticks)); Ich hab den Code auf ein Taster gelegt, sodass wenn ich diesen drücke, die 5 gesendet wird. Beim ersten drücken kommt im Hyperterminal ein Leerzeichen an. Bei jedem weiteren Drücken ein Häuschen!!!!!!!! keine Spur von einer 5. An was liegt das? Was muss ich anders machen? ach ja hier noch die routine usart_transmit(){ void usart_transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while ( !( UCSRA & (1<<UDRE)) ) ; /* Put data into buffer, sends the data */ UDR = data; } gruß beni
Würde einmal Ascii Zeichen schicken ! unsigned int ticks = 5; usart_transmit(printf ("%u",ticks + 0x30)); Josef
>Ich kann doch in mein C Programm keine Assembler Datei miteinbinden. Ja aber der Linker kann assemblierte Assembler Daten zusammenfügen >Deswegen hab ich die zweite Methode mit itoa versucht: >Da kommt aber nie das raus, was ich gern hät: >Wenn ich die Zahl 134 versenden möchte: Bitte schaue in der Doku nach wie die Parameter der itoa() Funktion lauten. >Mit usart_transmit kann ich nur ein Byte senden. Du musst eben eine Schleife programieren: char *p = buffer; while ( *p ){ usart_transmit(*p++) }
Meine Herren, das kann doch alles nicht wahr sein. Vergiss doch erstmal dein usart_transmit(), printf() benutzt die Routine putchar() für die Ausgabe.
@Josef: Das + 0x30 macht keinen Unterschied. Es kommt das gleiche im HyperTerminal an! @crazy horse: das heißt also, dass dieser Ausdruck: #include <stdio.h> unsigned int ticks = 5321; printf ("%u",ticks); ALLEINE, ohne irgendwelches usart_transmit die Zahl 5321 ans HyperTerminal sendet???? Kann nicht sein, hab ich nämlich schon ausprobiert, kommt gar nix an. (Kein Leerzeichen, nichts) Es gibt hier glaub ich missverständnisse: Frage: Kann mir jemand den Code sagen, der eine Zahl in einen String umwandelt und dann mit usart_transmit() sendet? Sodass im Hyperterminal auch diese Zahl ankommt? gruß beni
Was benutzt du denn für einen gestutzten Compiler? Printf() sollte eigentlich bei JEDEM funktionieren, das ist die zentrale Ausgabefunktion von C.
Hi printf() beim AVRGCC funktioniert aber nur mit einer zusätzlichen Routine die die einzelnen Zeichen ausgibt. Und diese Funktion muß man selber bereitstellen. Lösung: char buffer[7],i,*s; unsigned int ticks=134; itoa( ticks2, buffer, 10); s=buffer; while(*s) { usart_transmit(*s); s++; } Matthias
ach du Elend, was ist denn das fürn Ding?? Dann kauf ich mir doch lieber was ordentliches als mich mit solchen Sachen rumzuplagen. Gibts einen bestimmten Grund, warum das beim GCC nicht drin ist?
Hi woher soll denn der AVRGCC wissen wohin die Ausgabe von printf soll? LCD? RS232? USB? Parallel? I2C? SPI? Und eben dafür, um die Ausgabe eines Zeichens zu realisieren, muß man eine eigene Routine bereitstellen. Matthias
dafür passt man normalerweise die Funktion putchar() an, wenn man was anderes als die (für MCs eigentlich Standartschnittstelle UART) benutzen will. Aber das nützt ja jetzt auch alles nicht :-)
// UART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // UART Receiver: Off // UART Transmitter: On // UART Baud rate: 38400 UCR=0x08; UBRR=0x0C; //***********************Zahl in BCD umrechnen und an Anzeige schreiben******************************* void Convert_Numb (int Zahl) { int Help; Help = Zahl / 1000; Byte_T = Help + 0x30; Zahl = Zahl - (Help * 1000); Help = Zahl / 100; Byte_H = Help + 0x30; Zahl = Zahl - (Help * 100); Help = Zahl / 10; Byte_Z = Help + 0x30; Zahl = Zahl - (Help * 10); Help = Zahl; Byte_E = Help + 0x30; } //**********************//4 Zeichen an die Matrix-LCD************************************** //Hier ein Macro zum Zeichen ausgeben #define Put_Char(Data) while (( USR & b00100000) == 0); UDR = Data; //Ein Zeichen an die UART //Zahl ausgeben Put_Char(Byte_E); Put_Char(Byte_Z); Put_Char(Byte_H); Put_Char(Byte_T); //Alles getestet -läuft gut Byte_x sind als globale Variablen zu definieren //nicht allzu elegant, funktioniert aber super und brauch fast keinen Code Josef
Hallo Matthias, vieeeeeeelen Dank für diesen genialen Code. Es funktioniert!!!!!!!!!! Endlich, nach so langem rumprobieren. Hab absolut keine Probleme mehr. Juhuuuuu
ne den von Matthias. Hab den ersten genommen, weil er der erste war und der Code so schön klein. Hät er nicht funktioniert hätt ich deinen genommen Josef!
hallo, bin grad, jahre nach dem originalen post, über diese diskussion gestolpert. ich möchte keinesfalls gemein sein oder so, jeder beginnt irgendwo mal. jedoch frag ich mich wie man auf die idee kommt, µC programmieren zu wollen ohne den geringsten dunst von c zu haben. bitte leute, kauft euch mal ein gutes buch, denken drücken sprechen. hochachtungsvoll.
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.