Hallo, ich bin gerade dabei eine Kommunikation zwischen PC und MSP über RS232 zu erstellen. Ich möchte im Hyperterminal eine Taste drücken und das entsprechende Zeichen dann auf dem Display ausgeben. Leider bekomme ich das nicht so ganz hin. Wenn ich das ganze wie folgt mache, funktioniert es: #pragma vector=UART0RX_VECTOR __interrupt void usart0_rx (void) { LCDOutc(RXBUF0); } Das entsprechende zeichen wird dann auf dem Display ausgegeben. Ich würde nun aber gerne das empfangene Zeichen in einer Variablen speichern und dann später ausgeben. void main(void) { ... for(;;) { ThirdLine(); // In die dritte Zeile des Displays springen SpaceOut(7); // Leerzeichen auf dem Display ausgeben //LCDOutc(temp_str); // Temperatur auf Display ausgeben LCDOutc(temp); LCDOuts("°C"); // Grad Zeichen auf Display ausgeben }/* for(;;) */ }/* void main(void) */ #pragma vector=UART0RX_VECTOR __interrupt void usart0_rx (void) { temp= RXBUF0; } Leider funktioniert das nicht. Kann mir jemand sagen, wie ich das umsetzen kann? Ich wollte auch schon einen ganzen String emspangen und dann in einer Variablen speichern: char temp_str[]="0000"; temp_str= RXBUF0; Aber da wird schon beim copilen gemeckert. Jemand eine Idee, was ich da falsch mache? Vielen Dank. Gruß Uwe
> Leider funktioniert das nicht. Kann mir jemand sagen, wie ich das > umsetzen kann? Zunächst mal solltest du uns mal sagen, was du unter 'funktioniert nicht' verstehst. > char temp_str[]="0000"; > temp_str= RXBUF0; > > Aber da wird schon beim copilen gemeckert. Wieder. Der Compiler gibt die Fehlermeldung nicht nur zum Spass aus. Aber in dem Fall ist alles klar. temp_str ist ein Array. RXBUF0 ist nur ein einzelner popeliger char. Einem Array kann man aber keinen char zuweisen. Einem Array als ganzes kann man überhaupt nichts zuweisen. Wohl aber einem Element des Arrays: temp_str[0] = RXBUF0; Bitte besorge die C-Literatur. Deine Fragen sind in der Kategorie: In jedem noch so billigen C-Buch ausreichend genau erklärt.
hallo. versuch mal eine abfrage mit einer While schleife in dein for(;;) schleife zu setzen. in der While schliefe fragst du immer ab ob ein neue zeichen ankommt, wenn ja dann soll er das auf dein temp[i] speichern dann i incrementieren und weiter nächste zeichen.
Hallo, ich habe das ganze nun ein wenig umgeschrieben. Funktioniert nun schon ganz gut. Ich würde nun noch gerne eine Sache ändern. Die Ausgabe der empfangenen Zeichen steht in der Interrupt routine (siehe Code). Ich würde das nun so realisieren, dass ich das Auslesen und speichern der empfangenen Zeichen in der Interrupt routine habe aber die Zeichenausgabe in der "main". Wie gesagt, so wie ich es jetzt habe, funktioniert es, würde das gerne aber noch ändern, wenns geht. Gruß Uwe
Das ist ziemlich einfach. Mach eine globale Variable, die du beim String-Ende in der ISR setzt. in der Main-Schleife fragst du die ab, wenn sie gesetzt ist, dann Ausgabe des Strings und löschen der Variable. Übrigens musst du nicht sinnlos auf das RX-Flag der UART warten, die ISR wird doch ausgelöst, wenn was kommt. Also die While-Schliefe da is bissl sinnlos. Zwischendurch kannst du den MSP auch schlafen schicken, der LPM0 schaltet die CPU ab, alle Peripheriekomponenten bleiben an. Da musst du aber dann beachten, dass du in der ISR am Ende den MSP aufweckst.
einfachen interrupt abfrage in MAIN setzen: so zum beispiel. for(;;) { blabla . . > if ((IFG2 & URXIFG1)) // warte auf neues zeichen. wenn ja dann in Receive speichern. diese Receive in dein temp[i] nochmal speichern. > { > Receive = RXBUF1; > } . . ...blabla } hoffe das hilft dann.
So einen Pollig-Mist sollte man in der µC-Welt tunlichst schnell vergessen und die ganze Sache sauber interruptgesteuert bauen. Zumal dann die Stromsparmechanismen völlig für den Popo sind.
Hallo, ich habe die abfrage nun in die main gepackt wie oben angegeben. Das funktioniert. Vielen Dank. Gruß Uwe
Hallo, im Anhang mal mein Code, zumindest einen Teil davon. @ Christian R.: Das habe ich ja versucht, aber leider nicht hin bekommen. Wenn du weißt wie es geht oder was ich in meinem Code, den ich weiter oben schon einmal gepostet habe, noch ändern muss oder falsch mache, würde ich mich freuen, wenn du mir da weiter helfen könntest. Das die jetzige Lösung nicht sooo super ist, weiß ich selbst, weil das nämlich schöner "Blocking-Code" ist. Wie gesagt, das mit den INterrupts hab ich nciht hin bekommen, bin aber für jede Hilfe dankbar. Grüße Uwe
> Das habe ich ja versucht, aber leider nicht hin bekommen. Wenn du weißt > wie es geht oder was ich in meinem Code, den ich weiter oben schon > einmal gepostet habe, noch ändern muss oder falsch mache, würde ich mich > freuen, wenn du mir da weiter helfen könntest. Wie Christian schon sagte: Du benutzt eine globale Variable, die dem Hauptprogramm anzeigt, dass eine komplette Eingabezeile empfangen wurde. Im Interrupt empfängst du also zeichen: Wenn es kein 0x0D ist, dann wird das Zeichen im (ebenfalls) globalen Empfangsbuffer zwischengespeichert. Wenn es ein 0x0D war, dann wird diese zusätzliche Variable auf irgendeinen Werte gesetzt, der dem Hauptprogramm ermöglicht zu erkennen, dass jetzt im Buffer eine komplette Zeile vorliegt. Nachdem das Hauptprogramm die Zeichen in diesem Buffer nicht mehr braucht, setzt es diese Variable wieder zurück und erlaubt so der Interrupt Funktion die nächste Zeile in diesem Buffer zusammenzusetzen.
1 | ...
|
2 | |
3 | char tmp_str[40]; |
4 | unsigned char NextStr; |
5 | volatile unsigned char StringReady; |
6 | |
7 | #pragma vector=UART0RX_VECTOR
|
8 | __interrupt void usart0_rx (void) |
9 | {
|
10 | if( StringReady == 1 ) |
11 | {
|
12 | /* Der vorher empfangene String wurde
|
13 | noch nicht verarbeitet
|
14 | Für den Fall musst du dir noch was einfallen lassen:
|
15 | Fehler LED setzen oder was auch immer.
|
16 | */
|
17 | }
|
18 | |
19 | else
|
20 | {
|
21 | |
22 | if(RXBUF0 == 0x0D) |
23 | {
|
24 | temp_str[NextStr] = '\0'; |
25 | StringReady = 1; |
26 | NextStr = 0; |
27 | }
|
28 | else
|
29 | {
|
30 | temp_str[NextStr++] = RXBUF0; // Ankommendes Zeichen speichern |
31 | }
|
32 | }
|
33 | }
|
34 | |
35 | int main() |
36 | {
|
37 | ....
|
38 | |
39 | StringReady = 0; |
40 | NextStr = 0; |
41 | |
42 | |
43 | /* Initialisierung fortsetzen und UART freigeben */
|
44 | |
45 | ...
|
46 | |
47 | for( ;; ) |
48 | {
|
49 | if( StringReady == 1 ) |
50 | {
|
51 | ThirdLine(); |
52 | SpaceOut( 7 ); |
53 | LCDOuts( temp_str ); |
54 | |
55 | StringReady = 0; /* wichtig: Das ist das Signal für die |
56 | Interrupt Routine, dass der String
|
57 | abgeholt wurde, und dass wieder Zeichen
|
58 | in temp_str abgelegt werden können.
|
59 | Das können wir hier machen, weil der
|
60 | Inhalt von temp_str schon bearbeitet
|
61 | wurde und in Folge nicht mehr gebraucht
|
62 | wird.
|
63 | */
|
64 | LCDOuts( "°C" ); |
65 | }
|
66 | }
|
67 | }
|
Naja, musst den Interrupt für die UART freigeben, wie das geht, steht ja in den C-Demos. Ich hab mal was geschrieben. Sollte klappen, wenn der UARTRX Int eingeschaltet ist. Sowas klappt bei mir problemlos mit vielen verschiedenen Flags und auf 2 USART Schnittstellen. ich muss mit jedem µA geizen, da ist das sehr hilfreich.
Christian R. wrote:
> Oh, der Meister war wieder schneller ;)
Dafür hast du ein vollständiges Progaramm gebaut
und die CPU zwischendurch auch noch schlafen gelegt.
Allerdings hast du vergessen, den Buffer im Interrupt
mit einem '\0' zu terminieren :-)
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.