PDA

View Full Version : UART-not consistant



Macgman2000
- 19th August 2008, 23:26
Hello,

I am sending 100 decimal through a manchester routine and expecting to receive 100 at the RX on the LCD display.
The RX code is attached, what is going on is very strange. The numbers bounce around and <50% of the time it will display 100.
Why is it so erractic? I would appreciate a fresh pair of eyes to see what I am doing wrong.

Nick

Darrel Taylor
- 20th August 2008, 01:36
I think it's the "Context Saving".

If the PIC has 2K or more of program space, PBP automatically includes a routine to save the W reg, STATUS, PCLATH.

You're using a 16F877A, which has more than 2k.

So this section
; Uncomment the following if the device has less than 2k of code space
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
movf PCLATH, W ; Move PCLATH to W
movwf psave ; Save PCLATH


Should be commented.

hth,

Macgman2000
- 20th August 2008, 07:01
Darrel I will give it a try tomorrow. I have a question about the UART, it uses 1 start, 1 stop and 8 bits. LSB is sent out first from the TX to the RX. Isn't the byte in the receive buffer backwards now? If that is the case, wouldn't the data '100' decimal never show up correctly since the byte is backwards in the RX buffer?

Nick

Darrel Taylor
- 20th August 2008, 07:56
> ... Isn't the byte in the receive buffer backwards now? ..

No. The USART receives data LSB first too.

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2824" />

From the TX, it shifts out from the lowest bit, and the RX side shifts it in starting from the highest bit. So the TX LSB ends up at the RX LSB after 8(10) shifts.
<!-- 2824 -->

Macgman2000
- 20th August 2008, 16:27
Darrel,

I tried commenting out the lines you suggested. I am still getting garbage on the LCD. I think what is happening is that when the UART interrupts and the 2 manchester encoded bytes are being decoded another interrupt happens and hoses any sync the UART had. In addition to corrupting the contents to be displayed.

The first time decoding 2 bytes it is fine. This code is the stepping stone to my ultimate application, 6 bytes back to back in continuous mode. Is there a better way of doing this?

Nick

Darrel Taylor
- 20th August 2008, 20:47
I tried commenting out the lines you suggested. I am still getting garbage on the LCD.
OK, I didn't look past the first major problem I saw. Leave those lines commented.
Now for step 2.


I think what is happening is that when the UART interrupts and the 2 manchester encoded bytes are being decoded another interrupt happens and hoses any sync the UART had...
Yes, that's a big problem too.

At 9600 baud, you only get just a little over 1ms between each byte, (unless there are additional delays added from the transmit side).

The clear LCD command will take over 2ms by itself.
You could change that to $FE, $80 for Home Cursor, which will reduce the time to 50µs.

And each of the multiply's in the array operations will take 50µs. 2 per loop, 8 loops, for a total of 800µs.

Using a shift left(<<1) is the same thing as *2, and only takes a couple µs.
example: IF encoded.0[i<<1]=0 Then

With those two things changed, it might be able to do it all in time.
<br>

Darrel Taylor
- 20th August 2008, 23:27
AAAACK!

$FE,$80 still takes 2ms. :o

Let's see here ...

Trying to find another solution.

skimask
- 20th August 2008, 23:44
Decrease the LCD_CommandUS value until the LCD fails (without the UART code)?
I know the 'stock' LCD_CommandUS value is something like 1500us. All but one of the LCDs I've got here on my bench will run down to a value of 100 without a hitch (that 'one' needs 250).
Might be the extra time you need.
Incidentally, the PBP 2.50 manual shows 44 as the stock value for DATAUS. I don't have much luck going much slower than that. A couple of the LCDs will go down to 25, but most like 50us.
And the code is set up for a 4 bit interface to the LCD. Switching to an 8 bit interface might shave another bit of timing off the LCD access.

Past that, I'm thinking it'll be a pain to rewrite the LCDOUT code to check the Busy Flag rather just relying on a generic pause.

Darrel Taylor
- 21st August 2008, 00:08
Decrease the LCD_CommandUS value until the LCD fails (without the UART code)?
That was my "Bad Idea" that I deleted.

It sounds good, but there are commands in the LCD Initialization sequence. So without the proper COMANNDUS the Init fails. Black box time again.

I'd love to just say remove the LCD part, but that won't help since you can't see the results anymore.

Still pondering.
<br>

skimask
- 21st August 2008, 00:14
That was my "Bad Idea" that I deleted.
It sounds good, but there are commands in the LCD Initialization sequence. So without the proper COMANNDUS the Init fails. Black box time again.
I'd love to just say remove the LCD part, but that won't help since you can't see the results anymore.
Still pondering.
<br>

I figured that...simple, easy...but...doesn't hurt to try and decrease the value until the LCD fails completely and then bump it up a bit.
I'm sure that stock value of 1500 will be able to be dropped by quite a bit. And even if a person can only get it down to 500, that's still 1ms saved.

Macgman2000
- 21st August 2008, 03:14
Hey Guys,

Ok, I got rid of the LCD commands. I restructured the code such that it packs received data into memory locations and then towards the bottom of the code it scales the data to represent a duty cycle which is sent out to 3 I/O pins. I was able to receive via UART reliably, So basically I am able to equate the pulse widths to the data values. Also, manchester decoder is implemented in the code.


Thanks for the help!!!
Nick