Guten Tag, habe zwar einige Beiträge gefunden die in die Richtung gingen, aber nichts was mir weitergeholfen hätte. Folgendes: PIC wird über die rs-232 vom PC angesteuert, dazwischen sitzt ein max232 für die pegelwandlung. der aufbau ansich ist soweit richtig und funktioniert auch mit anderen (test)programmen. nun war geplant das eingangssignal am pic einzulesen, es zu verarbeiten und darauf hin eine ausgabe mit einer 7-segment platine zu realisieren. die eigentliche frage ist: was genau schreibt der pic in eine variable (c-programmierung) wenn die eingabe über das terminal zB eine "2" war? schreibt er da den ascii code rein als wert? oder was genau? da ich bislang feststellen konnte das die im terminal eingegebene 2 keine 2 in der variable ergibt und mein wissen anscheint auch noch nicht soweit ausreicht das ich da andere beurteilungen abgeben kann, frag ich hier. :) hier noch ein kleiner auszug aus dem quellcode: { while(!PIR1bits.RCIF); ein = RCREG; //wenn 2 im terminal eingegeben wird soll es in ein geschrieben werden LATB = ausgabeB[ein]; //hier wird nun allerdings nicht die wertigkeit von 2 LATA = ausgabeA[ein]; //für ein angenommen, was steht da jetzt drin? } ich wäre dankbar wenn mir jemand sagen könnte was nun in meiner variablen drin steht. :) ich brauch auch nur die zahlen von 0-9. MfG Kai
Kai J. schrieb: > schreibt er da den ascii code rein als wert? ganz genau. > bislang feststellen konnte das die im terminal eingegebene 2 keine 2 in > der variable ergibt was würdest du erwarten, wenn du anstelle der Taste '2' die Taste 'U' drückst? 'U' ist ja in dem Sinne auch keine Zahl, wie die Taste '2' auch keine 2 'in deiner Variablen generiert'
Es geht mir momentan nur um die Zahlen von 0-9. Ich habe jetzt anhand einer ascii tabelle die werte verwendet, allerdings ist das ergebniss das selbe wenn ich eine 2 eingebe müsste in der variable doch eine 32 stehen oder seh ich das nun völlig verkehrt?
Hallo Zeig doch mal ein bischel mehr. Stimmt die Baudrate? MfG XXXXX
"2" = dezimal 50 und hexadezimal 32 So würde eine Zwei in der Variable stehen wenn du "2" drückst: ein = RCREG - 48;
Stefan P. schrieb: > "2" = dezimal 50 und hexadezimal 32 > > So würde eine Zwei in der Variable stehen wenn du "2" drückst: > ein = RCREG - 48; man kanns aber auch so schreiben
1 | ein = RCREG - '0'; |
dann braucht man noch nicht einmal den ASCII Code selber kennen. Es reicht wenn ihn der Compiler weiß.
Kai J. schrieb: > wenn ich eine 2 eingebe müsste in der variable doch eine 32 stehen oder Die 32 ist aber Hex, die üblichen Variablen sind aber Dezimalzahlen. Somit wird aus der 32H eine 50 in dezimaler Schreibweise.
Kai J. schrieb: > wenn ich eine 2 eingebe müsste in der variable doch eine 32 stehen oder > seh ich das nun völlig verkehrt? 'Müsste' sind ganz schlechte Voraussetzungen für Fehlersuche. Entweder es tuts oder es tuts nicht. Aber nicht 'müsste'. Und wenn man es nicht weiß, dann muss man das kontrollieren. Du musst aus dem Stadium raus, indem die Dinge rätst! Du musst Fakten schaffen. Und wenn das bedeutet, du musst dir einen Mechanismus schaffen, wie du dir den Inhalt von Variablen ansehen kannst, dann bedeutet es das eben.
ok hier mal mein der text mit dem ich bis rumexperimentiert habe. die arrays sind für die ausgangschaltung um die segmente der 7-segment-anzeige anzusteuern #include <pic18fregs.h> #include "18f1320_config.h" #include <delay.h> //für Zeitroutinen #include <stdlib.h> #pragma stack 0x80 0x32 unsigned int ausgabeB[]={64,121,36,48,25,18,2,120,0,16}; unsigned int ausgabeA[]={231,239,231,239,239,255,247,239,231,231}; unsigned char ein ,ein1; //*********** Hauptprogramm *************************** void main() { //*********** Variable festlegen ********************** ein1 = 0; ein = 0; TRISB = 16; //RB4 als Eingang, alle anderen Leitungen auf Ausgang TRISA = 0; // PORTA alles auf Ausgang RCSTAbits.SPEN = 1; ADCON1bits.PCFG5 = 1; ADCON1bits.PCFG6 = 1; PIE1bits.TXIE = 0; PIE1bits.RCIE = 0; TXSTAbits.TX9 = 0; TXSTAbits.SYNC = 0; TXSTAbits.TXEN = 1; TXSTAbits.BRGH = 1; TXSTAbits.TRMT = 1; SPBRG = 25; RCSTAbits.RX9 = 0; RCSTAbits.CREN = 1; //*********************************** while(1) // Dauerschleife { while(!PIR1bits.RCIF); ein = RCREG; switch(ein) { case '49': ein1= 1; break; /* case '31': ein1= 1; break; case '32': ein1= 2; break; case '33': ein1= 3; break; case '34': ein1= 4; break; case '35': ein1= 5; break; case '36': ein1= 6; break; case '37': ein1= 7; break; case '38': ein1= 8; break; case '39': ein1= 9; break; */ } //delay1mtcy(1); //if (ein == 31) ein1 = 1; //ein1 = atoi(&ein); delay1mtcy(1); LATB = ausgabeB[ein1]; LATA = ausgabeA[ein1]; } }
Kai J. schrieb: > switch(ein) > { > case '49': ein1= 1; > break; Nope. Entweder du verwendest den ASCII Code, dann schreibst du case 49: ein1 = 1; oder wenn dir hex lieber ist case 0x31: ein1 = 1; oder du lässt den Compiler den ASCII Code raussuchen case '1': ein1 = 1; aber nicht einen Mischmasch aus beidem Die letzte Variante case '1': ist die zu Bevorzugende. Es gibt keinen Grund an dieser Stelle, das du den Leser deines Programms in die Verlegenheit treiben musst, dass er erst mal in einer ASCII Tabelle deine Codes nachschlagen muss, nur um zu verstehen, was da passieren soll. Von der UART kriegstr du ein Zeichen. Behandle es auch als Zeichen! Das Zeichen könnte 'a' oder 'A' oder 'X' oder '&' der '@' sein, je nachdem was der Benutzer auf der Tastatur drückt. Bei dir ist es eben '1' weil du deinen Benutzer dazu anhältst, nur die Zifferntasten zu benutzen. Nichts desto trotz ist auch '1' oder '5' einfach nur ein Zeichen, genauso wie 'g' oder '?' auch nur ein Zeichen ist. Lass dich nicht davon täuschen, dass du mit der Taste '1' etwas spezielles verbindest. Das ist nur 'zufällig', dass da auf der Tastenkappe ein Symbol aufgemalt ist, dass wie eine Eins aussieht. Für den Rechner unterscheidet sich diese Taste (und der zugehörige auszusendende Code) in nichts von dem der anderen Tasten.
Entschuldige die Verwirrung, hatte die Varianten durchprobiert und immer wieder auskommentiert, hatte aber jedes mal einheitliche Wete genommen. Die Vorgeschlagene Variante case '1' zu verwenden war die ursprüngliche Idee, allerdings funktioniert das so nicht, bei der Auslesung von "aus" gibt es den Inhalt 1 ja nicht, im Terminal (ich verwende unter linux gtkterm) gebe ich die 1 ein, sie wird gesendet, wird so aber nicht in ein geschrieben. while(1) // Dauerschleife { while(!PIR1bits.RCIF); ein = RCREG; switch(ein) { case '0': ein1= 0; case '1': ein1= 1; case '2': ein1= 2; case '3': ein1= 3; case '4': ein1= 4; case '5': ein1= 5; case '6': ein1= 6; case '7': ein1= 7; case '8': ein1= 8; case '9': ein1= 9; break; } delay1mtcy(1); LATB = ausgabeB[ein1]; LATA = ausgabeA[ein1]; } beim start wird mir die 0 angezeigt, allerdings reagiert nichts auf die Eingabe im Terminal. und warum das so ist konnte mir keiner sagen...
Kai J. schrieb: > und warum das so ist konnte mir keiner sagen... Dann solltest du als allererstes einmal kontrollieren, was dein µC eigentlich über die UART empfängt. Wenn zb deine Baudrate falsch ist, oder es sonst irgendein Problem gibt, dann spuckt die UART auf µC Seite alles mögliche aus, nur nicht '1' wenn du im Terminal die Taste '1' drückst. Also: 8 LED an einen Port klemmen und einfach mal das Byte von der UART direkt dort ausgeben. Das Bitmuster entziffern und mittels ASCII Tabelle identifizieren, ob du den ASCII Code des Zeichens kriegst, dessen Taste du drückst (höchst wahrscheinlich kriegst du den nämlich gar nicht) Wie ich weiter oben schon sagte: Nicht 'könnte' 'müsste' 'wollte' sondern Fakten schaffen. Deine UART spuckt ein Byte aus .... welches? Da du das nicht weißt, musst du dir einen Mechanismus ausdenken, mit dem du das feststellen kannst. Alles andere ist Stochern im Nebel und funktioniert in der Softwareentwicklung nicht.
Dann bedanke ich mich soweit erstmal und werde schauen wie ich das realisiert bekomme, also zu kontrollieren was nun wirklich übertragen wird. Es ist wahrscheinlich zu merken das mein Horizont in diesem Gebiet noch nicht wirklich gross ist. Daher auch die Unsicherheiten in meinen Beiträgen.
Deinem switch fehlen noch zwei Sachen: Erstens eine default-Klausel, die z.B. einen Fehlercode anzeigt (hint: abhängig vom Terminal-Programm wird an die Eingabe noch ein '\r', "\r\n" oder '\n' angehängt, das musst Du abfangen!). Zweitens musst du die einzelnen cases mit je einem break; abschließen, sonst läuft dir der IP bis ins letzte case hinein (hier: am Ende kommt ein1 == 9 bei raus). HTH
Ich habe jetzt mal folgendes Programm in den Pic geladen und die Rx/Tx Pins gebrückt: char ein; //*********** Hauptprogramm *************************** void main() { //*********** Variable festlegen ********************** RCSTAbits.SPEN = 1; ADCON1bits.PCFG5 = 1; ADCON1bits.PCFG6 = 1; PIE1bits.TXIE = 0; PIE1bits.RCIE = 0; TRISB = 16; TRISA = 0; TXSTAbits.TX9 = 0; TXSTAbits.SYNC = 0; TXSTAbits.TXEN = 1; TXSTAbits.BRGH = 1; TXSTAbits.TRMT = 1; SPBRG = 25; RCSTAbits.RX9 = 0; RCSTAbits.CREN = 1; //*********************************** while(1) // Dauerschleife { while(!PIR1bits.RCIF); ein = RCREG; delay1mtcy(1); while(!PIR1bits.TXIF); TXREG=ein; delay1mtcy(1); } } Das was ich über gtkterm eingebe, bekomme ich nun zurück. Sprich Senden/Empfangen funktioniert. Zurück zum anfänglichen besteht weiterhin das Problem das ich die Eingabe die ich am Terminal tätige nicht verarbeiten kann, ausser sie direkt zurück zusenden. Sobald ich nun aber die Arrays auswerten möchte bzw die Ausgänge des Pics schalten will, hat die variable keinen verwertbaren Inhalt, obwohl mir durch das Programm oben ja bewiesen wurde das es einer ist. Hier der letzte Stand vom Quelltext: int ausgabe1[] = {64,121,36,48,25,18,2,120,0,16}; int ausgabe2[] = {231,239,231,239,239,255,247,239,231,231}; int ein; //*********** Hauptprogramm *************************** void main() { //*********** Variable festlegen ********************** unsigned int z; ein = 0; z = 0; TRISB = 16; //RB4 als Eingang, alle anderen Leitungen auf Ausgang TRISA = 0; // PORTA alles auf Ausgang RCSTAbits.SPEN = 1; // serieller Port aktivieren RCSTAbits.RX9 = 0; RCSTAbits.CREN = 1; ADCON1bits.PCFG5 = 1; ADCON1bits.PCFG6 = 1; PIE1bits.TXIE = 0; // Interrupt nicht aktiviert PIE1bits.RCIE = 1; TXSTAbits.TX9 = 0; TXSTAbits.SYNC = 0; // asynchrone mode TXSTAbits.TXEN = 0; TXSTAbits.BRGH = 1; // Einstellung der Baudratenauswahl TXSTAbits.TRMT = 1; SPBRG = 25; // Baudrate = 9600 bei 4MHz //*********************************** while(1) // Dauerschleife { while(!PIR1bits.RCIF); ein = RCREG; delay1mtcy(1); if (ein == '0') z = 0; if (ein == '1') z = 1; if (ein == '2') z = 2; if (ein == '3') z = 3; if (ein == '4') z = 4; if (ein == '5') z = 5; if (ein == '6') z = 6; if (ein == '7') z = 7; if (ein == '8') z = 8; if (ein == '9') z = 9; LATB = ausgabe1[z]; LATA = ausgabe2[z]; } } Ich weiß das die Ausgänge angesprochen werden, da durch z = 0 beim einschalten auch die pins geschaltet werden die zur Bildung der 0 benötigt werden. Lese ich die Eingabe vom terminal an der falschen Stelle ein? Da jegliche Eingabe bzw senden über den terminal keine Veränderung der Beschaltung der Ausgänge bewirkt. Sieht vielleicht jemand einen Fehler bei den Konfigurationseinstellungen? Danke schonmal und Entschuldigung für ggf. komische Schreibweisen, ist schon spät. ;)
Kai J. schrieb: > Ich weiß das die Ausgänge angesprochen werden, da durch z = 0 beim > einschalten auch die pins geschaltet werden die zur Bildung der 0 > benötigt werden. Das verstehe ich nicht - Die Zeile : while(!PIR1bits.RCIF); wartet doch erstmal auf Daten von der seriellen... ? Übrigens, was für ein Pic ist es ? Und wie sehen die Config-Bits aus ? Ich leg die immer im Sourcecode fest... geht aber auch anderswo. Da könnte der Wurm drin sein, z.B. dass dich der Watchdog beisst.
So, es funktioniert alles und eigentlich waren die ganzen Mühen hier umsonst. Es lag an der Versuchsplatine, die ich für das Projekt von der Schule gestellt bekommen habe und wir auch auf Anfrage keine Pläne dafür bekommen haben. Der zuletzt gepostete Quelltext arbeitet richtig.
Hallo Kai, hier noch ein Tip. Du kannst in Windows jedes beliebige Byte eingeben (im HypterTerminal senden). Das funktioniert so: - Alt-Taste drücken und halten - Zahl mit den Zehnerblock (!) in Dezimal eingeben (1 bis 3 Stellen, 0-255) - Alt-Taste loslassen Gruß John
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.