Sending Via PIC18F97J60 EUSART

microcontrollerpicserialuart

When trying to send and receive using a PIC18F97J60 and MAX232 using a program written with the C18 compiler, I am only able to transmit data. For receiving, I have tried at least 50 methods but none are working. I even tried the software on multiple micro-controller boards to check for a hardware problem but none of the boards ever receive anything. I believe that the following items are correct:

  • My clock is perfect at 41.6667MHz
  • My baud generation is perfect
  • My hardware is OK (some other IIIrd party hex code able to receive also)
  • My host PC, its COM port, and the serial cable are OK

Can anyone guide with probable areas I may be missing?

—————— FURTHER CLARIFICATIONS ——————————————-

Thanks Olin for helping, you are great man. Sorry for not putting my question correctly. Please note:

I was trying to do serial I/O to write a boot loader for the PIC18F97J60 myself as my vendor's supplied boot loader stops sending/receiving with PCloader software after a partial user application hex download. It also ensures that RS232 port is able to both send and receive. Moreover, Microchip's boot loader described in AN1310 also stucks on receiving data.

My sample application (a bootloader) is able to transmit but never receives anything. I'm in soup: either I need a new boot loader or my application must work. I have never faced such a problem in my 12 years of development and I am feeling like a fool.

Other details as you requested are as follows:

  1. I had 10-12 PIC18F97J60 cards with MAX232 on C6/C7 for Serial I/O. The problem is the same for all boards (of different batches).
  2. I wish to do 9600 baud, 8 bit, no parity, 1 stop, no handshake, no interrupt data exchange with RealTerm (Better Than Hyperterminal – Displays HEX Code).
  3. My clock and baud rate calculations are perfect for 41.6667MHz. I have set OSCTUNE = 0x40 and BAUDCON = 1084. I am able to receive perfectly on the PC with RealTerm.
  4. My program not able to receive anything on the PIC but able to transmit.
  5. I tried polling as well as interrupt but nothing works.

Snippet of code is as follows:

void putchar(unsigned char Char)
{
    //Wait for (TSR==1)
    while(TXSTA1bits.TRMT!=1);
    //Trasmit Current Data
    TXREG1= Char;
    //Wait for (TSR==1)
    while(TXSTA1bits.TRMT!=1);
}

void putstr(unsigned char *String)
{
     do
     {
         putchar((*String));
     }while(*String++);
    //CR
     putchar(CR);
    //LF
    putchar(LF);
}

void main(void)
{
    unsigned char RS232[] = "RS-232";
    OSCTUNE = 0x40;
    TXSTA1 = 0x24;
    RCSTA1 = 0x90;
    BAUDCON1=0x08;
    SPBRGH1=0x04;
    SPBRG1=0x3C;

while(1)
{
    putstr(RS232);
    Delay10KTCYx(200);
    if(PIR1bits.RC1IF == 1)
    {
            MYChar = RCREG1; //*** No OERR & FERR present, RC1IF never gets set ***
    }
}

}

Best Answer

One annoying misfeature of the UART on every PIC I've worked with is that a data overrun error will shut down the receiver until code disables and re-enables it. It is thus imperative to have code that will periodically check the overrun-error flag and, if it is set, disable and re-enable the UART receive function. Otherwise if the receive buffer overruns, you won't just lose a received byte--you'll lose all data forevermore.

I'm not really sure why Microchip designed their UARTs this way. My guess would be that in early PICs a receive overrun would cause the receive state machine to lose frame sync, and that disabling the receiver was considered preferable to receiving randomly-framed data (I might agree with them on that point, though I would consider dropping whole bytes while maintaining sync to be better still); later PICs maintained the behavior for compatibility, despite substantial redesigns of the UART subsystem.

In any case, the PIC's UART implementation is what it is. Check to ensure that the UART receiver is enabled and the receive-overflow isn't tripped. If not, disable the UART receive function and re-enable it. Note, btw, that on some PICs the master disable for the UART function will not disable the receiver; you need to clear and re-set the receiver enable.

Related Topic