Are you sure there isn't a global interrupt that requires clearing? I would say that most systems have a clearable flag somewhere.
Also, is your interrupt handler routine only triggered by the UART or is that where all interrupts will land?
On PIC micro and Atmel architectures (thus I assume ARM too, otherwise my answer holds no water) there is only one function that is ever called when an interrupt occurs. It is up to the programmer to determine which specific interrupt has occurred from code. If you have, say, ten possible interrupt sources then you need to poll those ten flags individually to find the source of the IRQ. From there you call an individual routine for that interrupt.
In your case, the constant sending of the NULL character is because the program is continuously running the handler routine, but is that because the UART interrupt is being caught or because a global interrupt is set. Your code doesn't allow you to find out at the moment. The easy solution is to add a single "if" statement as the first line of the interrupt routine that returns from the routine immediately if the UART flag is not set. Do this, then run the code.
What happens?
If nothing changes, you know you MUST be able to clear that UART interrupt flag. If it truly is read only, try disabling then re-enabling the UART interrupt. There has to be a way of clearing the flag! Run the code again.
If the continuous NULL has gone, you aren't necessarily finished! Remember that the global interrupt flag may still be set so, for debugging purposes, add some more code to the interrupt handler routine to do something (maybe send a particular character) if the routine is called but the UART flag is NOT set. That's the only way you'll know you are dealing with interrupts correctly.
EDIT:
After trawling through the ARM178x User Manual I have found the key line (page 510, "18.6.5 - UARTn Interrupt Identification Register") as follows:
The UnIIR must be read in order to clear the interrupt prior to exiting the Interrupt Service Routine.
Your code just assumes that the interrupt has been called because of one single request and, although you may have only enabled one single interrupt source, the ARM expects otherwise. In a full blown program there will be more than one reason for the UARTn IRQ to occur, which means you would have to make a read to LPC_UART2->IIR to find out what has caused the interrupt. In your case it should be sufficient just to read the address and discard the information, but it might be good practise to at least check the IIR to make sure that you're handling the correct interrupt.
In my opinion a 'correct' interrupt routine shouldn't really contain much code itself. It should just check whichever interrupt register it needs to and then call subroutines to do carry out the necessary code. For example:
void InterruptServiceRoutine(void) {
BYTE InterruptRegisterState = Requesting_Interrupt_Register;
// This 'read' instruction should clear your read-only flags
if (InterruptRegisterState && InterruptFlag_A)
Interrupt_A_Handler(void);
if (InterruptRegisterState && InterruptFlag_B)
Interrupt_B_Handler(void);
if (InterruptRegisterState && InterruptFlag_C)
Interrupt_C_Handler(void);
// ... add one for each interrupt source
}
void Interrupt_A_Handler(void) {
// Put actual your code here...
}
. . . etc.
As you can see this makes your initial ISR much clearer as there's nothing in it. You're then free to write as much code in your individual "Interrupt_X_Handler()" subroutine as you like.