www.mikrocontroller.net

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


Autor: Tobias Eckhardt (doenges2)
Datum:

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

Autor: Marco L. (lehmi)
Datum:

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

Autor: Tobias Eckhardt (doenges2)
Datum:

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

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.