Trying to send RS232 with PIC sends incorrect data in TeraTerm

I am trying to work out RS232 using a PIC, so I created a simple
program to send a string message which would appear in the TeraTerm
window. Here is the code snippet:

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

void main() {

output_high(PIN_A0);
delay_ms(1000);
output_low(PIN_A0);
delay_ms(1000);

while(TRUE){
output_high(PIN_B4);
delay_ms(500);
output_low(PIN_B4);
printf("Please work\n");
delay_ms(1000);
}
}

====================

I have a Max232 converter in configuration according to the diagram on
page 7 of this datasheet:
http://www.ortodoxism.ro/datasheets/texasinstruments/max232.pdf

I am also using a device which transforms RS232 to USB and then has
drivers to emulate a COM port on the PC, since my computer has no
serial port. It is this piece:
http://www.sparkfun.com/commerce/product_info.php?products_id=198

My settings in both my device manager for COM1 (the emulated com port)
and in Tera Term are

9600 baud
8 data bits
no parity
1 stop
no flow control

When I run this program, I get the following in Tera Term:
http://bitzphoto.com/ECE445/teraterm.png
That is, a repeating sequence of incorrect characters.

I'm lost at any other settings that might need to be changed to make
the data appear correctly; any thoughts would be greatly appreciated.

Oddly, it worked correctly one time only, and it was not on the first
try; but previous and subsequent attempts have repeatedly displayed
this gibberish sequence.
 
A

Anthony Fremont

Jan 1, 1970
0
I am trying to work out RS232 using a PIC, so I created a simple
program to send a string message which would appear in the TeraTerm
window. Here is the code snippet:

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

Are you using a 20MHz clock?
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

void main() {

output_high(PIN_A0);
delay_ms(1000);
output_low(PIN_A0);
delay_ms(1000);

while(TRUE){
output_high(PIN_B4);
delay_ms(500);
output_low(PIN_B4);

Are you getting what you expect here? Is the time delay coming out
correctly?
printf("Please work\n");
delay_ms(1000);
}
}

So 12 characters from the PIC turns into 6 characters on the
display.....sounds like a baud rate issue to me. Have you tried changing
the baud in the windos program? Do you have a scope? If so, just look at
the width of the data bits to see what the PIC is sending.
====================

I have a Max232 converter in configuration according to the diagram on
page 7 of this datasheet:
http://www.ortodoxism.ro/datasheets/texasinstruments/max232.pdf

I am also using a device which transforms RS232 to USB and then has
drivers to emulate a COM port on the PC, since my computer has no
serial port. It is this piece:
http://www.sparkfun.com/commerce/product_info.php?products_id=198

My settings in both my device manager for COM1 (the emulated com port)
and in Tera Term are

9600 baud

8 data bits
no parity
1 stop
no flow control

When I run this program, I get the following in Tera Term:
http://bitzphoto.com/ECE445/teraterm.png
That is, a repeating sequence of incorrect characters.

I'm lost at any other settings that might need to be changed to make
the data appear correctly; any thoughts would be greatly appreciated.

Oddly, it worked correctly one time only, and it was not on the first
try; but previous and subsequent attempts have repeatedly displayed
this gibberish sequence.

Try different baud rates in teraterm to see if it suddenly starts coming in
clearly. Make sure you are really using a 20MHz clock on the PIC. Looks
like you are almost there.
 
Are you using a 20MHz clock?

Yes, I am using a 20MHz clock
Are you getting what you expect here? Is the time delay coming out
correctly?

Yes, the time delays are correct here.
So 12 characters from the PIC turns into 6 characters on the
display.....sounds like a baud rate issue to me. Have you tried changing
the baud in the windos program? Do you have a scope? If so, just look at
the width of the data bits to see what the PIC is sending.
Try different baud rates in teraterm to see if it suddenly starts coming in
clearly. Make sure you are really using a 20MHz clock on the PIC. Looks
like you are almost there.

I will try to adjust the Baud; I imagine I just presumed they would be
consistent if set the same.
 
I am trying to work out RS232 using a PIC, so I created a simple
program to send a string message which would appear in the TeraTerm
window.  Here is the code snippet:

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

void main() {

   output_high(PIN_A0);
   delay_ms(1000);
   output_low(PIN_A0);
   delay_ms(1000);

   while(TRUE){
      output_high(PIN_B4);
      delay_ms(500);
      output_low(PIN_B4);
      printf("Please work\n");
      delay_ms(1000);
   }

}

====================

I have a Max232 converter in configuration according to the diagram on
page 7 of this datasheet:http://www.ortodoxism.ro/datasheets/texasinstruments/max232.pdf

I am also using a device which transforms RS232 to USB and then has
drivers to emulate a COM port on the PC, since my computer has no
serial port. It is this piece:http://www.sparkfun.com/commerce/product_info.php?products_id=198

My settings in both my device manager for COM1 (the emulated com port)
and in Tera Term are

9600 baud
8 data bits
no parity
1 stop
no flow control

When I run this program, I get the following in Tera Term:http://bitzphoto.com/ECE445/teraterm.png
That is, a repeating sequence of incorrect characters.

I'm lost at any other settings that might need to be changed to make
the data appear correctly; any thoughts would be greatly appreciated.

Oddly, it worked correctly one time only, and it was not on the first
try;  but previous and subsequent attempts have repeatedly displayed
this gibberish sequence.

Firstly 16 series pics don't work well with C. If you must use C
switch to the 18 series (I think there is a pin compatable one for
your chip) you'll get much better results. Secondly slow periferals
like UARTS should use their interrups with a buffer. Your program just
writes to the buffer and the ISR sends out the data, you do a similar
thing with the reciever. Thirdly printf is a monster, to be avoided if
at all possible (you only need it if you are sending floating point
numbers).
 
D

Donald

Jan 1, 1970
0
Yes, I am using a 20MHz clock




Yes, the time delays are correct here.




I will try to adjust the Baud; I imagine I just presumed they would be
consistent if set the same.
On most C compilers, you still need to write code to init the serial
port and baud rate timer.

The compiler you are using will auto-magicly set the baudrate for you ??

What compiler are you using ??

donald
 
R

Roger Hamlett

Jan 1, 1970
0
Donald said:
On most C compilers, you still need to write code to init the serial
port and baud rate timer.
No. He is using CCS, from the syntax used. It automatically sets up the
port according to the #use RS232 line.
The compiler you are using will auto-magicly set the baudrate for you ??

What compiler are you using ??
What he posts, should work. However there are some caveats:
What _version_ of CCS. They recently (nearly a year ago now!...), launched
their 'version 4' compilers. So far, these are still not working right.
The latest version (32 releases after the supposed 'launch'), is
approaching a 'beta' status to my mind. They ran a 'beta' program for a
few weeks, and had not even got the compiler close to working, or any of
the main issues fixed, before they went 'live'. I was on the beta program,
and one of the things I raised, was only fixed a couple of weeks ago...
I'd guess this may be the free 'demo' version (since this supports the
16F877), and how good this is I don't know. However I would expect basic
code at this level to work OK.
I have to 'query' why on earth he bothers to test for the compiler being
PCM?. This is normally only done, when you want to make the source code
portable, across multiple chips, and as shown, is an extra thing to go
wrong.
The 'odd' thing, is that the behaviour (which appears to be returning 6
characters for 12 sent), would appear to be the wrong way 'round' for a
likely crystal rate problem.

Best Wishes
 
J

James Beck

Jan 1, 1970
0
Firstly 16 series pics don't work well with C.
They work well enough for his trivial program to function.
If you must use C switch to the 18 series (I think there is a pin compatable one for
your chip) you'll get much better results.
The 18 series would not fix his problem here.
Secondly slow periferals
like UARTS should use their interrups with a buffer. Your program just
writes to the buffer and the ISR sends out the data, you do a similar
thing with the reciever.
You know nothing about the 'C' cross compiler he is using.
CCS does NOT use any buffers or ISRs to send out data when using the
built in functions. It just uses polled IO.
Thirdly printf is a monster, to be avoided if
at all possible (you only need it if you are sending floating point
numbers).
I don't like to throw printf around either, but NOTHING you offered up
will do anything to help this guy.
WE ALL GET IT. You don't like PIC MCU's. Great.
Now, just for fun, see if you can give him some info that just might
help him along.

Jim
 
M

mpm

Jan 1, 1970
0
When I first read this thread, my immediate "conclusion" was that it
was probably something in the USB to Serial adapter. (I've never had
much luck with those...)

It would be interesting to try the circuit out on a dumb terminal,
like one of those old TeleVideo or Qume or Wyse terminals.

As for the characters, it starts off with (1) incorrect character, and
then the rest are a repeating sequence. (Again, incorrect) - but it
makes you wonder what the heck the first character is doing? The 6
for 12 argument personally doesn't sway me all that much.

I guess you could try slowing down the baud rate on each end, to say
300 Baud or so and see if that works. If the real cuplrit is sloppy
timing, the errors should be less critical at the lower baud rates.

Otherwise(??), I just don't know enough about the parts the OP is
using.
Good luck.

-mpm
 
What he posts, should work. However there are some caveats:
What _version_ of CCS. They recently (nearly a year ago now!...), launched
their 'version 4' compilers. So far, these are still not working right.
The latest version (32 releases after the supposed 'launch'), is
approaching a 'beta' status to my mind. They ran a 'beta' program for a
few weeks, and had not even got the compiler close to working, or any of
the main issues fixed, before they went 'live'. I was on the beta program,
and one of the things I raised, was only fixed a couple of weeks ago...
I'd guess this may be the free 'demo' version (since this supports the
16F877), and how good this is I don't know. However I would expect basic
code at this level to work OK.

Yes, it is the version 4 CCS compiler. :-(
I have to 'query' why on earth he bothers to test for the compiler being
PCM?. This is normally only done, when you want to make the source code
portable, across multiple chips, and as shown, is an extra thing to go
wrong.

Sorry, this was just the pertinent snippet; this code is based on the
framework of one of CCS's sample programs, in which they have a full
test for PCM, PCB, or PCH. I just copied the important #defines to
show my RS232 setup. I can simply remove the check if you think that
is a possible issue.
 
I don't like to throw printf around either, but NOTHING you offered up
will do anything to help this guy.

In regards to printf() I was simply mirroring the way it was used in
some CCS sample code, but if you think something like puts() is better
or some other function I will try that.
 
When I first read this thread, my immediate "conclusion" was that it
was probably something in the USB to Serial adapter. (I've never had
much luck with those...)

It would be a shame if that part was bad, because it wasn't very cheap
to replace :-(
I guess you could try slowing down the baud rate on each end, to say
300 Baud or so and see if that works. If the real cuplrit is sloppy
timing, the errors should be less critical at the lower baud rates.

I will try lowering the baud rate.
 
So we shortened the message to just output "A".

The display on the Tera Term is now "_" (underscore)

The binary for A is 1000001
The binary for _ is 1011111.

Just an update.
 
J

James Beck

Jan 1, 1970
0
In regards to printf() I was simply mirroring the way it was used in
some CCS sample code, but if you think something like puts() is better
or some other function I will try that.
For what you are doing, printf() is just fine.

If I were trying to get this example working I would do the following :

1) Verify that your USB-> RS232 adapter was working as expected.
Try shorting pins 2 and 3 together, type, and see if you at least
see the chars getting echoed.
Make sure you have local echo turned off on your comm program.

2) Verify that your level shifter (MAX232) is working OK.
Same thing. Remove the PIC so it isn't trying to drive
the port lines and short your in to your out, on the logic
side of the level shifter. You should get the chars echoed
again.

3) Make sure your oscillator is REALLY running at 20MHz.

4) Check to see what the error % is when setting up your
baud rate at 20MHz. We had a situation where an oscillator
was out of whack to the high end of its tolerance and our
ATEN USB to Serial adapter was out of whack to the low end
and between the 2 if was enough to trash the communications.

You should just have to do something like this :

Start a new project using the CCS project wizard.
Just setup the serial defines by specifying the clock frequency and your
desired baud rate. Make sure all other hardware is just set to OFF for
now.
When the program shell is made just add something like the following
after the hardware setup info :

printf("Hello World\n\r");
sleep();

nothing more.
Then, let's see what happens.
BTW, I have been using the Ver 4 compiler for quite a while now. I
moved from Rev 3 after they had a month or so to see what was going to
blow up in the field, and I have not had any problems that were show
stoppers.

Jim
 
They work well enough for his trivial program to function.

True but so what, I expect he wants to do something practical
sometime.
The 18 series would not fix his problem here.

See previous answer.

You know nothing about the 'C' cross compiler he is using.
CCS does NOT use any buffers or ISRs to send out data when using the
built in functions.  It just uses polled IO.

I do know nothing of the CCS compiler. You have missed the point of
the statement. Read it slower and see if you can spot the point I'm
trying to make.
I don't like to throw printf around either, but NOTHING you offered up
will do anything to help this guy.

It might if he reads better than you.

�
WE ALL GET IT.  You don't like PIC MCU's.

Wrong again, I've been using PICS since the 80's, I like them.

�Great.
Now, just for fun, see if you can give him some info that just might
help him along.

                       Jim

I have some routines, if he emails me he can have them. Their not
written for the PIC and they rely on an understanding of how
interrupts work so he may not yet be ready for them just yet.
 
If I were trying to get this example working I would do the following :

1) Verify that your USB-> RS232 adapter was working as expected.
Try shorting pins 2 and 3 together, type, and see if you at least
see the chars getting echoed.
Make sure you have local echo turned off on your comm program.

In this setup the characters echo correctly.
2) Verify that your level shifter (MAX232) is working OK.
Same thing. Remove the PIC so it isn't trying to drive
the port lines and short your in to your out, on the logic
side of the level shifter. You should get the chars echoed
again.

They do indeed echo correctly here.
3) Make sure your oscillator is REALLY running at 20MHz.

hooking up the oscillator to a scope, I get that the period is 5
divisions with each division 10ns, which works out to 20MHz.
4) Check to see what the error % is when setting up your
baud rate at 20MHz. We had a situation where an oscillator
was out of whack to the high end of its tolerance and our
ATEN USB to Serial adapter was out of whack to the low end
and between the 2 if was enough to trash the communications.

You should just have to do something like this :

Start a new project using the CCS project wizard.
Just setup the serial defines by specifying the clock frequency and your
desired baud rate. Make sure all other hardware is just set to OFF for
now.
When the program shell is made just add something like the following
after the hardware setup info :

printf("Hello World\n\r");
sleep();

nothing more.
Then, let's see what happens.

Here is the resulting output:

www.bitzphoto.com/ECE445/nothello.png

In a similar vein, I adjusted the original code in the following way:
char test = '0';
while(TRUE){
output_high(PIN_B4);
delay_ms(500);
output_low(PIN_B4);
printf("%c", test);
test++;
delay_ms(1000);
}

Hoping to create the ASCII list 0,1,2,3.....x,y,z. Instead I get
this:

www.bitzphoto.com/ECE445/decrements.png
(ignore the question marks, they are not part of the sequence).

So it is kind of like a decrementing sequence, except it alternates
between the numbers grouping and the letters. I will look at this for
possible patterns; one I see right away is that the one group has a
first significant ASCII bit as 0 and the other as a 1, but the
alternating isn't everytime.
 
J

James Beck

Jan 1, 1970
0
True but so what, I expect he wants to do something practical
sometime.

Learning is practical enough.
See previous answer.
See previous answer.
I do know nothing of the CCS compiler. You have missed the point of
the statement. Read it slower and see if you can spot the point I'm
trying to make.

The point I am trying to make, is his program SHOULD work just fine.
It might if he reads better than you.
So, what information did you give him that would make his problem go
away?
ï¿=3F

Wrong again, I've been using PICS since the 80's, I like them.
Oh, excuse me, you are just one of those PIC assembler nuts then.
ï¿=3FGreat.

I have some routines, if he emails me he can have them. Their not
written for the PIC and they rely on an understanding of how
interrupts work so he may not yet be ready for them just yet.
So, in fact you do not have any information to help him with.
Big surprise.

Jim
 
R

Roger Hamlett

Jan 1, 1970
0
So we shortened the message to just output "A".

The display on the Tera Term is now "_" (underscore)

The binary for A is 1000001
The binary for _ is 1011111.

Just an update.
Ok.
Now multiple things. If you have download rights for the compiler, 3.249,
is available to download. Install this into another directory, and see if
the behaviour is the same. If so, you have at least ruled this out.
Now, remember that for asynchronous serial, the data is sent LSBit first.
Also, the 'start', requires a '0' (low) at the input, before the data byte
itelf is sampled. Then there is a high 'stop bit' at the end. So, 'A' is:

1010000010x1, with '0' being 0v, and '1' being 5v (the 'x' is the parity
bit, which would depend on whether this is enabled, and how it is set)

The _, is:

1011111010x1

Now the chip will start reading, when it sees a 0v for the first time.
Notice the five successive '1's in the second stream, and the five
successive '0's in the first.
If you invert the bit pattern for the 'A', you get:

0101111101/x0

Notice how if you shift this left one bit, it closely resembles what you
are receiving.
It looks suspiciously like you might be lacking a signal inversion in the
connection to the PIC (RS232 uses -3 to -25v for a '1', and +3 to +25v for
a '0').
Are you sure the converter you have is USB to RS232?. You speak about it
as being expensive, but these are incredibly cheap (well under 10$). I
have a nasty suspicion, that your converter, might be something like USB
to RS485, rather than RS232!. This would explain it's price. While I
agree, that the USB-RS232 converters can sometimes be troublesome, most
now work OK.
I would try the simple test of connecting it to another PC with RS232 (can
you borrow one from a friend?),using just the minimum 3 wire connection
(TX to RX, RX to TX, and GND to GND). At least this will allow you to
'rule out' the unit if it works.
I really would be looking at the snalling polarity, and the connections
round the MAX232.

Best Wishes
 
J

James Beck

Jan 1, 1970
0
In this setup the characters echo correctly.
Scratch that off the list.
They do indeed echo correctly here. That too....


hooking up the oscillator to a scope, I get that the period is 5
divisions with each division 10ns, which works out to 20MHz. One more.....


Here is the resulting output:

www.bitzphoto.com/ECE445/nothello.png

In a similar vein, I adjusted the original code in the following way:
char test = '0';
while(TRUE){
output_high(PIN_B4);
delay_ms(500);
output_low(PIN_B4);
printf("%c", test);
test++;
delay_ms(1000);
}

Hoping to create the ASCII list 0,1,2,3.....x,y,z. Instead I get
this:

www.bitzphoto.com/ECE445/decrements.png
(ignore the question marks, they are not part of the sequence).

So it is kind of like a decrementing sequence, except it alternates
between the numbers grouping and the letters. I will look at this for
possible patterns; one I see right away is that the one group has a
first significant ASCII bit as 0 and the other as a 1, but the
alternating isn't everytime.

I take it you have swapped the PIC out to make sure you don't have one
with a wonky UART.

Maybe the divisor is being set up wrong.
Can you change out oscillators?
You might try a different clock rate and see if that makes any
difference. I don't have any boards here that we run at 20MHz to test
the divisor settings with. That would be all I can think of off the top
of my head.

Jim
 
D

Donald

Jan 1, 1970
0
hooking up the oscillator to a scope, I get that the period is 5
divisions with each division 10ns, which works out to 20MHz.

OK, you do have a scope on hand.
In a similar vein, I adjusted the original code in the following way:
char test = '0';
while(TRUE){
output_high(PIN_B4);
delay_ms(500);
output_low(PIN_B4);
printf("%c", test);
test++;
delay_ms(1000);
}

This is too busy to trouble shoot hardware with.

Try this:

while( TRUE)
{
output_low(PIN_B4);
delay_ms(1);
output_high(PIN_B4);
printf("A"); // replace this line with a serial_char_out('A');
delay_ms(1);
}

On your two channel scope, put one channel on PIN_B4 and the other
channel on the serial out pin.

Sync your scope on the raising edge of PIN-B4.

It should look something like:

B4 +---------------------------------------------------+
______| |____________

------+start+-01--+ 02 04 08 10 20 +-40--+ 80 +stop-.---
Sout |_____| |_____._____._____._____._____| |____|

9600 baud is ~104 uSec per bit time

Theree will be a delay between the raising edge of B4 and the leading
edge of the serial start bit.

So B4 should bracket the letter A ( more or less). If this does not
match, then the baud rate is wrong.

I think your printf function is not calling the serial output routine
correctly. I have not used CCS before, so checking that the serial port
code is correct, would be your next task.


good luck
donald

PS: I haven't looked at the old messages, but it this hardware your own
design and construction ??
 
So we shortened the message to just output "A".




Ok.
Now multiple things. If you have download rights for the compiler, 3.249,
is available to download. Install this into another directory, and see if
the behaviour is the same. If so, you have at least ruled this out.
Now, remember that for asynchronous serial, the data is sent LSBit first.
Also, the 'start', requires a '0' (low) at the input, before the data byte
itelf is sampled. Then there is a high 'stop bit' at the end. So, 'A' is:

1010000010x1, with '0' being 0v, and '1' being 5v (the 'x' is the parity
bit, which would depend on whether this is enabled, and how it is set)

The _, is:

1011111010x1

Now the chip will start reading, when it sees a 0v for the first time.
Notice the five successive '1's in the second stream, and the five
successive '0's in the first.
If you invert the bit pattern for the 'A', you get:

0101111101/x0

Notice how if you shift this left one bit, it closely resembles what you
are receiving.
It looks suspiciously like you might be lacking a signal inversion in the
connection to the PIC (RS232 uses -3 to -25v for a '1', and +3 to +25v for
a '0').
Are you sure the converter you have is USB to RS232?. You speak about it
as being expensive, but these are incredibly cheap (well under 10$). I
have a nasty suspicion, that your converter, might be something like USB
to RS485, rather than RS232!. This would explain it's price. While I
agree, that the USB-RS232 converters can sometimes be troublesome, most
now work OK.
I would try the simple test of connecting it to another PC with RS232 (can
you borrow one from a friend?),using just the minimum 3 wire connection
(TX to RX, RX to TX, and GND to GND). At least this will allow you to
'rule out' the unit if it works.
I really would be looking at the snalling polarity, and the connections
round the MAX232.

Best Wishes

Well I'm a poor college student, so 20 dollars is expensive to me ;-)

The datasheet for the part indicates USB to rs232 functionality; and
the chip that resides on the breakout board is the cp2102 which lists
as its applications rs232 to USB on its datasheet.

Here is the sparkfun product page:
http://www.sparkfun.com/commerce/product_info.php?products_id=198

I am not sure what snalling polarity is. Our connections to the
Max232 have been checked by many people, and we have done so according
to the numerous schematics we have found. Also, we know that the Max
works at least for data sent out from the PC and shorted back 'round
through the pins.
 
Top