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
Hast du denn schon einmal generell Interrupts zum Laufen bekommen ? Siehe auch: http://www.mikrocontroller.net/articles/ARM-elf-GCC-Tutorial
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.
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
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.
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?
Aber die werden doch immer ungefähr gleich benannt, oder? Warum ist das beispiel denn so dämlich? wird da irgendwas falsch gemacht?
"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
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
Fast vergessen: die armVIC.c/.h gibt´s in den WinARM Examples irgendwo ;-) Grüße
Das solltest du so, oder so ähnlich ins wiki stellen, bis auf die CCO frequenz ist das gut ;)
Ja Ja, die CCO Frequenz ;) Da muss ich nachher nochmal gucken.
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.
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
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.