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.