Forum: Mikrocontroller und Digitale Elektronik IRQ durch Tastendruck - AT91Sam7S256 und Olimex


von Tobias E. (doenges2)


Lesenswert?

Hallo,

ich versuche mich zur Zeit am ersten Interruptprogrämmchen mit meinem 
neuen ARM vo Atmel und stoße auf ein komisches Problem für mich.
Eine LED soll ganz normal über einen delay blinken und die andere durch 
einen Tastendruck, also durch einen Interrupt.

Hier ist mal die main und die dazugehörige ISR:

MAIN.C:
------------------------------------------------
#include "AT91SAM7S256.h"
#include "board.h"
#include "delay.h"
#include "stdlib.h"
#include "string.h"

void button2irqhandler (void);
extern  void LowLevelInit(void);
extern  unsigned enableIRQ(void);
void LowLevelInit();

int main (void)  {

// Set up the LEDs (PA0 - PA3)
  volatile AT91PS_PIO  pPIO = AT91C_BASE_PIOA;      // pointer to PIO 
data structure
  pPIO->PIO_PER = LED_MASK | Button1;          // PIO Enable Register - 
allow PIO to control pins P0 - P2 and pin 19
  pPIO->PIO_OER = LED_MASK;              // PIO Output Enable Register - 
sets pins P0 - P2 to outputs
  pPIO->PIO_SODR = LED_MASK;              // PIO Set Output Data 
Register - turns off the two LEDs

// Select PA19 (pushbutton) to be IRQ function (Peripheral B)
  pPIO->PIO_BSR = Button2;

// Set up the AIC  registers for Button2
  volatile AT91PS_AIC  pAIC = AT91C_BASE_AIC;      // pointer to AIC 
data structure
  pAIC->AIC_IDCR = (1<<AT91C_ID_IRQ0);        // Disable timer 0 
interrupt in AIC Interrupt Disable Command Register
  pAIC->AIC_SVR[AT91C_ID_IRQ0] =            // Set the Button2 IRQ 
handler address in AIC Source
      (unsigned int)button2irqhandler;            // Vector Register[12]
  pAIC->AIC_SMR[AT91C_ID_IRQ0] =            // Set the interrupt source 
type and priority
  (AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0x4 );       // in AIC Source Mode 
Register[12]
  pAIC->AIC_ICCR = (1<<AT91C_ID_IRQ0);         // Clear the TC0 
interrupt in AIC Interrupt Clear Command Register
  pAIC->AIC_IDCR = (0<<AT91C_ID_IRQ0);        // Remove disable timer 0 
interrupt in AIC Interrupt Disable Command Reg
  pAIC->AIC_IECR = (1<<AT91C_ID_IRQ0);         // Enable the TC0 
interrupt in AIC Interrupt Enable Command Register
  enableIRQ();


  while (1) {
    Delay(200);
    if  ((pPIO->PIO_ODSR & LED1) == LED1)  {    // read previous state 
of LED1
      pPIO->PIO_CODR = LED1;
    } else {
      pPIO->PIO_SODR = LED1;
    }
  }
}
--------------------------------------------
button2isr.c:
--------------------------------------------
#include "AT91SAM7S256.h"
#include "board.h"

void button2irqhandler (void) {

  volatile AT91PS_TC     pTC = AT91C_BASE_TC0;    // pointer to timer 
channel 0 register structure
  volatile AT91PS_PIO    pPIO = AT91C_BASE_PIOA;    // pointer to PIO 
register structure
  unsigned int       dummy;            // temporary

  dummy = pTC->TC_SR;                  // read TC0 Status Register to 
clear interrupt

  if  ((pPIO->PIO_ODSR & LED2) == LED2)
    pPIO->PIO_CODR = LED2;              // turn LED2 (DS2) on
  else
    pPIO->PIO_SODR = LED2;              // turn LED2 (DS2) off
}
------------------------------------------



Ich erhalte folgende Fehlermeldung:

make -k all
..linking
arm-elf-ld -v -Map main.map -Ttest123.cmd -o main.out crt.o  main.o 
lowlevelinit.o libc.a libm.a libgcc.a
GNU ld version 2.17
main.o: In function `main':
L:\Workspace\test/main.c:33: undefined reference to `enableIRQ'
L:\Workspace\test/main.c:43: undefined reference to `button2irqhandler'
make: *** [main.out] Error 1
make: Target `all' not remade because of errors.


Hat irgendjemand eine Ahnung?

Gruß

Tobias

von Marco L. (lehmi)


Lesenswert?

1. der linker muss auch wissen, dass er button2isr.c mit benutzen muss, 
das weiß er bis jetzt noch nicht (siehe Output)
2. wo ist denn die Funktion enableIRQ ?

Grüße

lehmi

von Tobias E. (doenges2)


Lesenswert?

ZU 1. der Felher war in der makefile, dort hatte ich die ganzen 
Interruptfiles noch nicht dazugefügt, dumm!
Seitdem ich das getan habe kann ich "build Project" ohne Fehler 
durchführen

Zu 2.
Die Function habe ich mir von einem anderem Projekt "geklaut"
So ganz verstehen tue ich die nicht, aber dort funktioniert sie!

Hier ist sie:

unsigned enableIRQ(void)
{
  unsigned _cpsr;

  _cpsr = __get_cpsr();
  __set_cpsr(_cpsr & ~IRQ_MASK);
  return _cpsr;
}


Mittlerweile bringe ich das laufende Programm zum Absturz wenn ich die 
Taste drücke......nach einer gewissen Zeit startet der Watchdog das 
Programm von vorne!  So als springt er irgendwo hin und bleibt dann 
hängen.

Beim Neustart durch den Watchdog leuchtet die LED, die für den Interrupt 
gedacht ist, ganz kurz auf! Auch so ein Rätsel was es zu lösen gilt.

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.