This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Multiple ISRs (interrupt service routines)

I'm using the Keil MCB900 eval board with a P89LPC938 at 7.3728MHz and the LPC900 development tools (demo version). I'm using most of Mark Odell's UART and Timer code.

I have setup Timer 1 as the baud rate generator and Timer 0 as a 10ms system timer tick. The timer tick toggles three LEDs at 10ms, 100ms, and 1s. Both the UART and Timer 0 have their own ISR (interrupt service routines) with the appropriate number and separate register banks. Each works fine on its own. But if I initialize both the timer tick AND the UART/Timer 1, it appears the timer tick runs wide open, or much faster than it should, as evidenced by the LEDs.

I have tried setting up different IP (interrupt priority) levels for each interrupt, but that doesn't seem to help. For now, they're both at level 0. Is there anything special (best practices, guidelines) you have to do to make multiple ISRs work?

Here is some of the code. I can post more.

volatile bit data Tick10ms;             // 10ms
volatile bit data Tick100ms;    // 100ms
volatile bit data Tick1s;               // 1s

static void Timer0_ISR(void) interrupt 1 using 2
{
        static U8 num10msTicks;

        TR0 = 0;                // stop timer
        TL0 = TIMER0_10MS_LO;   // reload
        TH0 = TIMER0_10MS_HI;
        TR0 = 1;                        // start timer

        Tick10ms = !Tick10ms;   // 10ms
        ++num10msTicks;

        if (!(num10msTicks % 10)) {     // 100ms
            Tick100ms = !Tick100ms;     // toggle
        }

        if (num10msTicks == 100) {      // 1s time region
            num10msTicks = 0;
            Tick1s = !Tick1s;   // toggle
        }
}

static void uartIsr(void) interrupt 4 using 1
{
    static U8 data inChar;

    if (RI) {
        RI = 0;
        inChar   = SBUF;
        if (s_rxRingEmpty || s_rxWrIdx != s_rxRdIdx) {
            s_rxRing[s_rxWrIdx] = inChar;
            ++s_rxWrIdx;

#if RX_RING_SIZE != 256
            s_rxWrIdx %= RX_RING_SIZE;
#endif
            s_rxRingEmpty = 0;
        }
    }

    if (TI) {
        TI = 0;
        if (s_txRdIdx != s_txWrIdx) {
            SBUF = s_txRing[s_txRdIdx];
            ++s_txRdIdx;

#if TX_RING_SIZE != 256
            s_txRdIdx %= TX_RING_SIZE;
#endif
        }
        else {
            // declare empty after last SCON.TI event
            s_txRingEmpty = 1;
        }
    }
}

void main(void)
{
        P2M1 = 0;               // set output mode
        P1M1 = 0;

        TMR_Init();             // A
        initUart(BAUD_RATE_57600);      // B

        EA = 1;         // enable ints

        printf("Baud rate: 57600\n");  // B

        P2 = 0x00;      // turn off LEDs

        while (1) {             // endless loop
                LED0 = Tick10ms;        // P2^0
                LED1 = Tick100ms;       // P2^1
                LED2 = Tick1s;  // P2^2
        }
}

0