PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] LED's springen bei Hyperterminal



Unbekannt
18.11.2014, 09:20
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.



#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 benutze den AT19CAN128, im HyperTerminal sind eingestellt: Baudrate 9600, 1 Stoppbit, kein Handshaking, 8-bit.

Ich bedanke mich schonmal für die Hilfe!

Hubert.G
18.11.2014, 09:37
Du gibst alles auf PortC aus was ankommt. Wenn du das nicht willst musst du filtern.

oberallgeier
18.11.2014, 09:43
... Ich benutze den AT19CAN128 ...AT19.. ?? Vermutlich den AT90.. oder nicht?



...
int main(void)
...
else
{
// Kein Zeichen empfangen, Restprogramm ausführen...
}
...Was bitte steht im Restprogramm ??

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

Unregistriert
18.11.2014, 10:33
Ja AT90 natürlich, da habe ich mich verschrieben.


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

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.

oberallgeier
18.11.2014, 11:41
Ja AT90 natürlich, da habe ich mich verschrieben ... 01101101 eingebe warden nicht die richtigen LED's geschaltet ...
a) Wie gibtst Du das Muster ein?
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 :-/

Unregistriert
18.11.2014, 15:28
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?

oberallgeier
18.11.2014, 16:29
... Problem... so halb herausgefunden. Auch ein Leerzeichen hat lt. ASCII einen Code und wird dann sofort auf den Controller übertragen ...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 :.-.)


... wenn ich ein Muster eingebe, wird jedes einzelne Zeichen als String übertragen ...Wie sollte das denn sonst anders gehen!?


... 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? ...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.

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*).