PDA

View Full Version : USART with INTERRUPTS



crhomberg
- 17th April 2007, 14:30
Hi All,

I have never used the USART of the PIC 16F877A and I used to use Serin2 in a loop to check for packets of 8 bytes which came to control a PTZ video camera. As the pic had other things to do you can imagine it missed messages from time to time.
I tried using the sample program USART.bas but when I connected the RX to the serial program of Microcode Studio and sent single bytes out and then wrote a serin2 command to send rcreg back, the value was always different and many times the same value arrived back when I entered a different one.

I was sending my data to the RX via com1 and receiving using serout2 via com2.

This was my code:

@ device hs_OSC, wdt_on, pwrt_on, protect_off
'OPEN USART
define osc 20
Include "modedefs.bas"

RCSTA = %10010000 ' Enable USART receive
SPBRG = 31 ' Set baud rate to 4800 (20MHz clock)
INTCON = %11000000
PIE1.5=1

trisc.6=0
TRISC.7=1
TRISA.0=0

test var porta.0
counter var word
BAUD CON 16390

loop:

on interrupt goto myroutine

if counter= 5000 THEN 'just to keep the pic busy to make sure the
toggle portd.0 ' interrupts are working.
COUNTER=0
else
counter=counter+1
endif

INTCON = %11000000
goto loop



goto loop

'********************************************
disable
myroutine:

if PIR1.5=1 then

serout2 test,BAUD,[dec rcreg,10,13] 'send the value to com2
serout2 test,BAUD,["PIR1.5=",BIN PIR1.5,10,13]
IF RCSTA.1=1 THEN
serout2 test,BAUD,["BUFFER OVERRUN",10,13] 'Just to see if overflow occured
ENDIF
endif

resume
enable
'********************************************

end

Best Regards

Christopher in Santiago

skimask
- 17th April 2007, 14:55
Try this instead....

@ device hs_OSC, wdt_on, pwrt_on, protect_off
define osc 20
Include "modedefs.bas"
RCSTA = %10010000:SPBRG = 31:INTCON = %11000000:PIE1.5=1:trisc.6=0
TRISC.7=1:TRISA.0=0:test var porta.0:counter var word:BAUD CON 16390

---------------------------------jump over your interrupt routines
goto main
-----------------------------------------------------------------

on interrupt goto myroutine

disable
myroutine:
if PIR1.5=1 then
serout2 test,BAUD,[dec rcreg,10,13] 'send the value to com2
serout2 test,BAUD,["PIR1.5=",BIN PIR1.5,10,13]
IF RCSTA.1=1 THEN
serout2 test,BAUD,["BUFFER OVERRUN",10,13] 'Just to see if overflow occured
ENDIF

-------------------read the serial port input register and reset the input interrupt flag
x=rcreg : PIR1.5 = 0

endif
resume
enable

main:
if counter= 5000 THEN 'just to keep the pic busy to make sure the
toggle portd.0:counter=0 ' interrupts are working.
else
counter=counter+1
endif
goto main

end

You're program organization was messed up a bit. Also, you have to read RCREG and reset the flag manually when using the serial port, just like the datasheet says.

Which version of PBP are you using?

crhomberg
- 17th April 2007, 17:36
Thanks for correcting my code but at 9600 baud (BRGH=31 for 20MHz)
When I send decimal 1 I receive 103
2 = 51
3 = 102
4 = 25
5 = 101
6 = 50 etc

I am using the code just as your wrote it?
What have I set up wrong, I checked the baud rates on the terminal program.

Regards

Chris

crhomberg
- 17th April 2007, 17:40
How would I achieve the same end result by using HSERIN,
I tried but it seemed to just freeze even when I sent byte by byte to ensure
I did'nt get a buffer overflow?

Regards

Chris

skimask
- 17th April 2007, 17:46
Thanks for correcting my code but at 9600 baud (BRGH=31 for 20MHz)

If you're using SEROUT2 to send characters back to the PC, you need to go back and read the PBP manual on how to use it. And, you have to set up a few more registers to get the UART receive port working correctly. Read the UART section in the datasheet for a bit and come back with your results...

And which version of PBP are you using?

skimask
- 17th April 2007, 18:00
So, all you're really trying to do right now is get a 'loop back' to work?

@ device hs_OSC, wdt_on, pwrt_on, protect_off
define osc 20
Include "modedefs.bas"
trisc.6=0:trisc.7=1:trisd.0=0:serialdata var byte : counter var word : counter2 var word
main:
counter=counter+1 : portd.0 = counter.1 'toggle led on portd.0 each time thru the loop
serialdata=0:serin portc.7, n9600, serialdata:if serialdata=0 then goto main 'get serial data, if none, restart loop
counter2 = counter2 + 1:serout portc.6, n9600, [ dec counter2 , ":" , serialdata , 13 , 10 ]:goto main
end

crhomberg
- 17th April 2007, 18:02
Thanks SkiMask,

I have used and tested SEROUT2 many times without a hitch, it is sending test values just as I send them.
As far as reading the USART manual, I have been reading it for the last 2 days.
I am getting square eyes but seem to have missed something.

You saw how I used SEROUT2 in my code (is it wrong?)

Maybe I should just use HERIN instead

Regards

Chris

crhomberg
- 17th April 2007, 18:03
Yes, just a loopback

skimask
- 17th April 2007, 18:09
Yes, just a loopback

See post 6. Are you using a max232 or the resistors like in the manual?

AND WHICH VERSION OF PBP ARE YOU USING?

crhomberg
- 17th April 2007, 18:54
I tried the tester as below (cut & paste except the range) but just a a list of ascii garbage. I am monitoring using the microcode studeo serial communicator and have tried receiving at various speeds.
The output is via a 1K resistor.

Regards

Chris

´*********************************

@ device hs_OSC, wdt_on, pwrt_on, protect_off
define osc 20

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 64 ' 2400 Baud @ 4MHz, 0.17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

Pause 500

Start:
FOR SPBRG=15 to 100
HSEROUT ["SPBRG=",#SPBRG]
PAUSE 50
NEXT
stop 'put this in to do it only once
GOTO Start

crhomberg
- 17th April 2007, 18:55
By the way,

I am using PBP version 2.46

Regards

Chris

Charles Linquis
- 17th April 2007, 19:34
If you are using HSERIN/HSEROUT, you can't simply use a resistor. The data is inverted compared to what it needs to be in order to communicate with any normal serial device (such as a PC).

A MAX232 (or equivalent), not only changes the voltage swings and levels, it inverts the signals as well.

crhomberg
- 17th April 2007, 21:01
Thanks to both of you,

I have finally had success but I have to admit that the problem was me all the time and I only added the MAX232 at the end but still had problems.
All that was needed was a decoupling cap on the Max232.

I have to eat humble pie today!

Thanks all,

You have kept my sanity

Regards

Chris