dspic Interrupts The dspic30f4012 has 30 interrupt sources which 3 are external interrupts and 4 processor exception traps. There are 8 user selectable priority levels for each interrupt source. These interrupts are executed according to the priority level set for them. During an Interrupt, the CPU fetches the interrupt address from the Interrupt Vector Table(IVT) and place it into the Program Counter. The Interrupt Vector table is placed at the program memory 0x000004 near the beginning. Here is the dspic30f4012 Interrupt Vector Table. Interrupt Vector Interrupt Source Number Number Highest Natural Order Priority 0 8 INT0 External Interrupt 0 1 9 IC1 Input Capture 1 2 10 OC1 Output Compare 1 3 11 T1 Timer 1 4 12 IC2 Input Capture 2 5 13 OC2 Output Compare 2 6 14 T2 Timer 2 7 15 T3 Timer 3 8 16 SPI1 9 17 U1RX UART1 Receiver 10 18 U1TX UART1 Transmitter 11 19 ADC ADC Convert Done 12 20 NVM NVM Write Complete 13 21 SI2C I2C Slave Interrupt 14 22 MI2C I2C Master Interrupt 15 23 Input Change Interrupt 16 24 INT1 External Interrupt 1 17 25 IC7 Input Capture 7 18 26 IC8 Input Capture 8 19 27 OC3 Output Compare 3 20 28 OC4 Output Compare 4 21 29 T4 Timer4 22 30 T5 Timer5 23 31 INT2 External Interrupt 2 24 32 U2RX UART2 Receiver 25 33 U2TX UART2 Transmitter 27 35 C1 Combined IRQ for CAN1 39 47 PWM PWM Period Match 40 48 QEI QEI Interrupt 43 51 FLTA PWM Fault A The peripheral interrupts (i.e. ADC, timers, PWMs. UART and etc) and exceptions (i.e. traps) are activated by configuring appropriate special function registers. The Interrupt Control and Staus Registers are :- ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 1
INTCON1,INTCON2 global INTerrupt CONtrol Registers. INTCON1 conatains the interrupt NeSting DISable bit, as well as status flags for the processor trap sources. The INCON2 register controls the external interrupt request signal and the use of the alternative vector table. IFS0,IFS1,IFS2 Interrupt Flag Status Registers conatain all the interrupt request flags. Each source of interrupt has a status bit, which is set by it s respective peripherals or external signal and is cleared via software. IEC0,IEC1,IEC2 Interrupt Enable Control Registers contain all the interrupt enable bits. These bits are used to individually enable interrupts from the peripherals or external signals. IPC0 IPC11 Interrupt Priority Control Registers are used to set each user interrupt source to one of the eight priority levels. ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 2
SR The Status Register is NOT specifically part of the interrupt controller hardware, but if contains the IPL<2:0> status bits that indicates the current CPU priority level. The user may change the current CPU priority by to these IPL bits. CORCON CORe CONtrol register is NOT specifically part of the interrupt controller hardware, but if contains the IPL3 status bit which indicates the current CPU priority level. IPLs is a Read ONLY bit so that trap events can not be masked by the user software. Interrupt initialization 1. Set the NSTDIS (NeSTed DISabled) in INTCON1<15> if nested interrupts are not required. 2. Select the user assigned priority level for the interrupt source (if more than one interrupt is used and the priority of the interrupt events are essential) by writing the control bits in the appropriate IPCx Control register. 3. Clear the interrupt flag status bit associated with the peripheral in the associated IFSx Stauts register. 4. Enable the interrupt source by setting the interrupt enable control bit associated with the source in the appropriate IECx Control register. Interrupt enable bits in IEC0,IEC1,IEC2 registers are set to enable appropriate interrupt. The dspic30f keeps all interrupt vectors in Interrupt Vector Table (IVT) ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 3
MPLAB XC16 compiler automatically associates interrupt vectors with special user defined C functions as long as : They do not return any value (use type void). No parameter can be passed to the function (use parameter void). They cannot be called directly by other functions. The following example illustrates the syntax that could be used to associate a function to the Timer1 interrupt vector: void attribute (( interrupt)) _T1Interrupt ( void) { // interrupt service routine code here... } // InterruptVector In practice, to avoid the verbose syntax attribute (( interrupt)), it is more convenient to use the predefined macro _ISR as in the following example: void _ISR _T1Interrupt (void) { // interrupt service routine code here... } // InterruptVector ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 4
/* File: newmainxc16.c * Author: parchizh * * Created on 02 March 2015, 13:28 */ #include "p30f4012.h" //---------------------------------------------------------------------------- // Macros for Configuration Fuse Registers _FOSC(CSW_FSCM_OFF & XT_PLL16); /* Set up for Crystal */ _FWDT(WDT_OFF); /* Turn off the Watch-Dog Timer. */ /* Enable MCLR reset pin and turn off the power-up timers. */ _FBORPOR(PBOR_OFF & MCLR_EN); _FGS(CODE_PROT_OFF); /* Disable Code Protection */ /* Global Variables and Functions */ // #define _ISR attribute ((interrupt)) void main(void) { // setting up the Timer 1 TRISEbits.TRISE0 = 0; // Configure Port RE0 to be output PR1 = 15151; // set PR1 for 0.5 ms T1CONbits.TSIDL = 0; // off in idle mode T1CONbits.TCS = 0; // use internal clock Tcy T1CONbits.TCKPS = 0; // prescalar 1:1 T1CONbits.TGATE = 0; // no gated operation T1CONbits.TON = 1; // turn the timer ON // Setting up the Interrupt for the Timer 1 IFS0bits.T1IF = 0; // T1 interrupt flag cleared IEC0bits.T1IE = 1; // T1 interrupt enabled } while(1){ } void _ISR _T1Interrupt (void) {// interrupt service routine code here... PORTEbits.RE0 ^=1; // toggle the port pin IFS0bits.T1IF = 0; // clear timer1 flag } // _InterruptVector //************************************************************* //void attribute (( interrupt)) _T1Interrupt ( void) //{ // interrupt service routine code here... // PORTEbits.RE0 ^=1; // toggle the port pin // IFS0bits.T1IF = 0; // clear timer1 flag //} // _InterruptVector //*************************************************************/ /* * File: T12345_Interrupt_Pulse_mainXC16.c * Author: parchizh * * Created on 03 March 2015, 14:39 */ ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 5
#include "p30f4012.h" _FOSC(CSW_FSCM_OFF & XT_PLL16); /* Set up for Crystal */ _FWDT(WDT_OFF); /* Turn off the Watch-Dog Timer. */ /* Enable MCLR reset pin and turn off the power-up timers. */ _FBORPOR(PBOR_OFF & MCLR_EN); _FGS(CODE_PROT_OFF); /* Disable Code Protection */ /* Global Variables and Functions */ // #define _ISR attribute ((interrupt)) [ macro example ] void main(void) { TRISB = 0x0000; ADPCFG = 0xFFFF; //Port B is outputs //1st channel is sampled and coverted // Configure Timer1 to sample at 2KHz // Period1 = PR1 * prescaler * Tcy = 15151 * 1 * 33ns = 0.50000 ms (2KHz) PR1 = 15151; T1CON = 0b1000000000000000; // Type A timer = timer 1 // 1X-XXXXXX---X--X TON 1 = timer1 ON // -X0XXXXXX---X--X TSIDL 0 = operate during idle // -X-XXXXXX0--X--X TGATE 0 = Gated Time accumulation disabled // -X-XXXXXX-00X--X TCKPS 00= Timer input prescale 1:1 // -X-XXXXXX---X0-X TSYNC 0 = Do not Sync External clock(when TCS = 1) // -X-XXXXXX---X-0X TCS 0 = Clock source 0=internal(fosc/4) // Configure Timer2 to sample at 4KHz // Period1 = PR2 * prescaler * Tcy = 7575 * 1 * 33ns = 0.25000 ms (4KHz) PR2 = 7575; T2CON = 0b1000000000000000; // Type B timer = timer 2 // 1X-XXXXXX----X-X TON 1 = timer2 ON // -X0XXXXXX----X-X TSIDL 0 = operate during idle // -X-XXXXXX0---X-X TGATE 0 = Gated Time accumulation disabled // -X-XXXXXX-00-X-X TCKPS 00= Timer input prescale 1:1 // -X-XXXXXX---0X-X T32 0 = Timers 2/3 form separate 16-bit timers // -X-XXXXXX----X-X TCS 0 = Clock source 0=internal(fosc/4) // Configure Timer1 to sample at 8KHz // Period3 = PR3 * prescaler * Tcy = 3788 * 1 * 33ns = 0.12500 ms (8KHz) PR3 = 3788; T3CON = 0b1000000000000000; // Type C timer = timer 3 // 1X-XXXXXX---XX-X TON 1 = timer3 ON // -X0XXXXXX---XX-X TSIDL 0 = operate during idle // -X-XXXXXX0--XX-X TGATE 0 = Gated Time accumulation disabled // -X-XXXXXX-00XX-X TCKPS 00= Timer input prescale 1:1 // -X-XXXXXX---XX0X TCS 0 = Clock source 0=internal(fosc/4) // Configure Timer2 to sample at 16KHz // Period4 = PR4 * prescaler * Tcy = 1894 * 1 * 33ns = 0.06250 ms (16KHz) PR4 = 1894; T4CON = 0b1000000000000000; // Type B timer = timer 4 // 1X-XXXXXX----X-X TON 1 = timer4 ON // -X0XXXXXX----X-X TSIDL 0 = operate during idle // -X-XXXXXX0---X-X TGATE 0 = Gated Time accumulation disabled // -X-XXXXXX-00-X-X TCKPS 00= Timer input prescale 1:1 // -X-XXXXXX---0X-X T32 0 = Timers 4/5 form separate 16-bit timers // -X-XXXXXX----X-X TCS 0 = Clock source 0=internal(fosc/4) // Configure Timer1 to sample at 32KHz // Period5 = PR5 * prescaler * Tcy = 947 * 1 * 33ns = 0.03125 ms (32KHz) PR5 = 947; ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 6
T5CON = 0b1000000000000000; // Type C timer = timer 5 // 1X-XXXXXX---XX-X TON 1 = timer3 ON // -X0XXXXXX---XX-X TSIDL 0 = operate during idle // -X-XXXXXX0--XX-X TGATE 0 = Gated Time accumulation disabled // -X-XXXXXX-00XX-X TCKPS 00= Timer input prescale 1:1 // -X-XXXXXX---XX0X TCS 0 = Clock source 0=internal(fosc/4) // Configure Interrupt Priority IPC0 = 0b0001000000000000; //X001X---X---X--- timer 1 IP level 1 IPC1 = 0b0001000100000000; // timer 3 IP level 1, timer 2 IP level 1 IPC5 = 0b0000000100010000; // timer 5 IP level 1, timer 4 IP level 1 // Clear Interrupt Flags IFS0 = 0b0000000000000000; // T3IF = 0, T2IF = 0 IFS1 = 0b0000000000000000; // T5IF = 0, T4IF = 0 // Enable Interrupts IEC0 = 0b0000000011001000; // T3IE = 1, T2IE = 1, T1IE = 1 IEC1 = 0b0000000001100000; // T5IE = 1, T4IE = 1 } while(1) {} // Timer 1 interrupt service routine toggles RB0 void _ISR _T1Interrupt(void) { _LATB0 = ~_LATB0; _T1IF = 0; } // Timer 2 interrupt service routine toggles RB1 void _ISR _T2Interrupt(void){ _LATB1 = ~_LATB1; _T2IF = 0; } // Timer 3 interrupt service routine toggles RB2 void _ISR _T3Interrupt(void){ _LATB2 = ~_LATB2; _T3IF = 0; } // Timer 4 interrupt service routine toggles RB3 void _ISR _T4Interrupt(void){ _LATB3 = ~_LATB3; _T4IF = 0; } // Timer 5 interrupt service routine toggles RB4 void _ISR _T5Interrupt(void){ _LATB4 = ~_LATB4; _T5IF = 0; } // Timer 1 interrupt service routine toggles RB0 //void attribute ((interrupt)) _T1Interrupt(void){ // _LATB0 = ~_LATB0; // _T1IF = 0; //} ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 7
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 8
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 9
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 10
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 11
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 12
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 13
ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 14
errupt is generated. ENG721-S2 Mixed Signal Processing : Hassan Parchizadeh Page 15