PDA

View Full Version : Instant Interrupt and USART



sirvo
- 20th July 2008, 20:09
Hello.. again...

Well, I'm trying to use Timer1 and USART interrupts using Darrel Ins. Interrupts.

If I disable RX and TX interrupts, Timer1 works really fine. However, if all of them are enable, rx-tx works (microcode serial comm.) but not timer1..

Any ideas?

Thank again!



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 interrupt
@ INT_ENABLE TX_INT ;- enable the interrupt

.
.
.

Timer1:
TMR1L = load.lowbyte
TMR1H = load.highbyte
FLAG = 1
@ INT_RETURN

GetChar:
HSERIN 1, go, [cod]
received = 1
goto theend
go: received = 0
theend:
@ INT_RETURN

SendChar:
if received= 1 then hserout [cod]
received= 0
@ INT_RETURN

Darrel Taylor
- 20th July 2008, 20:57
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,...
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

sirvo
- 20th July 2008, 21:13
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.
.....


Darrel, I did think that it was interrupting all the time but i was not sure. Thanks for the help! I got it working now!

By the way, i'm still laughing about the conversation...... :)

Thanks!

sirvo
- 23rd July 2008, 01:54
Hello again..

As I posted, it worked well when using a single byte (cod). But, I can´t get it working when using array (cod[4]).



COD VAR BYTE[4]

HSERIN [STR COD\4]
.
or
.
HSERIN [STR COD\4\"~"]
.
.
HSEROUT [STR COD\4]
.
.


When using serial comm. as an echo, I get 'strange' number, but never a complete byte.

I've looked for this hserin format all over the forum but none of the solutions worked yet...

Any ideas?

Thanks again!

skimask
- 23rd July 2008, 02:38
As I posted, it worked well when using a single byte (cod). But, I can´t get it working when using array (cod[4]).
Thanks again!
What happens if you use 4 HSERIN's back-to-back?

sirvo
- 23rd July 2008, 03:08
What happens if you use 4 HSERIN's back-to-back?

Well, it works! :)

Danke schön!

Thanks skimask!