// Beispiel für Spurious und IRQ1 und IRQ von PIOB // // von: Manfred Pester // vom: 14.11.2006 // geändert: 13.11.2007 // TIOA3 (P3B11) mit IRQ1 (P3A4) verbinden Timer löst Interrupt // oder Spurious aus // Taste 1 und 2 löst Interrupt PIOB aus // Taste 1 initialisiert IRQ1 auf high-Pegel Triggerung und // erzeugt durch Timer 3 einen kurzen Impuls an IRQ1 was einen // Spurious-IRQ zur Folge haben sollte. // Taste 2 initialisiert IRQ1 auf positive Flankentriggerung und // erzeugt eine sichtbare Blinkfrequenz an TIOA3. // IRQ1-handler laesst LED1 toggeln // SpuriousIRQ laesst die LED2 toggeln // ACHTUNG vorm START RESET nicht vergessen #include "../h/pmc.h" #include "../h/pio.h" #include "../h/aic.h" #include "../h/tc.h" volatile int PIOB_IRQ_Bits=KEY1|KEY2; volatile int PIOA1=0x02; volatile int PIOA10=0x0400; volatile int PIOA9=0x0200; void irq_handlerPIOB (void) __attribute__ ((interrupt)); void Spurious_handler (void) __attribute__ ((interrupt)); void irq1_handler (void) __attribute__ ((interrupt)); void irq1_routine (void); void Timer3_init( void ); void irq1_routine(void) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B StructAIC* aicbase = AIC_BASE; // Basisadresse Advanced Interrupt Controller StructTC* timerbase3 = TCB3_BASE; // Basisadressse TC Block 1 // durch diese Sequenz wird ein Blinken der LED1 erreicht if( piobaseB->PIO_ODSR & LED1) piobaseB->PIO_CODR = LED1; else piobaseB->PIO_SODR = LED1; aicbase->AIC_EOICR = piobaseB->PIO_ISR; } void Spurious_handler (void) { StructAIC* aicbase = AIC_BASE; // Basisadresse Advanced Interrupt Controller StructTC* timerbase3 = TCB3_BASE; // Basisadressse TC Block 1 StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B // durch diese Sequenz wird ein Blinken der LED2 erreicht if( piobaseB->PIO_ODSR & LED2) piobaseB->PIO_CODR = LED2; else piobaseB->PIO_SODR = LED2; aicbase->AIC_EOICR = piobaseB->PIO_ISR; } // Interruptserviceroutine für Anforderungen an PIOB z.B. die Tasten SW1 und SW2 void irq_handlerPIOB (void) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO B StructAIC* aicbase = AIC_BASE; //__ StructTC* timerbase3 = TCB3_BASE; // Basisadressse TC Block 1 if ( !(piobaseB->PIO_PDSR & KEY1)) { aicbase->AIC_SMR[30] = 0x46; //high-Pegeltriggerung für IRQ1 timerbase3->TC_CCR = TC_CLKDIS; // Disable Clock // Initialize the mode of the timer 3 timerbase3->TC_CMR = TC_ACPC_CLEAR_OUTPUT | //ACPC : Register C clear TIOA TC_ACPA_SET_OUTPUT | //ACPA : Register A set TIOA TC_WAVE | //WAVE : Waveform mode TC_CPCTRG | //CPCTRG : Register C compare trigger enable TC_CLKS_MCK8; //TCCLKS : MCKI / 1024 timerbase3->TC_RA = 65530; // timerbase3->TC_RC = 65531; // kurzer high-Impuls timerbase3->TC_CCR = TC_CLKEN; timerbase3->TC_CCR = TC_SWTRG; } if ( !(piobaseB->PIO_PDSR & KEY2)) { aicbase->AIC_SMR[30] = 0x66; //Timer 3 starten für Spurious Interrupt // Initialize the mode of the timer 3 timerbase3->TC_CMR = TC_ACPC_CLEAR_OUTPUT | //ACPC : Register C clear TIOA TC_ACPA_SET_OUTPUT | //ACPA : Register A set TIOA TC_WAVE | //WAVE : Waveform mode TC_CPCTRG | //CPCTRG : Register C compare trigger enable TC_CLKS_MCK1024; //TCCLKS : MCKI / 1024 timerbase3->TC_RA = 2440; // timerbase3->TC_RC = 4880; // ca. 5Hz Rechtecksignal timerbase3->TC_CCR = TC_CLKEN; timerbase3->TC_CCR = TC_SWTRG; } aicbase->AIC_EOICR = piobaseB->PIO_ISR; } void irq1_handler (void) { StructAIC* aicbase = AIC_BASE; irq1_routine(); aicbase->AIC_EOICR = aicbase->AIC_ISR; } void PIOB_IRQ_init( void ) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B StructAIC* aicbase = AIC_BASE; // Basisadresse PIO B aicbase->AIC_IDCR = 0x4000; aicbase->AIC_ICCR = 0x4000; piobaseB->PIO_IER = KEY1 | KEY2; // Bits welche IRQ an PIOB auslösen dürfen aicbase->AIC_SMR[14] = 0x21; aicbase->AIC_SVR[14] = (unsigned int) irq_handlerPIOB; aicbase->AIC_IECR = 0x4000; } void PA10_IRQ1_init( void ) { StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A StructAIC* aicbase = AIC_BASE; aicbase->AIC_IDCR = 0x40000000; aicbase->AIC_ICCR = 0x40000000; piobaseA->PIO_ODR = PIOA10; piobaseA->PIO_PDR = PIOA10; // Interrupt fuer Interruptbox aicbase->AIC_SMR[30] = 0x46; aicbase->AIC_SVR[30] = (unsigned int) irq1_handler; aicbase->AIC_IECR = 0x40000000; } void Spurious_init( void ) { StructAIC* aicbase = AIC_BASE; aicbase->AIC_SPU = (unsigned int) Spurious_handler; } void PA10_IRQ1_end( void ) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B StructAIC* aicbase = AIC_BASE; // Basisadresse PIO B aicbase->AIC_IDCR = 0x40000000; } void PIOB_IRQ_end( void ) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B StructAIC* aicbase = AIC_BASE; // Basisadresse PIO B piobaseB->PIO_IDR = PIOB_IRQ_Bits; aicbase->AIC_IDCR = 0x4000; } void PIOB_init( void ) { StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO B piobaseB->PIO_PER = LED1 | KEY1 |KEY2; piobaseB->PIO_OER = LED1 | LED2; } void Timer3_init( void ) { StructTC* timerbase3 = TCB3_BASE; // Basisadressse TC Block 1 StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO B timerbase3->TC_CCR = TC_CLKDIS; // Disable Clock // Initialize the mode of the timer 3 timerbase3->TC_CMR = TC_ACPC_CLEAR_OUTPUT | //ACPC : Register C clear TIOA TC_ACPA_SET_OUTPUT | //ACPA : Register A set TIOA TC_WAVE | //WAVE : Waveform mode TC_CPCTRG | //CPCTRG : Register C compare trigger enable TC_CLKS_MCK8; //TCCLKS : MCKI / 1024 // Initialize the counter: timerbase3->TC_RA = 65530; timerbase3->TC_RC = 65534; //__ // Start the timer : // timerbase3->TC_CCR = TC_CLKEN ; //__ // timerbase3->TC_CCR = TC_SWTRG ; //__ piobaseA->PIO_PER = (1<PIO_OER = (1<PIO_CODR = (1<PIO_PDR = (1<PMC_PCER = 0x6200; // Peripheral Clocks einschalten für PIOB, PIOA, Timer3 PIOB_init(); Timer3_init(); PIOB_IRQ_init(); PA10_IRQ1_init(); Spurious_init(); while(1) { } // PIOB_IRQ_end(); // PIOA_IRQ_end(); // PA9_IRQ0_end(); // PA10_IRQ1_end(); return 0; }