usart PIC16F877

Started by fish_camera March 3, 2007
Attempting to troubleshoot problem with usart, asynchronous mode, for
a school project. Two 16F877. Using the ICD-2 in circuit debugger.
We believe our transmit chip is working but we can't get receive to
function correctly. We know interupts will not work while Single
stepping in debug mode, but in animate mode interupts should
function, correct?

How close do the clocks have to be? The clocks are within 95% of
each other, with the send and receive code using the same number for
baud rate.

Mike Predko's book, "Programming and Customizing pic
microcontrollers" says 2400bps is the maximum for a 4MHZ clock(pg
232), which is our clock speed. Why does the data sheet list much
higher rates?

We were watching the PIR1 register , RCIF, on the receiving chip,
expecting to see it reset, but it stays set. This is our receive code:

Receive
movfw RCREG
xorwf TXAddress
btfss STATUS, Z ;does the first byte agree???
return
bcf PIR1, RCIF
btfss PIR1, RCIF ;wait until next byte is received
goto $-1
movfw RCREG
movwf RCData ;save the byte for further use
;bcf PORTD, 0 ;tell tale OFF, ~8msec
movfw RCData
movwf PORTD

;call LoopTimer
;movlw 0x00
;movwf PORTD ;Blank the display
return

Any help is appreciated.

Thanks, John
I am currently on with a project using USART on the PIC16F877. I recently made a transmitter and receiver but not talking to each other, if that makes sense!
Anyway, the "top of the range" PIC16F877" can run at 20Mhz with speeds 250kbits+, depending on the SPBRG.
If the two clocks are out by to much then of course you will get some error in receiving, probably a framing error? My clock had +/- 30ppm, so if the 4Mhz was out by that you would get 99.99925% So your clocks are not very good tollerences. Your loosing about 200,000 clocks a min, 63,333 a second which i think would cause problems with long data streams? Does the crysal have the correct capacitors?

Here is my code to start receiving for two bytes. I don't use an interrupt for mine though cause of the application

bsf RCSTA,CREN ;Receive Enable

btfss PIR1,RCIF
goto $-1
movfw RCREG
movwf DMX_1

btfss PIR1,RCIF
goto $-1
movfw RCREG
movwf DMX_2

So at the end i have my two bytes in DMX_1 and DMX_2. I then go off to do other stuff, then check for the start again. I need to look for a low of 88us and a hight of 8us then i enable receive, thats just cause of my protocol. Anyway, are you using RCSTA,CREN to start receive or is it always receiving and then giving you an interrupt when it gets a byte? What is your config bytes? RCSTA? TXSTA? I take it SPBRG are the same? Do you get any error codes from RCSTA bit 2 or 1? Framing Error or Overrun error?

I should have a new pic board made soon so i could try talking together with them :-)

Hope my waffle helps in some way!
Paul

----- Original Message -----
From: fish_camera
To: p...
Sent: Thursday, February 08, 2007 4:01 AM
Subject: [piclist] usart PIC16F877
Attempting to troubleshoot problem with usart, asynchronous mode, for
a school project. Two 16F877. Using the ICD-2 in circuit debugger.
We believe our transmit chip is working but we can't get receive to
function correctly. We know interupts will not work while Single
stepping in debug mode, but in animate mode interupts should
function, correct?

How close do the clocks have to be? The clocks are within 95% of
each other, with the send and receive code using the same number for
baud rate.

Mike Predko's book, "Programming and Customizing pic
microcontrollers" says 2400bps is the maximum for a 4MHZ clock(pg
232), which is our clock speed. Why does the data sheet list much
higher rates?

We were watching the PIR1 register , RCIF, on the receiving chip,
expecting to see it reset, but it stays set. This is our receive code:

Receive
movfw RCREG
xorwf TXAddress
btfss STATUS, Z ;does the first byte agree???
return
bcf PIR1, RCIF
btfss PIR1, RCIF ;wait until next byte is received
goto $-1
movfw RCREG
movwf RCData ;save the byte for further use
;bcf PORTD, 0 ;tell tale OFF, ~8msec
movfw RCData
movwf PORTD

;call LoopTimer
;movlw 0x00
;movwf PORTD ;Blank the display
return

Any help is appreciated.

Thanks, John
I suppose you are trying to connect two PICs using UART. right? In
that case, the clock speed error should not come in. I suggest u
should tried to send a series of bytes and check on LCD or LED
without debugger mode.
--- In p..., "fish_camera" wrote:
>
> Attempting to troubleshoot problem with usart, asynchronous mode,
for
> a school project. Two 16F877. Using the ICD-2 in circuit debugger.
> We believe our transmit chip is working but we can't get receive to
> function correctly. We know interupts will not work while Single
> stepping in debug mode, but in animate mode interupts should
> function, correct?
>
> How close do the clocks have to be? The clocks are within 95% of
> each other, with the send and receive code using the same number
for
> baud rate.
>
> Mike Predko's book, "Programming and Customizing pic
> microcontrollers" says 2400bps is the maximum for a 4MHZ clock(pg
> 232), which is our clock speed. Why does the data sheet list much
> higher rates?
>
> We were watching the PIR1 register , RCIF, on the receiving chip,
> expecting to see it reset, but it stays set. This is our receive
code:
>
> Receive
> movfw RCREG
> xorwf TXAddress
> btfss STATUS, Z ;does the first byte agree???
> return
> bcf PIR1, RCIF
> btfss PIR1, RCIF ;wait until next byte is received
> goto $-1
> movfw RCREG
> movwf RCData ;save the byte for further use
> ;bcf PORTD, 0 ;tell tale OFF, ~8msec
> movfw RCData
> movwf PORTD
>
> ;call LoopTimer
> ;movlw 0x00
> ;movwf PORTD ;Blank the display
> return
>
> Any help is appreciated.
>
> Thanks, John
>
Animate, I believe, just does a bunch of single steps, so interrupts will
not be called. To see what your ISR is doing, set a breakpoint in the ISR.
Note that when you hit the breakpoint, the processor stops, so shifting of
data into or out of the uart will be messed up. If you have already
shifted a byte in, it will be ok, but if there is another one in progress,
it will be messed up. You can get around this by moving your breakpoint
around and letting the code start from reset.

Looking at your code, it generally looks ok. I don't think this instruction:

bcf PIR1, RCIF

will do anything since PIR1,RCIF is a read only bit.

Is TXAddress a variable in RAM or a constant in ROM? If it's in RAM, you
probably want to make this TXAddress,w so the result of the XOR ends up in
w instead of messing up TXAddress (destination bits default to "file"). If
the address is rom, you'd need do do something like this:

movf RCREG,w
xorlw TXAddress
I'd avoid the use of goto $-1. I'd put a label at your test and goto it
instead. If you move to an 18 series chip, the $-1 won't work (it becomes
$-4 for a goto or $-2 for a bra).

If this is an interrupt routine, I would not do a loop inside the routine.
Instead, I'd do a state machine that keeps track of where we are in the
routine. After getting the address byte, exit the ISR remembering that you
got a valid address. Enter the routine again to pick up your data.

Good luck!

Harold
> I suppose you are trying to connect two PICs using UART. right? In that
case, the clock speed error should not come in. I suggest u should tried
to send a series of bytes and check on LCD or LED
> without debugger mode.
> --- In p..., "fish_camera" wrote:
>>
>> Attempting to troubleshoot problem with usart, asynchronous mode,
> for
>> a school project. Two 16F877. Using the ICD-2 in circuit debugger. We
believe our transmit chip is working but we can't get receive to
function correctly. We know interupts will not work while Single
stepping in debug mode, but in animate mode interupts should
>> function, correct?
>>
>> How close do the clocks have to be? The clocks are within 95% of each
other, with the send and receive code using the same number
> for
>> baud rate.
>>
>> Mike Predko's book, "Programming and Customizing pic
>> microcontrollers" says 2400bps is the maximum for a 4MHZ clock(pg 232),
which is our clock speed. Why does the data sheet list much higher
rates?
>>
>> We were watching the PIR1 register , RCIF, on the receiving chip,
expecting to see it reset, but it stays set. This is our receive
> code:
>>
>> Receive
>> movfw RCREG
>> xorwf TXAddress
>> btfss STATUS, Z ;does the first byte agree???
>> return
>> bcf PIR1, RCIF
>> btfss PIR1, RCIF ;wait until next byte is received
>> goto $-1
>> movfw RCREG
>> movwf RCData ;save the byte for further use
>> ;bcf PORTD, 0 ;tell tale OFF, ~8msec
>> movfw RCData
>> movwf PORTD
>>
>> ;call LoopTimer
>> ;movlw 0x00
>> ;movwf PORTD ;Blank the display
>> return
>>
>> Any help is appreciated.
>>
>> Thanks, John
>

--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!
You want to keep the error much, much, smaller than 5%. Something
less than 1% is what you need to hit. Actually, much less than 1% is
better.

The UART is clocked at 16 times the bit rate so for 2400 baud, you
need a clock rate of 38400 Hz. The equations for clock generation are
given in sections 10.1 of the datasheet.

>From Table 10.3 in the datasheet, you can see that for a 4 MHz
crystal, you are limited to 2400 baud when you have to keep the %
error far less than 1% (BRGH=0).

1 MHz / (2400 * 16) = 26 so set the SPBRG to 25.

Now, if you set BRGH high, you can use Table 10-4 and operate up to
19200 baud with a 4 MHz crystal.

Some thoughts about crystal selection here:
http://www.bdmicro.com/crystals/

Each character is timed individually using the baudrate clock so
accumulated error is not a problem.

Richard