Forum: Compiler & IDEs INT2 Problem Mega32


von Holger P. (holgerp)


Lesenswert?

Hallo,

ich habe ein Problem mit dem externen INT2 vom Mega32.

ich habe folgendes an code:

Externer INT0 und INT1 funktionieren, was mache ich falsch??


...

  // globale interrupt register INT0 - INT2 einschalten
  GICR |= (1<<INT0); // enable INT0 - PD2
  GICR |= (1<<INT1); // enable INT1 - PD3
  GICR |= (1<<INT2); // enable INT2 - PB2

  // INT2 fallend Flanke
  MCUCSR |= (1<<ISC2);

...

/*
** Interrupt routine für externen INT2 - PB2
*/
ISR(INT2_vect)
{
 TxUart("INT2\r\n");

}

...

sei(); Globale interrupts einschalten


....

von Oliver (Gast)


Lesenswert?

Das einzige, was in den paar Zeilen auffällt, ist der falsche Kommentar 
in

>  // INT2 fallend Flanke
>  MCUCSR |= (1<<ISC2);

Oliver

von Holger P. (holgerp)


Lesenswert?

Hi Oliver,

dann berichtige mich doch bitte. Habe ja um Hilfe gebeten, weil ich das 
nicht ganz verstehe.

Ist denn ansonsten alles richtig und komplett, was man benötigt um INT2 
abzufragen??

Zur Beschaltung:

Taster an einer Seite an Masse und die andere halt am INT2.

von gast (Gast)


Lesenswert?

Datenblatt S.67:
1
If ISC2 is written to one, a rising edge on INT2 activates the interrupt.

von Holger P. (holgerp)


Lesenswert?

...

Ok, berichtigt:

 // INT2 steigende Flanke
 MCUCSR |= (1<<ISC2);

bekomme aber trotz dem keinen Interrupt.

Muss ich noch etwas anderes ein-/ausschalten? Was ist mit AINT0 ??


Hoger ...

von Oliver (Gast)


Lesenswert?

>bekomme aber trotz dem keinen Interrupt.

Woran merkst du das denn?
Funktioniert das TxUart() auch, wenn es dank Tasterprellen mehrfach 
hintereinander aufgerufen wird, auch wenn dabei noch nicht mal das 
allererste Zeichen über die Schnittstelle gegangen ist?

Ansonsten, wie eigentlich immer: zeig mal das ganze Programm, nicht nur 
die Zeilen, in denen du den Fehler vermutest. Denn in 99% der Fälle 
steckt der Fehler ganz woanders.

Oliver

von Holger P. (holgerp)


Lesenswert?

Hallo Oliver,

hier mal ein komplett abgespecktes Teil. Funzt Totzdem nicht !


#include "main.h"

/*
** delay ms routine
*/
void dms(unsigned int ms)
{
  unsigned int zaehler;
  while (ms)
  {
    zaehler = F_CPU / 5000;
    while (zaehler) {
      asm volatile ("nop");
      zaehler--;
    }
    ms--;
  }
}

/*
** delay ys routine
*/
void dus(unsigned int us)
{
  if (us < 4)
    return;

  if (us < 20)
    us-= 3;

  while (us)
  {
    asm volatile ("nop");
    us--;
  }
}

void Beep(u08 count, unsigned int le)
{
u08 i;

  for(i= 0;i < count; i++){
    sbi(BUZZER_PORT, BUZZER_PIN);
    dms(le);
    cbi(BUZZER_PORT, BUZZER_PIN);
    dms(le);
  }
}

/*
** initializing
*/
void Init(void){

  // init buzzer PIN
  sbi(BUZZER_DDR, BUZZER_PIN); // as output
  cbi(BUZZER_PORT,BUZZER_PIN); // Pin is low


  //### GLOBAL INTERRUPT CONTROLLER ###
  // enable disable the interrupts over
  // the global control register
  GICR |= (1<<INT0); // enable INT0 - PD2
  GICR |= (1<<INT1); // enable INT1 - PD3
  GICR |= (1<<INT2); // enable INT2 - PB2

  // INT2 fallende Flanke
  MCUCSR&= ~(1<<ISC2);

  //### SET SLEEP MODE ###
  // SLEEP_MODE_IDLE
  // SLEEP_MODE_PWR_DOWN
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  //### INTERRUPT PINS INITIALIZATION ###
  // as input to read from any key

  // INT0
  cbi(DDRD, PD2);   // input for read
  sbi(PORTD,PD2);    // set pullups

  // INT1
  cbi(DDRD, PD3);   // input for read
  sbi(PORTD,PD3);    // set pullups


  // INT2
  cbi(DDRB, PB2);   // input for read
  sbi(PORTB,PB2);    // set pullups

  // wachdog enable 2 secounds
  //wdt_enable(WDTO_2S);
}


/*
** INT0 - PD2
*/
ISR(INT0_vect)
{
  Beep(3, 500);

  while ( bit_is_clear(PIND, PD2)){
    dms(1);
  }

  gSleepCnt= 0;

  return;
}

/*
** INT1 - PD3
*/
ISR(INT1_vect)
{
  Beep(5, 500);
  while ( bit_is_clear(PIND, PD3)){
    dms(1);
  }

  gSleepCnt= 0;

  return;
}

/*
** INT2 - PB2
*/
ISR(INT2_vect)
{
  Beep(8, 500);
  while ( bit_is_clear(PINB, PB2)){
    dms(1);
  }

  gSleepCnt= 0;

  return;
}


/*
**############# MAIN ###########################
*/
int main(void) {
u08  gMainDelay;

  Init();
  sei();

  Beep(3,200);

  // init buzzer PIN
  sbi(BUZZER_DDR, BUZZER_PIN); // as output
  cbi(BUZZER_PORT,BUZZER_PIN); // Pin is low

  // init member
  gMainDelay    = 1; // 1 ms delay
  gSleepDelTime  = 3000; // 3 secounds
  gSleepCnt      = gSleepDelTime; // now to sleep

  wdt_disable();


  //###################################################################### 
#########
  //### Main Loop function
  //###################################################################### 
#########
  for (;;) {

    //####
    // tue irgend was ....

    //### sleep
    if (gSleepCnt >= gSleepDelTime) {
      gSleepCnt= 0;
      dms(1);
      sei();
      Beep(1,1);
      sleep_mode();

    }

  // increment the sllep counter
  gSleepCnt++;

  // main delay
  dms(gMainDelay);

  }// for (;;)
}

von Gast (Gast)


Lesenswert?

**GlaskugelModus An**

Am Int2 Pin fehlt der PullUp-Widerstand.

**GlaskugelModus Aus**

Ein Schaltplan wäre von Vorteil.

von Holger P. (holgerp)


Lesenswert?

Ja, hätte ich dazuschreiben sollen

Anschlussplan:

Taster      _
           _|_
GND -------| |----+---| 1 Kilo |----------->> +5V
                  |
                  |
                  |
                 ---
                |xxx|  <<--- INT2 PB2
                 ---

von Oliver (Gast)


Lesenswert?

>hier mal ein komplett abgespecktes Teil.

Sicher?

Bei mir fangen AVR-Programme eigentlich immer mit
1
#include <avr/io.h>
an.

Zeig doch mal was kompilierbares.

Und in der avr-libc gibt es wunderschöne delay-Funktionen. Die 
funktionieren sogar :-)

Oliver

von Holger P. (holgerp)


Angehängte Dateien:

Lesenswert?

Oliver,

ich habe jetzt mal das kleine Testprog angehangen.

Eventuell kannst du ja den / die Fehler erkennen.

Danke vorab für dein Bemühen.

Mario..

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fehler sehe ich erstmal nicht, aber externer Interrupt mit einem
mechanischen Taster ist ein rotes Tuch.  ISR mit einem delay drin
ebenfalls.

Du hast das Pferd irgendwie von hinten aufgezäumt.  Mechanische
Taster fragt man im `heartbeat'-Timer-Interrupt ab, in dem man auch
die Entprellung macht.

(Den IRQ würde ich wohl via JTAG debuggen wollen, wenn ich das Problem
hätte.)

von Oliver (Gast)


Lesenswert?

Also, in der Simulation in VMLAB springt er in die ISR2, wie erwartet. 
Aber die delay-Funktionen sind arg seltsam. Nimm doch die aus der 
avrlibc.

Oliver

von Holger P. (holgerp)


Lesenswert?

Hallo,

bin wieder da. Erst einmal vielen Dank für die Hilfe.

Meine Hardware habe ich überprüft, alles soweit ok. Delay Funktion werde 
ich tauschen.

Hat von Euch einer einen Code-Schnipsel mit dem ich es doch eventuell 
testen kann?

Jörg, wie sieht denn solch eine Abfrage der Taster aus, wenn der 
Controller im Sellep Mode ist - set_sleep_mode(SLEEP_MODE_PWR_DOWN) und 
er durch den Taster aufgweckt werden soll??

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Holger Patz schrieb:

> Jörg, wie sieht denn solch eine Abfrage der Taster aus, wenn der
> Controller im Sellep Mode ist - set_sleep_mode(SLEEP_MODE_PWR_DOWN) und
> er durch den Taster aufgweckt werden soll??

Dann muss man natürlich einen Interrupt haben, aber beim ATmega32
kannst du meiner Erinnerung nach den INT2 dafür vergessen, da bei
diesen alten AVRs nur ein pegelgetriggerter Interrupt den Controller
aus dem Sleep holen kann, und das wiederum geht beim INT2 nicht
einzustellen.

Wenn du das willst, dann nimm einen pinkompatiblen ATmega324P.

Nach dem Aufwecken klemmt man dann den Externinterrupt sofort ab,
und die normale (zeitgesteuerte) Tastaturabfrage der Applikation
erkennt dann die gedrückte Taste.

von Oliver (Gast)


Lesenswert?

Beim Mega32 weckt aus dem Power-down-mode auch der INT2 wieder auf.
Steht zumindest mal so im Datenblatt.

>Hat von Euch einer einen Code-Schnipsel mit dem ich es doch eventuell
>testen kann?

Tja, dummerweise tut dein Code. Der springt in die ISR. Etwas anderes 
würde mit anderem Code auch nicht passieren.

Oliver

von Holger P. (holgerp)


Lesenswert?

Ok, dann bin ich jetzt ein wenig ratlos, was oder wie ich das lösen 
soll. Eventuell Vorschlag vom Jörg den ATmega324P zu probieren.

Problem ist im Moment, dass ich von 3 verschiedenen Taster den Mega 
aufwecken muss. INT0 und INT1 funktionieren ja aaaber INT2 halt nicht.

Oliver, einen Taster hattest du bei deinem Test nicht angeschlossen oder 
??
Wenn das mit einem physikalisch angeschlossenen Taster bei dir geht, 
dann kann es ja wirklich nur an meine Hardware liegen.

Ok, danke erst einmal ...

von Oliver (Gast)


Lesenswert?

>Problem ist im Moment, dass ich von 3 verschiedenen Taster den Mega
>aufwecken muss. INT0 und INT1 funktionieren ja aaaber INT2 halt nicht.

Das Problem ist, daß du bisher immer noch nicht gesagt hast, WAS nicht 
funktioniert. Springt er gar nicht in die ISR für INT2, auch nicht, wenn 
der Prozessor nicht im sleepmode ist? Oder wird er nur nicht aufgeweckt?

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Oliver schrieb:
> Beim Mega32 weckt aus dem Power-down-mode auch der INT2 wieder auf.
> Steht zumindest mal so im Datenblatt.

OK, stimmt, sehe ich jetzt auch.  Ich hatte mich nur dran erinnert,
dass INT0/1 nur level triggered aufwecken können.

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
Noch kein Account? Hier anmelden.