TX_INT works a little different than the other interrupts.
It's interrupt flag is set when the TXREG register is empty, which means it's almost always =1. So you always end up back in the interrupt handler if TX_INT is ENABLED. Nothing else will be able to do anything because it's continuously entering and exiting the interrupts.
When you place a byte in TXREG (via HSEROUT), it gets transferred to the TSR register, and the flag gets set again even though the USART is currently transmitting the byte. The TRMT bit will =1 While the USART is transmitting.
If USART is still transmitting the byte in TSR when you place another byte in TXREG, the TXIF flag will finally be cleared and you can successfully leave the interrupt handler. But as soon as the byte in TSR is gone, the flag gets set again, and away you go back to the handler.
Essentially what this all does is to allow you to have data ready and waiting to be sent, and let the USART tell you when it's OK to send the next byte.
If you don't have any data waiting, it's a constant conversation between the program and the USART.
USART: Hey, it's ok to send.
PROGRAM: I have nothing to send.
USART: Hey, it's ok to send.
PROGRAM: I have nothing to send.
USART: Hey, it's ok to send.
PROGRAM: I have nothing to send.
.....
What needs to be done here is to control when the TX_INT is ENABLED. If there is data waiting to be sent then ENABLE TX_INT. When it's ok to send, the USART will fire the TX interrupt and you can put 1 byte into TXREG. If there is still more data to be sent, exit the handler and it will interrupt again when it's ready to send the next byte.
If there's no more data to send, DISABLE TX_INT to keep it from continuously interrupting.
Also, when you're only working with 1 byte at a time, there's no need for Timeouts in the HSERIN statement. When you get an RX interrupt, you are guaranteed to have at least 1 byte in the USART buffer.
For your previous LoopBack example it could look like this,...
Code:
ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _Timer1, PBP, yes
INT_Handler RX_INT, _GetChar, PBP, yes
INT_Handler TX_INT, _SendChar, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; TMR1
@ INT_ENABLE RX_INT ;- enable the RX interrupt
.
.
.
Timer1:
TMR1L = load.lowbyte
TMR1H = load.highbyte
FLAG = 1
@ INT_RETURN
GetChar:
HSERIN [cod]
@ INT_ENABLE TX_INT ;- enable the TX interrupt
@ INT_RETURN
SendChar:
hserout [cod]
@ INT_DISABLE TX_INT ;- disable the TX interrupt
@ INT_RETURN
Bookmarks