mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupts beim ARM ( LPC2106 ) in C


Autor: Armin Strobel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab folgendes Problem:

Ich möchte mit Cap1... PWM-Signale auswerten. Mir ist bisher eigentlich
fast klar was ich in welches regsiter zu schreiben hab, daß es
fuktioniert. Bisher hab ich nur in Assembler programmiert. Ich bin
bisher über einige C-Biblitheken gestolpert, aber die waren bisher nur
sehr schwer verwenden und sehr unvollständig. Kann mir da jemand
weiterhelfe?
P.S. fals es im text nicht ganz klar wurde ich möchte das in C
programieren.
Danke

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du denn schon einmal generell Interrupts zum Laufen bekommen ?
Siehe auch:
http://www.mikrocontroller.net/articles/ARM-elf-GCC-Tutorial

Autor: Armin Strobel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein ich hab bisher noch kein Interrupt zum laufen gebracht, genau das
ist ja mein Problem. Klar hab ich mir das ARM-elf-GCC-Tutorial
angeschaut. Mir ist nur nicht klar wie ich C beibringen soll was es bei
dem interrupt machen soll. Hab bisher schon erfolgreich einige AVR
Programme in Assembler und ein paar wenige in C geschrieben. Mir ist
auch klar wie ich ihm beibringe bei welchen ereignissen er ein
Interrupt auslösen soll. Ich weiß nur nicht wie ich ihm beibringe was
er dann zu tuen hat.
Beim AVR:
void interrupt(....)
{.....
...
}

Beim ARM:
???

Kann mit dem folgendem nicht viel Anfangen:

void _attribute_ ((interrupt("IRQ"))) isr(void); // Prototyp

void _attribute_ ((interrupt("IRQ"))) isr(void){
  // A lot of Work
  VICVectAddr = 0;       // Acknowledge Interrupt
}

Bräuchte lediglich mal ein Beispielprogramm mit einer vernünftigen Lib.

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void _attribute_ ((interrupt("IRQ"))) isr(void){ }

Dies ist die Deklaration der Interrupt Service Routine.
Hier kommen deine Instruktionen rein, die beim jeweiligen Interrupt
ausgeführt werden. Wie du einen Interrupt angibst ist auch im
Tutorial.
Einen Timer Interrupt Code kann ich morgen mal posten. Der lässt eine
LED toggeln im 1 sek Abstand (bei 14,7456 Quarz x4 PLL = 58,xx MHz).

Grüße

Autor: Lupin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube du solltest vorher auch die IRQs im CPU register aktivieren:

void enableIRQ(void) {
  asm volatile (
    "mrs  r0, cpsr\n"
    "and  r0, r0, #~0x00000080 \n"
    "msr  cpsr, r0\n"
  );
}


Lad dir mal WinARM runter und schau im examples ordner nach
"lpc2106_blink_switch_irq" da wird gezeigt wie man einen Timer mit
IRQ benutzt.

Autor: Armin Strobel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal danke an euch!

Hab ich doch alles schon längst gemacht.
lpc2106_blink_switch_irq ist ein sau dämliches Beispiel ( sorry für die
ausdrucksweise ).
Lest doch mal meine Frage genau durch.
Das mit dem IRQ aktivieren ist alles kein problem.

Nur leider weden die Interrupts in jder lib anderst benannt.

Hat niemand ein beispiel mit einem externen interrupt?

Autor: Lupin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber die werden doch immer ungefähr gleich benannt, oder?

Warum ist das beispiel denn so dämlich? wird da irgendwas falsch
gemacht?

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Nur leider weden die Interrupts in jder lib anderst benannt."
Es ist egal wie die ISR heißt, du übergibst ja eh nur die Adresse in
ein Adresse des VICs.

Morgen gibt´s Code, ich hoffe das ist dann ausreichend ;)

Grüße

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier der versprochene Code:

#include <arch/philips/lpc2114.h>
#include <stdlib.h>
#include "armVIC.h"

#define VIC_TIMER1 5

volatile unsigned char stat;

void init_MCU(void);
void _attribute_ ((interrupt("IRQ"))) timer1(void);

void init_MCU(void){
  //PLL Multiplier
  SCB_PLLCFG = 4-1; // Multiplier auf 4x
  SCB_PLLCON = 0x01; // PLLE Set
  SCB_PLLFEED = 0xAA;  //PLL Feed Sequence
  SCB_PLLFEED = 0x55;
  while ( !( SCB_PLLSTAT & (1<<10) ) ); // PLOCK testen
  SCB_PLLCON = 0x03; // PLLC & PLLE Set
  SCB_PLLFEED=0xAA;  //PLL Feed Sequence
  SCB_PLLFEED=0x55;

  //Memory Accelerator Module
  MAM_MAMCR = 0;
  MAM_MAMTIM = 3; // MAM-Fetch cycle to 3 cclk (>40MHz)
  MAM_MAMCR = 2; // MAM fully enabled -> See Page 75 in the Datasheet

  //Pheriphal Bus
  SCB_VPBDIV = 1; //VPB Divider = 1

  PCB_PINSEL1 = 0x00; // All Pins has to be I/O Ports
}

void _attribute_ ((interrupt("IRQ"))) timer1(void){
  T1_IR = 1; // Clear interrupt flag by writing 1 to Bit 0
  if (stat == 0){
    GPIO0_IOSET=(1<<25);
  }else{
    GPIO0_IOCLR=(1<<25);
    stat = !stat;
  }
  VICVectAddr = 0;       // Acknowledge Interrupt
}

int main (void){
  GPIO0_IODIR|=(1<<28)|(1<<25);
  init_MCU();
  SCB_MEMMAP = 1;  //interrupt vectors reside in flash
  T1_PR=64; // Prescaler für Timer1
  T1_MR0=921600L-1; // Match every Second on 14,7456 * 4x PLL
  T1_MCR=3; // Interrupt on MR0 and RESET MR0 on Match
  T1_TCR=1; // Start Timer1

  VICIntEnClear = 0xFFFFFFFF;
  VICIntSelect = 0x00000000;
  VICVectAddr0=(unsigned long)timer1;
  VICVectCntl0=(1<<5) | VIC_TIMER1;
  VICIntEnable=(1<<VIC_TIMER1);
  enableIRQ();
}

Dieses Programm lässt eine LED toggeln die an Port0.25 angeschlossen
ist.

Grüße

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fast vergessen:
die armVIC.c/.h gibt´s in den WinARM Examples irgendwo ;-)

Grüße

Autor: Lupin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das solltest du so, oder so ähnlich ins wiki stellen, bis auf die CCO
frequenz ist das gut ;)

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja Ja, die CCO Frequenz ;)
Da muss ich nachher nochmal gucken.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heheh, "sau daemlich" ist gut. Vielleicht erstmal die C-Kentnisse
vertiefen, das Manual des gcc durchlesen (zumindest den Abschnitt
function attributes) sowie den Abschnitt zum VIC im LPC-Datenblatt
lesen und auch zumindest halbwegs nachvollziehen bevor man hier
Formulierungen wie "Lest doch mal meine Frage genau durch" oder
"habe ich schon laengst gemacht" (woher soll man das wissen) oder
"sau daemlich" abwirft.

Habe mir das "sau daemliche" Beispiel grade nochmal angeschaut, mir
faellt auf Anhieb nicht ein, wie man die notwendigen Einstellungen fuer
"was es bei dem interrupt machen soll" simpler demonstrieren kann.
Verbessungsvorschlaege dafuer sind natuerlich willkommen.
Implementierung der ISR und Einstellung der Adresse im VIC sind bei
externem Interrupt im Prinzip genau so wie in dem "daemlichen"
Beispiel.

Von welchen "libs" die Rede ist bleibt offen, vermute mal, es handelt
sich um die verschiedenen SFR-Defintionsdateien, aber "libs" sind das
nicht.

Martin Thomas - derjenige, der das "sau daemliche" Beispiel
herausgegeben hat.

Autor: Ppp Mmm (sanic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Echt Martin,
mach mal nicht so dämliche Beispiele!
Woher soll man denn wissen was der Controller in der ISR machen soll?
Unmöglich von dir ;-)

Grüße

Autor: Armin Strobel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups da bin ich wohl jemandem auf die Füße getreten. :-)
War da nur etwas geladen.
Für einen C-Anfänger wie mich ist das nicht gerade einfach zu
verstehen.
Sorry aber das obilge Beispiel find ich etwas anschaulicher.
(Geschmacksache)

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.