Hallo zusammen, ich habe ein kleines Problem. Der unten stehende Quellcode sollte folgende Bedienungsmöglichkeiten realisieren: Es wird ein Gerät gebaut, welches über Taster am Gerät oder wahlweise über RS232 über Kontroll-Rechner (LabView, dSpace...) bedient werden soll. Mein Vorhaben wäre, in der Arbeitsschleife die Tasten zu pollen bzw. über eine EMPFÄGER-INTERRUPTROUTINE Zeichen über RS232 zu empfangen, diese zu vergleichen und ebenfalls Befehle ausführen. (Befehle RS232 und Taster sind identisch). Leider mache ich die Einbindung der Interruptroutine falsch. Könnt Ihr mir bitte weiterhelfen? Ich hab auch im Tutorial nichts passendes gefunden. Vielen Dank im Voraus. Gruß Tom ************************************************************************ *** //HEADERDATEIEN #include <avr/io.h> //Deklarationen #include <avr/interrupt.h> //Headerdatei mit Interruptfunktionen #include <avr/own_timestep.h> //Eigene Headerdatei mit Delay-Fkt. usw. #include <avr/own_uart.h> //Eigene Headerdatei mit RS232-Fkt. #include <avr/own_ref.h> //Eigene Headerdatei mit der kompletten Referenzfunktion //FESTLEGUNG UNABHÄNGIGER TYPENNAMEN typedef unsigned int uint16; typedef signed int sint16; typedef unsigned char uint8; typedef signed char sint8; //GLOBALE VARIABLEN UND STRINGS uint8 eingabe = 0; //Hilfsvariable für RS232-Steuerung uint8 enter = 0; //Hilfsvariable für RS232-Steuerung uint8 init[] = "\n\n\rRS232 initialisiert.\n\rSystem referenziert\n\r"; uint8 command[] = "\n\rBitte einen Befehl auswaehlen: \n\r\t1: Referenzfahrt\n\r\t2: Messfahrt 0 bis 360 \n\r\t3: Messpunkt +\n\r\t4: Messpunkt - \n\n\r\tAuswahl bitte mit Enter bestaetigen\n\r\t"; uint8 falsch[] = "\n\n\r\t!!FALSCHE EINGABE!!\n\r\t"; //SERVICEROUTINE FÜR EMPFÄNGERINTERRUPT SIGNAL(SIG_UART_RECV) { //Einlesen zweier Werte über RS232 und Übergabe an Hilfsvariablen getche(); eingabe = got_cha; getche(); enter = got_cha; cli(); //Alle Interrupts global sperren } //HAUPTFUNKTION int main (void) { //Portzuweisungen DDRA = 0x7f; DDRB = 0xff; DDRC = 0x00; DDRD = 0x80; initusart(); //UART initialisiert; Funktion in own_uart.h UCSRB |= RXCIE; //Empfängerinterrupt frei sei(); //Alle Interrupts global frei //AUFFORDERUNG FÜR REFERENZFAHRT while(PINC & (1<<PC3)) { PORTD &= ~(1<<PD7); delay(50000); PORTD |= (1<<PD7); delay(50000); PORTD &= ~(1<<PD7); } referenz(); //BILDSCHIRMAUSGABE ÜBER RS232 uint8 *pinit; //String Init pinit = init; uint8 *pcommand; //String Eingabeaufforderung pcommand = command; uint8 *pfalsch; //String Falsche Eingabe pfalsch = falsch; //Bildschirmausgabe RS232 initialisiert while(*pinit != 0) { putch(*pinit++); } //Bildschirmausgabe Eingabeaufforderung while(*pcommand != 0) { putch(*pcommand++); } putch(0x07); //Akustisches Signal // *** ARBEITSSCHLEIFE *** while(1) { //MÖGLICHKEIT ERNEUTER REFERENZIERUNG if(!(PINC & (1<<PC3)))// Taste "Ref" { referenz(); } //MESSFAHRT 0° bis 360° if(!(PINC & (1<<PC2)))// Taste "Messfahrt 0° bis 360°" { uint16 i; for(i = 6400; i>0; i--) { Step_plus_micro(); } PORTA &= ~(1<<PA2) & ~(1<<PA3) & ~(1<<PA4) & ~(1<<PA5); } //POLLEN DER EINGABE ÜBER KONTROLL-RECHNER if((eingabe == 0x31) && (enter == 0x0d)) { referenz(); eingabe = enter = 0; } } return 0; }
in einer ISR verwendete Variablen sollten volatile deklariert werden
Hallo Boxi Boxitec, vielen vielen Dank für Deine Hilfe. Natürlich gehts jetzt. Ohne Schmarrn, ich schau schon mind. eine Stunde meinen Code an und hab nix gefunden. Danke und Gruß Tom
Boxi Boxitec wrote: > in einer ISR verwendete Variablen sollten volatile deklariert werden Damit es keine Missverständnisse gibt: Nur Variablen, die sowohl in einer ISR als auch im Hauptprogramm verwendet werden (was auf die hier vermutlich gemeinte Variable "eingabe" allerdings zutrifft), sollten volatile sein. Variablen, die ausschließlich in einer ISR verwendet werden, dagegen nicht. @Tom: > eingabe = enter = 0; Bist Du ganz sicher, dass das so sein soll? Abgesehen davon hat Boxi recht: UCSRB |= RXCIE ist falsch, es sei denn, Du hast RXCIE irgendwo umdefiniert...
unser blödes hirn sieht halt immer nur das, was es schreiben wollte, nicht was geschrieben wurde...
@ Tom (Gast) >Könnt Ihr mir bitte weiterhelfen? Ich hab auch im Tutorial nichts >passendes gefunden. Sicher? Glaub ich nicht. Vor allem, weil di den Interrupt in der alten Schreibweise deklariert hast. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ISR Ausserdem fehlt der Quelltext für deine Funktionen, da kann man keine Aussagen treffen. cli() am Ende eines Interrupts ist reichlich sinnlos. Wozu eigene delay-Funktionen? Gibt es fertig getestet. Lass den Unsinn mit den eigenen typedefs. Stdint hält wunderbare Typen bereit, uint8_t etc. Aber der Hammer ist. Du hast das Prinzip des UART RX Interrupts noch nicht verstanden. Zweimal getche() im Interrupt ist Nonsense! http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts MFG Falk
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.