Du gibst alles auf PortC aus was ankommt. Wenn du das nicht willst musst du filtern.
Schönen guten Tag,
ich bin ein ziemlicher Neuling in der Mikrocotroller Programmierung und taste mich nun langsam voran. Nachdem das Senden von Daten vom Controller an den PC wunderbar geklappt hat, wollte ich den Spieß mal umdrehen.
Zum Porgramm: Durch das eingeben von Befehlen wie "0b11111001" sollten die LED's am PORTC im angegebenen Muster aufleuchten. Jedoch springen die LED's bereits bei der kleinsten Eingabe, z.B. auch den Drücken der Leer- oder Pfeiltasten, wild hin und her und ich kann keine Logik dahinter erkennen.
Ich benutze den AT19CAN128, im HyperTerminal sind eingestellt: Baudrate 9600, 1 Stoppbit, kein Handshaking, 8-bit.Code:#include <avr/io.h> #define F_CPU 16000000UL // Systemtakt in Hz - Definition als unsigned long beachten #define BAUD 9600UL // Baudrate #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler. #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! #endif #include "util/delay.h" uint8_t uart_getc(void) { while (!(UCSR0A & (1<<RXC0))); // warten bis Zeichen verfuegbar return UDR0; // Zeichen aus UDR an Aufrufer zurueckgeben } int uart_putc(unsigned char c) { while(!(UCSR0A & (1<<UDRE0))) { } _delay_ms(100); UDR0= c; } void uart_puts (char *s) { while (*s) { uart_putc(*s); s++; } } int main(void) { UBRR0H = UBRR_VAL >> 8; UBRR0L = UBRR_VAL & 0xFF; UCSR0C=(0<<UMSEL0)|(1<<UCSZ00)|(1<<UCSZ01); //Asynchroner Mode, 8-bit UCSR0B= (1<<TXEN0)|(1<<RXEN0); //Transmitter einschalten while(1) { if ( (UCSR0A & (1<<RXC0)) ) { uint8_t c; c = uart_getc(); DDRC = 0xFF; PORTC = c; _delay_ms(200); } else { // Kein Zeichen empfangen, Restprogramm ausführen... } } }
Ich bedanke mich schonmal für die Hilfe!
Du gibst alles auf PortC aus was ankommt. Wenn du das nicht willst musst du filtern.
AT19.. ?? Vermutlich den AT90.. oder nicht?... Ich benutze den AT19CAN128 ...
Was bitte steht im Restprogramm ??Code:... int main(void) ... else { // Kein Zeichen empfangen, Restprogramm ausführen... } ...
Nachtrag:
Du gibst also 1111 1001 auf Deine LED-Leiste aus, danach Leer- und Pfeiltasten über die Tastatur - und das Terminal übermittelt die an den Controller (der Code ist mW der in C übliche Tastaturcode). Hubert hat Dir ja schon das Problem genannt, im Einzelnen ist Deine Eingabe dadurch
1111 1001
0010 0000 Leertaste
0100 1000 Pfeil auf
0100 1011 Pfeil links
0100 1101 Pfeil rechts
0101 0000 Pfeil ab
Geändert von oberallgeier (18.11.2014 um 09:59 Uhr) Grund: Tastenspielereien
Ciao sagt der JoeamBerg
Ja AT90 natürlich, da habe ich mich verschrieben.
Okay das leuchtet mir ein, aber selbst wenn ich nur ein Muster wie 01101101 eingebe warden nicht die richtigen LED's geschaltet. Die Belegung der LED's ist definitive richtig, die habe ich bereits über ein "normales" Programm getestet.Du gibst also 1111 1001 auf Deine LED-Leiste aus, danach Leer- und Pfeiltasten über die Tastatur - und das Terminal übermittelt die an den Controller (der Code ist mW der in C übliche Tastaturcode). Hubert hat Dir ja schon das Problem genannt, im Einzelnen ist Deine Eingabe dadurch
1111 1001
0010 0000 Leertaste
0100 1000 Pfeil auf
0100 1011 Pfeil links
0100 1101 Pfeil rechts
0101 0000 Pfeil ab
a) Wie gibtst Du das Muster ein?Ja AT90 natürlich, da habe ich mich verschrieben ... 01101101 eingebe warden nicht die richtigen LED's geschaltet ...
b) Gib doch bitte mal "m" ein.
c) Sind die LEDs alle richtig gepolt? Müssten ja, sonst gingen andere Tests nicht wie gewünscht :-/
Ciao sagt der JoeamBerg
Ahhh okay das Problem habe ich schon so halb herausgefunden. Auch ein Leerzeichen hat lt. ASCII einen Code und wird dann sofort auf den Controller übertragen. Und auch wenn ich ein Muster eingebe, wird jedes einzelne Zeichen als String übertragen.
Das heißt ja im Klartext, beim Eingeben der Daten muss so lange mit der Übermittlung an den Controller gewartet warden, bis ich mein vollständiges Muster übergeben habe. Nun aber die Frage "wie"?!
Muss ich oben das beim uart_puts() angeben? Also z.B. in dem ich sage, speicher die so lange bis ein Enter (das dann im ASCII-Code) auftritt? Oder gibt es da Einstellungen im HyperTerminal?
Da bin ich jetzt froh, dass mein (stiller) Verdacht sich bewahrheitet - Du hattest Deine LED-Muster als Tastatureingabe - Zeichen für Zeichen als einzelne Zifferntasten an den Controller geschickt. Da kommt dann natürlich ein einzelnes [m][RETURN] beim Controller eben tatsächlich als "01101101" an, eben als genau diese BIT-Folge, ein einzelnes "1" als "00110001" und eine "0" als 00110000. Wegen dieses Verdachtes kam ja genau meine Frageliste :.-.)... Problem... so halb herausgefunden. Auch ein Leerzeichen hat lt. ASCII einen Code und wird dann sofort auf den Controller übertragen ...
Wie sollte das denn sonst anders gehen!?... wenn ich ein Muster eingebe, wird jedes einzelne Zeichen als String übertragen ...
Was macht denn Dein uart_puts()? Vermutlich hast Du das genauso wie von Dir vorgestellt irgendwo rauskopiert - und weil kein Kommentar da ist, weiß niemand, was diese Routine tut. Im Englischen heißt put setzen, legen, stellen - das hat also wohl nix mit holen zu tun. Und wenn Du das genau ansiehst, dann ruft dieses uart_puts() eine Funktion auf uart_putc(*s) - die dann ein einzelnes Zeichen setzt/legt/stellt.... Muss ich oben das beim uart_puts() angeben? Also z.B. in dem ich sage, speicher die so lange bis ein Enter (das dann im ASCII-Code) auftritt? ...
So gehts also nicht.
Du musst in Deinem Controllerprogramm das Gegenstück zu uart_puts() einbauen. Hinweis: puts hat was mit put und s zu tun - und dieses s bedeutet String. Deshalb gibts die Weiterschaltung zu putc - also zu setzen/legen/stellen Character. Ein Character ist ein einzelnes Zeichen. Wenn Du in Deiner Codewühlkiste eine Routine findest die etwa gets.... heißt - oder so ähnlich, dann bist Du ein Stückchen weiter. Ich kann Dir da nicht so ohne weiteres ein Beispiel senden, weil meine Controller die Zeichen per Interruptroutine empfangen und in einem gesonderten Empfangsspeicher ablegen. Das ist eine Variante die vermutlich für den Anfang etwas undurchsichtig ist (ausserdem müsste ich für ne Weitergabe reichlich Kommentare einfügen *ggg*).
Ciao sagt der JoeamBerg
Lesezeichen