www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt Eingänge bei mega8 richtig verwenden - HILFE!


Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Leute!

Ich würde gerne mit meinem ATmega8 folgendes realisieren:

Durch das setzen einer Variablen soll der INT0-Eingang "freigegeben" 
werden.
Nachdem einmal ein Impuls über INT0 "herein kommt", soll INT0 
deaktiviert und dafür

der INT1-Eingang aktiviert werden. Weiters wird ein Timer gestartet, 
welcher so lange

läuft, bis eine bestimmte Taste gedrückt wird. Über den INT1 Eingang 
kommen

laufend Impulse. Nach einem Tastendruck (die vorher gesetzte Variable 
wird wieder

gelöscht) soll dann dieser Eingang (und der Timer) wieder deaktiviert 
werden...

Leider schaffe ich es nicht, das Programm zum laufen zu bringen...

Hier mal meine bisherigen "Ergebnisse":
#include <mega8.h>
#include <LCDlib2x16.h>
#include <stdio.h>
           
//Definiton der Ein- bzw. Ausgaenge
#define Links     !PINC.0  //Active High Taster --> Links  
#define Rechts    !PINC.1  //Active High Taster --> Rechts   
#define Enter     !PINC.2  //Active High Taster --> Enter   
#define Back      !PINC.3  //Active High Taster --> Back

#define LCD_SIZE 16    //Zeichen pro Zeile im Display


// Welcome string to display on a 16 char-LCD:
const char Fstmsg[16]=// 
{'M','e','s','s','u','n','g','>','s','t','a','r','t',' ','K','2'};


// Declare your global variables here:
unsigned char n;  // global count variable
long zeit=0;
long zeitarray[20];
long aktuellezeit;
void time_convert(unsigned long hundertstel, unsigned char zeile);
void messfunktion(void);
void LCD_puts(char *pStr1, char *pStr2, unsigned char);
void initSFR(void);
int run=0;  //countvariable  
bit runLCD=0;
bit erster=0;  //sobald der erste Laeufer im Ziel ist wird diese
               //Variable 1 gesetzt...
int laeuferNR=1;
bit Messung_ready;
bit Messung_running;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{  
   if(!Messung_running){
      zeit++;
      TCNT0=0x06;}
   else
   {;}
} 

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
   TCCR0=0x03;
   Messung_running=1;
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
   TCCR0=0x03;
   messfunktion();
}

void main(void)
{  
   bit x=0;
   initSFR();
   // Global enable interrupts
   #asm("sei")
   
   InitLCD(); // initialize LCD; auto increment cursorposition
   delay(10); // wait 250 ms before first write
   // write to LCD (cursor is at 1. pos. after initialization) 
   
   SetCursLCD(1);
   for(n=0;n<16;n++)   // write first 8 chars of welcome message
      {WrCharLCD(Fstmsg[n]);}
   
   SetCursLCD(17);
   for(n=0;n<16;n++)   // write first 8 chars of welcome message
      {WrCharLCD(Fstmsg[n]);}

   while (1)       // do forever
   {  
      if(Enter)
      {  Messung_ready=1;
         GICR|=0x40;
         MCUCR=0x01;
         GIFR=0x40; }
      else if(Back)
      {  Messung_ready=0;}
      else
      {  
         while(Messung_running && Messung_ready)
           {if(x=0)
           {   GICR|=0x80;
               MCUCR=0x04;
               GIFR=0x80;}
           else
               {time_convert((zeitarray[1]+zeit),1);
                time_convert(zeitarray[laeuferNR]+zeitarray[0],2);
                delay(10);}
      }    }
   }// End of while 

} //End of main

void time_convert(unsigned long hundertstel, unsigned char zeile)
{
   unsigned long int stunden, minuten, sekunden,
   minutenR, sekundenR, hundertstelR;
   unsigned char time[16],x;
   
   SetCursLCD(1);
   hundertstel = hundertstel / 10;
   hundertstelR =  hundertstel % 100; //hundertstel
   sekunden  = hundertstel / 100; //ganze sekunden
   sekundenR = sekunden % 60; //sekunden
   minuten   = sekunden / 60; //ganze minuten
   minutenR  = minuten % 60; //minuten
   stunden   = minuten / 60; //ganze Stunden
   
   sprintf(time, "%i. %02d:%02d:%02d,%02d ", 

laeuferNR,stunden,minutenR,sekundenR,hundertstelR);

   if(zeile==0){ 
      LCD_puts(time,time,0);}

   if(zeile==1){   
      LCD_puts(time,time,1);}

   if(zeile==2){   
      LCD_puts(time,time,2);}
     
}  //time_convert                              

void messfunktion(void)
{
   if(!erster) {
     zeitarray[1]=zeit;
     zeit=0;
     erster=1; }
   else {
    laeuferNR++;
    zeitarray[laeuferNR]=zeit; }
} 
 
void initSFR(void)
{
// Declare your local variables here

//Allgemeine Definitionen des Mikrocontrollers
// Port B initialization
PORTB=0x00;
DDRB=0x3F;
// Port C initialization
PORTC=0x7F;
DDRC=0x00;
// Port D initialization 
PORTD=0xFF;
DDRD=0x00;  
// Analog Comparator initialization
ACSR=0x80;
SFIOR=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
GICR|=0x00;
MCUCR=0x00;
GIFR=0x00;  
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
TCCR0=0x03;  //Prescaler 64 --> 0x01 = Standartwert
TCNT0=0x06;  //Vorladen mit 6 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
}          
/**Funktion um einzelne Zeichen eines Arrays auszugeben **/
void LCD_puts(char *pStr1, char *pStr2, unsigned char zeile)
{                       
    unsigned char count=0;
    
   if((zeile==1)||(zeile==0))
   { 
    SetCursLCD(1);
    while (*pStr1)
    { WrCharLCD(*pStr1++);
      count++;}
    while (count++ < LCD_SIZE)
    { WrCharLCD(' '); }
    delay(2);
    count = 0;
    }
    else
   if((zeile==2)||(zeile==0))
   {
    SetCursLCD(17);
    while (*pStr2)
    { WrCharLCD(*pStr2++);
      count++; }
    while (count++ < LCD_SIZE)
    { WrCharLCD(' ');}
   }
}

Ich würde mich echt freuen, wenn ihr mir weiter helfen könntet...


lg Patrick

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bevor wieder jemand diesen dämlichen abgenutzen Glaskugel-Spruch bringt, 
frag ich mal ganz "normal": Was genau geht denn nicht ?!

Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das Problem liegt daran, dass die Interrupts nicht so funktionieren 
wie sie sollten: sobald er erste interrupt (INT0) auftritt, wird der 
zweite Interrupt (INT1) nicht mehr erkannt... Beim nochmaligen auftreten 
von INT0 startet das Programm von vorne...

lg

Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
keiner eine Idee?

Ach ja, ich verwende CVAVR zum Programmieren und PonyProg zum 
Daten-überspielen...


lg

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick F. wrote:

> läuft, bis eine bestimmte Taste gedrückt wird. Über den INT1 Eingang
> kommen
>
> laufend Impulse.

Schön für die Impulse, daß sie reinkommen.
Aber was sollen diese bewirken ?

Versuch mal offline in Ruhe die Funktion zu beschreiben, d.h. nicht so 
wirr, sondern daß man es auch versteht, und dann poste es.


>          GICR|=0x40;
>          MCUCR=0x01;
>          GIFR=0x40; }

Ich hab keine Lust, ständig im Datenblatt zu blättern.
Also verwende bitte statt kryptischer Hexwerte die im Datasheet 
vordefinierten Bitnamen und kommentiere, was Du damit bewirkst.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und Code natürlich immer als Dateianhang posten !

Mein Scrollfinger ist schon total verkrampft.


Peter

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum nimmst du nicht einfach die C Funktion bei :

// Global enable interrupts
   #asm("sei")

Soviel ich weiß ist die doch sei(); oder ? Ansonnsten würde ich einfach 
mal versuchen inerhalb des ersten Iterrupts den zu deaktivieren damit er 
nicht einfach neu starten kann und erst beim Benden des anderen wieder 
zu aktivieren wenn ich die Funktion richtig verstanden hab =). Ich sehe 
nicht das du irgendwo inerhalb des Interrupts den auch wieder 
deaktivierst wie oben geschrieben.

Gruß Andreas

Autor: Pat F. (breaker87)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab mir jetzt Zeit genommen und eine Beschreibung (inkl Skizze) 
verfasst, welche sich im Anhang befindet.
Den C-Code habe ich auch in den Anhang gegeben...


lg Patrick

Autor: Andreas Kramer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum lässt du nicht einfach den Timer dauerhaft laufen und sezt einfach 
mit dem Int0 den Timer auf 0 und die intern erhöte Varible auch und 
deaktivierst noch Int0. So damit ist teil eins fertig.

Jetzt nimmst du Int1 und sagst ihm die im timer verwendete variable in 
ein Array bsp mit nem Zeiger und erhöst hier noch eine 2te variable um 
zu wissen der wievielte Wert das ist damit dein Array nicht überläuft 
z.b. noch damit ne Begrenzung einbauen. Jetzt setzt du die Variable im 
Timer auf 0 und verschiebst den Zeiger weiter für das nächste Ergebniss. 
Oder du nimmst anstelle von dem Array einfach die benötigte Anzahl von 
Variablen z.B. 4 und dann ne Schleife die jeweils die timervariable in 
der richtigen Var speichert.

Gruß Andreas

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Andreas:
In CodeVision gibts kein sei(). Das #asm("sei") ist schon korrekt.

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.