Connect with us

Trying to send RS232 with PIC sends incorrect data in TeraTerm

Discussion in 'Electronic Design' started by [email protected], Apr 10, 2007.

Scroll to continue with content
  1. Guest

    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>
    #use delay(clock=20000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

    void main() {


    printf("Please work\n");


    I have a Max232 converter in configuration according to the diagram on
    page 7 of this datasheet:

    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:

    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:
    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.
  2. Are you using a 20MHz clock?
    Are you getting what you expect here? Is the time delay coming out
    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.
  3. Guest

    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.
  4. Guest

    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
  5. Donald

    Donald Guest

    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 ??

  6. No. He is using CCS, from the syntax used. It automatically sets up the
    port according to the #use RS232 line.
    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
    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
  7. James Beck

    James Beck Guest

    They work well enough for his trivial program to function.
    The 18 series would not fix his problem here.
    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 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.

  8. mpm

    mpm Guest

    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
    Good luck.

  9. Guest

    Yes, it is the version 4 CCS compiler. :-(
    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.
  10. Guest

    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.
  11. Guest

    It would be a shame if that part was bad, because it wasn't very cheap
    to replace :-(
    I will try lowering the baud rate.
  12. Guest

    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.
  13. James Beck

    James Beck Guest

    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

    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
    When the program shell is made just add something like the following
    after the hardware setup info :

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

    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

  14. Guest

    True but so what, I expect he wants to do something practical
    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.
    It might if he reads better than you.

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

    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.
  15. Guest

  16. James Beck

    James Beck Guest

    Learning is practical enough.
    See previous answer.
    The point I am trying to make, is his program SHOULD work just fine.
    So, what information did you give him that would make his problem go
    Oh, excuse me, you are just one of those PIC assembler nuts then.
    So, in fact you do not have any information to help him with.
    Big surprise.

  17. 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:


    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:


    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
  18. James Beck

    James Beck Guest

  19. Donald

    Donald Guest

    OK, you do have a scope on hand.
    This is too busy to trouble shoot hardware with.

    Try this:

    while( TRUE)
    printf("A"); // replace this line with a serial_char_out('A');

    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

    PS: I haven't looked at the old messages, but it this hardware your own
    design and construction ??
  20. Guest

    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:

    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.
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day