Thursday 28 February 2019

Interrupt Structure of LPC2148:

what is interrupt:

An interrupt is a signal sent to the CPU which indicates that a system event has a occurred which needs immediate attention.

ISR: This function or ‘small piece of code’ is technically called an ‘Interrupt Service Routine‘ or ‘ISR‘. So when an IRQ arrives to the CPU , it stops executing the code current code and start executing the ISR. After the ISR execution has finished the CPU gets back to where it had stopped. 
Interrupts in LPC214x are handled by Vectored Interrupt Controller (VIC) (which is specific to ARM based microcontrollers and CPUs) and are classified into 3 types based on the priority levels.

    1. Fast Interrupt Request i.e FIQ : which has highest priority
    2. Vectored Interrupt Request i.e Vectored IRQ : which has ‘middle’ or priority between FIQ and Non-Vectored IRQ.
    3. Non-Vectored IRQ : which has the lowest priority.

    Interrupt Structure:

    • ARM7 Processor hardware interrupt inputs: 2, (FIQ. IRQ).
    • LPC2148 external interrupt inputs: 4 (available on 9 pins).
    • Processor and on-chip user peripherals generate interrupts.
    • LPC2148 uses ARM PrimeCell (PL190) Vectored Interrupt Controller for managing interrupts.
    • PL190 is interfaced to ARM core through the fast AHB bus.
    When interrupt occurs:
    1. VIC identifies the source of interrupts.
    2. Passes requests on interrupt request pins as per the configuration.
    3. If more than one interrupt occurs at a time, VIC resolves priority.

    Vectored Interrupt Controller (VIC)

    • 32 interrupt request inputs, LPC2148 uses 21 of 32 interrupts.
    • Categorizes into Fast Interrupt Request, Vectored IRQ, Non Vectored IRQ interrupts.
    • Any of the 21 interrupts can be assigned to FIQ / VIRQ / NVIRQ.
    • FIQ: Generally, only one interrupt is assigned, VIC provides ISR address. If more than one is assigned to FIQ, VIC combines all, generates VICFIQ, provides only one ISR address for all FIQ (Non-Vectored FIQ).
    • VIRQ & NVIRQ.
    • VIC has 16 VIRQ slots, Slot-0 to Slot-15. Any IRQ configured interrupts can be assigned to any slot. Priorities are in the order of slot number. Slot-0 has highest priority than slot-15.
    • Interrupts configured as IRQ, not assigned any VIRQ slot, is assigned as NVIRQ.
    • VIRQ & NVIRQ interrupts are combined and VICIRQ is generated.
    • Programs can handle 1 FIQ, 16 VIRQ, 1 NVIRQ (total 18) interrupts.
    The difference between Vectored IRQ(VIRQ) and Non-Vectored IRQ(NVIRQ) is that VIRQ has dedicated IRQ service routine for each interrupt source which while NVIRQ has the same IRQ service routine for all Non-Vectored Interrupts. 
    VIC Structure


    VIC Registers:

    1)VICIntSelect
    This register is used to select an interrupt as IRQ or as FIQ. Writing a 0 at a given bit location(as given in below) will make the corresponding interrupt as IRQ and writing a 1 will make it FIQ. For e.g if you make Bit 4 as 0 then the corresponding interrupt source i.e TIMER0 will be IRQ else if you make Bit 4 as 1 it will be FIQ instead. Note than by default all interrupts are selected as IRQ. Note that here IRQ applies for both Vectored and Non-Vectored IRQs.

    Interrupt select
    It is also 32 bit register.
    If any bit between  0:31 is 1 then it will select FIQ.
    If any bit between  0:31 is 0 then it will select IRQ.
    2)

    2) VICIntEnable (R/W) :


    VICIntEnable = (1<<18);    //Enable AD0 Interrupt



       

       

       

       


      #include <lpc214x.h> 

      void  delay_ms(unsigned char time)    
      {  
       unsigned int  i, j;
       for (j=0; j<time; j++)
        for(i=0; i<8002; i++);
      }

      void LCD_command(unsigned char command)
      {
      IOCLR0 = 0xFF<<16; // Clear LCD Data lines
      IOCLR1=1<<16; // RS=0 for command
      IOCLR1=1<<17; // RW=0 for write
      IOSET0=command<<16;
      IOSET1=(1<<18); // en=1 
      delay_ms(10) ; // delay
      IOCLR1=(1<<18); // en=0
      }

      LCD_data(unsigned char data)
      {
      IOCLR0 = 0xFF<<16; // Clear LCD Data lines
      IOSET1=1<<16; // RS=1 for data
      IOCLR1=1<<17; // RW=0 for write
      IOSET0= data<<16; // put command on data line
      IOSET1=(1<<18); //en=1 
      delay_ms(10) ;   //delay
      IOCLR1=(1<<18); //en=0
       }

      LCD_init()
      {
      LCD_command(0x38); //8bit mode and 5x8 dotes 
      delay_ms(10) ; // delay
      LCD_command(0x80);
      delay_ms(10) ; // delay
      LCD_command(0x01); //clear lcd(clear command)
      delay_ms(10) ; // delay
      LCD_command(0x06);  
      delay_ms(10) ; // delay
      LCD_command(0x0c);
      }

      void LCD_write_string(unsigned char *string)
      {

      int i=0;
      while(string[i] != '\0')
        {    
        LCD_data(string[i]);
        delay_ms(10);
        i++; //sending data on LCD byte by byte
      }
      }

      void  __irq ADC0_ISR(void)

      unsigned int ADC_Result=0;
      unsigned char i, val[4];
      ADC_Result = AD0DR2; //Store converted data
      ADC_Result = (ADC_Result>>6) & 0x3FF;
      LCD_command (0xCA);//Goto 10th place 
       
           for( i=0;i<4;i++)
               {
         val[i]=ADC_Result%0x0A;
               val[i]=val[i]+0x30;
         ADC_Result=ADC_Result/0x0A;
      }
      LCD_data(val[3]);
      LCD_data(val[2]);
               LCD_data(val[1]);
      LCD_data(val[0]);
      delay_ms(250);
         

      VICVectAddr = 0x00;    //Acknowledge Interrupt
      }

      int main(void)
      {
      PINSEL1 = 0x04000000; 
      PINSEL2 = 0X00; //Configure PORT1 as GPIO
      IODIR1= 0x07<<16;//
      IODIR0=0xFF<<16; //Configure P0.23 - P0.16 as outpu
      LCD_init(); //Initialize LCD 16x2
      LCD_write_string("AP");
      LCD_command(0xc0);//second line
      LCD_write_string("ADC O/P=");

      VICIntSelect = 0x00000000;// Setting all interrupts as IRQ v
      VICVectCntl0 = 0x20 | 18; /*Assigning Highest Priority Slot to ADC0 and enabling this slot*/
      VICVectAddr0 = (unsigned long)ADC0_ISR; /* Storing vector address of ADC0*/
      VICIntEnable = (1<<18);    //Enable AD0 Interrupt

      /* Configure ADC0 for following
      ADC Channel = AD0.2
      ADC Clock = 3 MHz
      Clock Selection = 11 Clock Cycles/10bit
      Start Condition = No start
      Power Down = 1, EDGE = 0, BURST = 1 */
       
      AD0CR = 0x00210404;

      while (1);

      }



         

        2 comments:

        1. Bitcoin to neteller offers some simple ways to buy Bitcoin, including Neteller. Use Neteller offers a fast, easy and secure way to buy bitcoins instantly in EUR.

          ReplyDelete