www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interruptroutine funzt nicht


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
}

Autor: Boxi Boxitec (boxi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UCSRB |= (1<<RXCIE);

nicht


UCSRB |= RXCIE;

?

Autor: Boxi Boxitec (boxi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in einer ISR verwendete Variablen sollten volatile deklariert werden

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Boxi Boxitec (boxi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unser blödes hirn sieht halt immer nur das, was es schreiben wollte, 
nicht was geschrieben wurde...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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-Tu...

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.