Hi, bastel gerade ein wenig mit RS232 herum. Ich habe eine bidirektionale Verbindung zwischen PC und µc. Der PC sendet bspl. eine "10" Die "10" wird in der Variablen "c" gespeichert und an den PC zurück gegeben. Soweit so gut. In einer ISR habe ich die Variable "tempo" Wie kann ich die "10" aus "c" nun an "tempo" übergeben ? Gruß odin
Er erhält "10" und das ist ein string. Daher: strcpy(tempo,c); :D Du musst darauf achten, dass c eine globale Variable ist, da du ansonsten aus der ISR keinen Zugriff darauf hast. EDIT: In der Annahme, dass du C verwendest...
Vorsicht bissiger Hund! Werden über die serielle Schnittstelle die Zeichen "1" und "0" übertragen, so kann der Zugriff via. strcpy () Probleme bereiten. strcpy steht auf das Abschließende "\0" - so war‘s wenigstens früher mal.
Also ich verwende die lib von Peter Fleury. Mit c = uart_getc(); --> weise ich den Inhalt der variablen c zu. C wird außerhalb der Funktion mit unsigned int c; --> global ebso die variable tempo mit unsigned int
Hier mal der Code. Es haut so aber nicht hin: #include <stdlib.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <string.h> #include "uart.h" #ifndef F_CPU #define F_CPU 16000000 #endif #define UART_BAUD_RATE 9600 #define LED_DDR DDRA #define LED_PORT PORTA #define LED_PORTPIN1 PA2 #define LED_PORTPIN2 PA1 volatile uint8_t zaehler; unsigned int tempo; unsigned int c; // Timer0(8-bit) init void initTimer0(void) { TCCR0 |= (1<<CS00) | (1<<CS02); // Prescale von 1024 TIMSK |= (1<<TOIE0); // Interrupts aktivieren TCNT0 = 0x00; sei(); } ISR(TIMER0_OVF_vect) { if (zaehler <=tempo) { zaehler ++; } else { LED_PORT ^= LED_PORTPIN1; LED_PORT ^= LED_PORTPIN2; zaehler = 0; } } int main (void) { LED_DDR = 0xFF; // Port als Ausgang LED_PORT = 0x02; // Anfangszustand der LED initTimer0(); char buffer[7]; int num=134; uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); sei(); uart_puts("String stored in SRAM\n"); for(;;) { c = uart_getc(); tempo = c; if ( c & UART_NO_DATA ) { } else { if ( c & UART_FRAME_ERROR ) { uart_puts_P("UART Frame Error: "); } if ( c & UART_OVERRUN_ERROR ) { uart_puts_P("UART Overrun Error: "); } if ( c & UART_BUFFER_OVERFLOW ) { uart_puts_P("Buffer overflow error: "); } uart_putc( (unsigned char)c ); } } }
odin schrieb: > volatile uint8_t zaehler; > unsigned int tempo; > unsigned int c; Mach erstmal aus tempo und c auch ein volatile uint8_t, sonst gibts casting Probleme. c muss allerdings nicht volatile sein. Ausserdem musst du entweder ein einzelnes Byte übertragen (also z.B. ein grosses 'A' hätte dann 0x41 als Wert), oder du brauchst eine Empfangsroutine, die dir eine Zahl, gefolgt von einem 'Ende' Zeichen umwandelt in ein Byte.
odin schrieb: > Mit c = uart_getc(); --> weise ich den Inhalt der variablen c zu. Quatsch. Damit steht in c nur das letzte empfangene Zeichen, z.B. '0' = 48. Du willst aber eine Zeichenkette empfangen und dann in eine Zahl umwandeln. Dazu mußt Du Dir erstmal ein Protokoll überlegen, wie der Anfang und das Ende der Zeichenkette markiert und erkannt werden kann.
Vielleicht kann "Odin" ja mal aus seinem Götterhimmel herauskrabbeln und seinen Anhängern erklären ob er so etwas simples wie ein binäres Zeichen z.B. 0xA=10=ein Zeichen, oder eine ASCII-Zeichenkette wie z.B. "1" + "0" = zwei Zeichen, durch die Lande schaukelt.
Hey amatuer, keine Spässe über meinen Name, ich heisse wirkich so ! Also ich wollte einfach nur den ordinären Wert 10 vom PC übertragen, der die Blinkgeschwindigkeit änder soll
... was nichts daran ändert, das eine Klarstellung nötig war. Also nix mit strcpy () sondern einfach warten bis ein Zeichen im Puffer vorhanden ist und dieses dann holen/kopieren (=).
odin schrieb: > for(;;) > { > c = uart_getc(); > > tempo = c; > > if ( c & UART_NO_DATA ) > { > } So so. Du verwendest also das c bereits, noch ehe klar ist, ob uart_getc() überhaupt ein Zeichen für dich hatte, oder ob es mangels Daten UART_NO_DATA geliefert hat, um anzuzeigen, dass vom Sender nichts gekommen ist. Liest heute eigentlich noch irgendwer Democode und überlegt sich, was er da gelesen hat oder wird heutzutage in Demos nur noch gedankenlos und dämlich das reingeschrieben, was man sich irgendwie denkt? Mann ihr wärt aber sowas von aufgeschmissen gewesen, wenn ihr in einer Zeit angefangen hättet, in der es kaum Demos gab und man sich aus 500 Seiten Manuals alles zusammensuchen musste und dann stundenlang das Gelesene versucht hat, in Code zu giessen.
Ja was sol ich da sagen , Gnade der späten Geburt ! Ich nehme aber einmal an, du wolltest mir auch damit weiter helfen. Vielen Dank
odin schrieb: > Ja was sol ich da sagen , Gnade der späten Geburt ! > > Ich nehme aber einmal an, du wolltest mir auch damit weiter helfen. Ich will dich aufrütteln, dass du Democode auch STUDIEREN musst. Das was du in einer Demo siehst, das steht da nicht von ungefähr! P. Fleury het den nicht geschrieben, weil ihm fad war, sondern weil er damit etwas demonstrieren will. Nämlich: wie verwendet man die Funktion korrekt und wie wertet man den Returncode korrekt aus. Und wenn ich seinen Code studiere, dann sehe ich dass er von der Funktion einen Wert bekommt, den er in c speichert. Und dann gehts weiter! Was macht er mit diesem c? Wie wertet er die Variable aus. Bereits in der nächsten Zeile steht if( c & UART_NO_DATA ) UART NO DATA? Da muss es doch sofort zum Klingeln anfangen. NO DATA - keine Daten. Was macht seine Demo in diesem Fall? Nichts - sie macht buchstäblich nichts. Wie denn auch, wenn die Funktion liefert "Ich hab nichts", dann ist da auch nichts, mit dem man etwas tun könnte (etwa ausgeben).
Ok, die Funktion hahe ich ja auch soweit verstanden. Mein "tempo = c;" steht da nur aus lauter Verzweifelung. Aus meiner bescheidenen Sicht müsste der Code hier stehen : for(;;) { c = uart_getc(); if ( c & UART_NO_DATA ) { } else { if ( c & UART_FRAME_ERROR ) { uart_puts_P("UART Frame Error: "); } if ( c & UART_OVERRUN_ERROR ) { uart_puts_P("UART Overrun Error: "); } if ( c & UART_BUFFER_OVERFLOW ) { uart_puts_P("Buffer overflow error: "); } uart_putc( (unsigned char)c ); tempo = c; } } Denn nur wenn alle DANN Möglichkeiten NICHT zutreffen, ist erfolgreich etwas übertragen worden. Es klappt aber leider auch so nicht
Ich habe nie mit der Bibliothek von Peter Fleury gearbeitet, aber vielleicht wäre es hilfreich statt mit: tempo = c; mit tempo = c & 0xff; zu arbeiten. Irgendwie sieht euer Code so aus als ob da mehr als char zurückgeliefert wird, euer Interesse aber auf char beschränkt ist.
Sorry, wenn euer char im Obergeschoss (Bit 8 bis 15) herumhängt. Dann könnte: tempo = c >> 8; recht hilfreich sein.
amateur schrieb: > tempo = c; > > mit > > tempo = c & 0xff; > > zu arbeiten. Das passt schon. Wenn alle Fehler ausgeschlossen sind, dann bleibt in c nur mehr das LowByte übrig. Das High-Byte ist definitiv 0. "Funktioniert nicht" ist nun mal keine ordentliche Fehlerbeschreibung. Der COde sendet ja das Byte, welches dann an temp zugewiesen wird über die UART zurück. D.h. da hat man ja die Bestätigung beim Sender, was der AVR eigentlich erhalten hat, und welche Werte dann auch tatsächlich an tempo zugewiesen werden. Aber noch bin ich mir nicht sicher, ob er überhaupt den UNterschied zwischen einer ASCII Übertragung und einer binären Übertragung versteht. Mal genauer nachfragen.
> Also ich wollte einfach nur den ordinären Wert 10 vom PC übertragen, > der die Blinkgeschwindigkeit änder soll Und wie machst du das auf PC-Seite? Und wurde die UART eigentlich schon mal prinzipiell getestet? Wenn du vom AVR was zum PC schickst (zb indem dort ein Terminalprogramm läuft), erscheint dann dort das Gesendete korrekt?
Ich weis nicht wie Fehlerträchtig (hängt wohl vom Quarz ab) die Übertragung ist, aber bei einem UART_FRAME_ERROR, UART_OVERRUN_ERROR oder UART_BUFFER_OVERFLOW erfolgt trotzdem ein: tempo = c;
amateur schrieb: > Ich weis nicht wie Fehlerträchtig (hängt wohl vom Quarz ab) die > Übertragung ist, aber bei einem UART_FRAME_ERROR, UART_OVERRUN_ERROR > oder UART_BUFFER_OVERFLOW erfolgt trotzdem ein: > tempo = c; Yep, Das ist nicht schön. Aber wenn die UART prinzipiell korrekt funktioniert (was man erst mal testen müsste), dann kommen diese Fehler praktisch nicht vor. In einem Profiprogramm werden sie selbstverständlich behandelt, aber für die ersten Schritte ist es schon ok. Die ganze Problematik wird ja auch im Tutorial komplett ignoriert. Ein
1 | uint8_t uart_getc(void) |
2 | {
|
3 | while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar |
4 | ;
|
5 | return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben |
6 | }
|
ist ja so gesehen auch nur die halbe Miete, weil ja die ganze Fehlerbehandlung komplett ignoriert wird. Irgendwo muss man nun mal anfangen und Fehlerbehandlung hat die Tendenz, die Dinge mal schnell kompliziert und unübersichtlich zu machen. Aber wie gesagt: Wenn die UART prinzipiell funktioniert, dann treten diese Fehler nicht auf und können so gesehen fürs erste ignoriert werden.
@odin Mit welchem Prozessor redest Du eigentlich? Habe es wahrscheinlich 5 mal überlesen aber ...
Also die uart funktioniet. Ich kann etwas senden und ich kann etwas empfangen. Den Rest muss ich gleich mal test
So vielen Dank für die Unterstützung ! Es funktioniert !! Natürlich muss ich auch binär etwas senden, wenn ich binär etwas erwarte :-) Und ich habe sogar verstanden warum tempo = c & 0xff; zum Ziel führte ! Danke an alle !
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.