Saturday, 7 January 2012

Interrupt Example Programs for Timer 0,1 and UART 0,1 using LPC2148

#include "LPC214x.H"
#include "stdio.h"
//CCLK=12xM=12x5=60MHZ
//PCLK=CCLK (VPBDIV=0x00)

#define RDR        0x01
#define THRE    0x20
#define RDA        0x04

void Timer0ISR(void)__irq;
void Timer1ISR(void)__irq;
void UART0ISR(void)__irq;
void UART1ISR(void)__irq;
void Exint0ISR(void)__irq;

unsigned char rxdat,rxdat1;
int txf,timer0_flag,timer1_flag,eint0_flag;
unsigned char a = 0;
unsigned short int fdiv;
         
void Init_PLL()
{
    //System Clock
    //PLLCFG = 0x00100100;              //p=2 (PSEL=01) and m=5-1 (MSEL=00100)
//    PLL0CFG = 0x00;     //0x0010 0010   //48Mhz m = 4-1 = 3 i.e 00010
    PLL0CFG = 0x23;                   //60Mhz m=5-1=4 i.e 00011
    PLL0CON = 0x01;
    PLL0FEED = 0xaa;
    PLL0FEED = 0x55;
    while((PLL0STAT & 0x400) == 0);
    PLL0CON = 0x03;
    PLL0FEED = 0xaa;
    PLL0FEED = 0x55;

    //USB clock
    //PLL1CFG = 0x00100011;            //p=2 (PSEL=01) and m=4-1 (MSEL=00011)
    PLL1CFG = 0x23;
    PLL1CON = 0x01;    
    PLL1FEED = 0xaa;
    PLL1FEED = 0x55;   
    while((PLL1STAT & 0x400) == 0);   
    PLL1CON = 0x03;                   
    PLL1FEED = 0xaa;
    PLL1FEED = 0x55;           
}

void Init_MAM(void)
{
    MAMTIM = 0x00000001;
    MAMCR  = 0x02;
}

void Init_VPB(void)
{
    VPBDIV = 0x00;
}
   
void Init_TIMER0(void)
{
    T0IR  = 0xff;         //clr the pending flags of interrupt
    //T0CTCR = 0x00;      //timer mode
    T0PR  = 1000;         //prescalar maximum count value keep it 1000 and change T0MR0
    T0PC  = 0;       
    T0MCR = 0x0003;       //MR0I=interrupt when TC=MR and reset
    T0MR0 = 1000;         //match the final value (using )
    //T0TC  = 0;
    T0TCR = 0x02;         //reset the timer
    T0TCR = 0x01;         //enable the timer
}

void Init_TIMER1(void)
{
    T1IR  = 0xff;         //clr the pending flags of interrupt
    //T1CTCR = 0x00;      //timer mode
    T1PR  = 1000;         //prescalar maximum count value keep it 1000 and change T0MR1
    T1PC  = 0;       
    T1MCR = 0x0003;       //MR0I=interrupt when TC=MR and reset
    T1MR0 = 1000;         //match the final value (using )
    //T1TC  = 0;
    T1TCR = 0x02;         //reset the timer
    T1TCR = 0x01;         //enable the timer
}

void Init_EXTINT0(void)
{
    EXTINT    = 0x01;     //clr interrupt bit
    INTWAKE   = 0x0000;
    EXTMODE   = 0x01;     //EINT0 edge sensitive
    EXTPOLAR  = 0x01;     //EINT0 rising edge
}

void Init_UART0(void)
{
    U0LCR = 0X83;
    U0FDR = 0xa1;
    fdiv  = ((12000000 * 10)/(16 * 9600 * 11));
    U0DLM= fdiv/256;
    U0DLL = fdiv%256;
    U0LCR = 0x03;
    U0FCR = 0x01;
    U0IER = 0x00000003;    //RI and TI interrupt
}

void Init_UART1(void)
{
/*        formula for BR calculation:    =PCLK x mulval /
                            [(16 x (16 x U0DLM + U0DLL))x(MULVAL + DIVADDVAL)
        9609 = 48Mhz x 5 / [(16 x (16 x 0 + 223)) x (5 + 7)]    */
    U1LCR = 0X83;
    U1FDR = 0xa1;
    fdiv  = ((12000000 * 10)/(16 * 9600 * 11));
    U1DLM= fdiv/256;
    U1DLL = fdiv%256;
    U1LCR = 0x03;
    U1FCR = 0x01;
    U1IER = 0x00000003;    //RI and TI interrupt
}

void Init_VIC(void)
{
    VICIntSelect = 0x00000000;          //select timer0 interrupt ad IRQ i.e bit 4=0
    //VICDefVectAddr  = (unsigned long int)timer0ISR; do not use when more than one interrupts are used
    VICVectAddr0 = (unsigned long int)Timer0ISR;
    VICVectCntl0 = 0x24;                 //bit 5 is enabled the slot to produce unique interrupt address for enabled timer0 interrupt
    VICIntEnable = 0x00000010;          //enable timer0 interrupt

    //VICDefVectAddr  = (unsigned long int)timer0ISR; do not use when more than one interrupts are used
    VICVectAddr1 = (unsigned long int)Timer1ISR;
    VICVectCntl1 = 0x25;                 //bit 5 is enabled the slot to produce unique interrupt address for enabled timer0 interrupt
    VICIntEnable |= 0x00000020;          //enable timer0 interrupt

    VICVectCntl2 = 0x26;
    VICVectAddr2 = (unsigned long int)UART0ISR;
    VICIntEnable |= 0x00000040;          //enable UART0 interrupt


    VICVectAddr3 = (unsigned long int)UART1ISR;
    VICVectCntl3 = 0x27;      
    VICIntEnable |= 0x00000080;

    VICIntEnable |= 0x00004000;          //enable EINT0 interrupt
    VICIntSelect = 0x00000001;          //select EINT0 interrupt as IRQ i.e bit 14=0
    VICVectAddr4 = (unsigned long int)Exint0ISR;
    VICVectCntl4 = 0x2e;
}

void Init_PORT(void)
{
    PINSEL0 = 0x00050005;          //p0.15 and p0.7 as GPIO P0.1=RXD P0.0=TXD
    PINSEL1 = 0x00000000;          //p0.16 as EINT0
    PINSEL2 = 0x00000000;
    IO0DIR  = 0xffffffff;
    IO0CLR  = 0xffffffff;
}

void delay(void)
{
    unsigned short int i;
    for(i=0;i<50000;i++);
}

int main(void)
{
    Init_PLL();
    Init_MAM();
    Init_VPB();
    Init_PORT();   
    Init_TIMER0();
    Init_TIMER1();
    Init_EXTINT0();
    Init_UART0();
    Init_UART1();
    Init_VIC();
                   
     while(1)
      {
           if(rxdat == 'A')
        {
            IO0SET |= 0x00004000;
            while(!(U0LSR & THRE));
                U0THR = rxdat;
            rxdat = 255;
        }
           if(rxdat == 'B')
        {
             IO0CLR |= 0x00004000;
            while(!(U0LSR & THRE));
                U0THR = rxdat;
            rxdat = 255;
        }   
    }
}

void Timer0ISR(void)__irq
{
    T0IR = 0xff;
    if(timer0_flag)
        IO0SET |= 0x00001000;
    else
        IO0CLR |= 0x00001000;   
    timer0_flag = ~timer0_flag;   
    VICVectAddr = 0x00;
}

void Timer1ISR(void)__irq
{
    T1IR = 0xff;
    if(timer1_flag)
        IO0SET |= 0x000000010;
    else
        IO0CLR |= 0x000000010;   
    timer1_flag = ~timer1_flag;   
    VICVectAddr = 0x00;
}

void Exint0ISR(void)__irq
{
    EXTINT = 0x01;   
    if(eint0_flag)
        IO0SET |= 0x00000080;
    else
        IO0CLR |= 0x00000080;   
    eint0_flag = ~eint0_flag;   
    VICVectAddr = 0x00;
}

void UART0ISR(void)__irq
{
    if(U0IIR & RDA)
        rxdat = U0RBR;
    VICVectAddr = 0x00;
}
                               
void UART1ISR(void)__irq
{       
    if(U1IIR & RDA)
        rxdat = U1RBR;
    VICVectAddr = 0x00;
}

6 comments:

  1. wow fanstatic.... ARM king ah aeidenga pola...

    ReplyDelete
  2. i'm a beginner to interrupts in ARM. can u give simple arm interrupt program.

    ReplyDelete
  3. i'm a beginner to in ARM. I need to operate timer0 act in different match register like (MR0,MR1,MR2 and MR3). Is this possible? can You send me details to jvivekumarme@gmail,com its very urgent for me

    ReplyDelete
  4. hi... everything fine but when power down and power up that time interrupt is not working why?

    ReplyDelete
  5. youre the champion king ostjaaa madonnaaaaa

    ReplyDelete