PDA

View Full Version : Hserin, 1st character always lost!



Ioannis
- 2nd June 2007, 12:20
I have used many time command Hserin, but just now I noticed that everytime the first incoming character is lost.

So a simple test code was compiled to prove this:

INCLUDE "C:\PBP\MODEDEFS.BAS"
DEFINE OSC 4

@ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _CP_OFF

intcon=%11000000 'Enable USART interrupts or else 0
t1con=0'%00110001 'Enable Timer1,prescaler/8,ON
pie1=%00100000 'Enable Peripheral Timer1,RCIE

trisa=1:trisb=1:trisc=128:trisd=0:trise=0
PORTA=0:PORTB=0:PORTC=0:PORTD=0:PORTE=0

OPTION_REG=%11110001

DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h '9600 baud rate, BRGH=1
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 25
DEFINE HSER_CLROERR 1

adcon0=%10000001
adcon1=%10001110

i var byte

loop:
hserin [i]:hserout [i]
goto loop

end

The result is that indeed the first incoming is always lost.

Did anyone noticed that and how is it overcomed?

Ioannis

Ioannis
- 2nd June 2007, 12:36
This happens only after a RESET of the PIC and only for the first character.

Maybe Hserin is not Enabled before a character is received?

Ioannis

skimask
- 2nd June 2007, 18:36
This happens only after a RESET of the PIC and only for the first character.

Maybe Hserin is not Enabled before a character is received?

Ioannis

Try doing a 'dummy read' on RCREG before starting your program.

Ioannis
- 2nd June 2007, 19:44
Thanks skimask. I tried reading twice the rcreg, just to be sure. Nothing good.

But, playing with the setting of the PIC I found that if the intcon GIE and PEIE are set, then the first byte is lost.

When these were disabled, 1st byte showed up at once! I cannot say yet which is the offending bit, but I'll come back with this.

Ioannis

mister_e
- 2nd June 2007, 20:58
what happen if you place a ON INTERUPT GOTO myint and define a simple ISR as bellow?



disable
myint:

resume
enable

Even if it doesn't care of anything, you should see some difference. At very least, your program know where to go when an interrupt happen.

Bruce
- 4th June 2007, 22:17
The problem is that you have interrupts enabled, but you don't have an interrupt handler routine.

PBP issues a CALL to a routine called hserinloop. The return address is pushed onto the stack. In this loop, it will continuously check the RCIF USART interrupt flag bit, and loop until it's set.

While in this loop, if your interrupt happens, the address within this loop (wherever it happens to be) is pushed onto the return stack.

Note that now you have a return address on the stack that is still inside this loop. Not to where PBP issued the CALL hserinloop.

Once RCIF is set, the received value is loaded into the W reg, and PBP exits hserinloop with GOTO DONE. Inside DONE you land on a RETURN, and you're right back in the hserinloop until the 2nd character arrives.

It works OK for the 2nd character because global interrupts are still disabled.

The original return address is now OK, and on RETURN it shows the 2nd character.

If you disable interrupts this problem goes away since the RETURN will always be to the proper location after PBP issues the CALL to hserinloop.

It has the same problem after a reset because your code is enabling interrupts again.

Ioannis
- 5th June 2007, 12:49
Wow Bruce, that was detailed analysis! That was exactly the problem.

Thanks all that contributed.

I have attached the first attempt to write some VB6 user interface that configures the LCD of the connected device. For anyone interested to use it, be my guest. I know it is not some super-duper code, but, hey I just started VB! Any suggestions most welcome.

Also a great thanks for Darrel's LCDbar_INC.bas that helped me a lot in this project.

Ioannis