This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to get second FX2 serial port to work?

Hello,

I have read all the info regarding how to get the 2nd serial port to work with putchar (printf). I have updated the 'PUTCHAR.C' file like recommended by Keil:

char putchar (char c)  {
  while (!TI1);
  TI1 = 0;
  return (SBUF1 = c);
}

My main function looks like this:

void main()
{
        unsigned long ul;

#ifndef MONITOR51
    SCON  = 0x50;                       /* SCON: mode 1, 8-bit UART, enable rcvr      */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
    TH1   = 221;                /* TH1:  reload value for 1200 baud @ 16MHz   */
    TR1   = 1;                  /* TR1:  timer 1 run                          */
    TI    = 1;                  /* TI:   set TI to send first char of UART    */
#endif

        // Initialize the second serial port on the FX2 eval board.
        // NOTE that we are sharing timer 1 with serial port 0.
    SCON1  = 0x50;                      /* SCON1: mode 1, 8-bit UART, enable rcvr      */
    TI1    = 1;                 /* TI1:   set TI1 to send first char of UART    */

        while(1)
        {
                for(ul=0; ul<0xffff; ul++)
                {
                        //PRINTF(("%ld\r\n", ul));
                        printf("Testing...");
                }
        }
}

Both serial ports 0 and 1 are using timer 1 as baudrate generator. The problem with the above code is that the code hangs on this statement in putchar: "while (!TI1);". I have tried to set TI1 but it immediately gets cleared again...

I want to get printf to work on serial port 1 because i want to be able to stop a running application via uVision3 (i'm using Mon51).

Parents
  • "i'm using Mon51"

    But all your setup code for the 2nd UART is within a #ifndef MONITOR51...

    #ifndef MONITOR51 // The following code is disabled when MONITOR51 is defined!!
        SCON  = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr      */
        TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload        */
        TH1   = 221;  /* TH1:  reload value for 1200 baud @ 16MHz   */
        TR1   = 1;    /* TR1:  timer 1 run                          */
        TI    = 1;    /* TI:   set TI to send first char of UART    */
    #endif
    

Reply
  • "i'm using Mon51"

    But all your setup code for the 2nd UART is within a #ifndef MONITOR51...

    #ifndef MONITOR51 // The following code is disabled when MONITOR51 is defined!!
        SCON  = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr      */
        TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload        */
        TH1   = 221;  /* TH1:  reload value for 1200 baud @ 16MHz   */
        TR1   = 1;    /* TR1:  timer 1 run                          */
        TI    = 1;    /* TI:   set TI to send first char of UART    */
    #endif
    

Children
  • "But all your setup code for the 2nd UART is within a #ifndef MONITOR51..."

    No it is not. The second UART uses the same timer 1 for its baudrate generation so it doesn't need to be initialized again. MONITOR51 is defined in the preprocessor so that snippet of code is never executed.

    The second UART shares timer 1 with the first UART. The MON51 monitor initializes timer 1 for the first UART so that a baudrate of 38400 N81 is being used. This works fine since i can connect and debug with uVision3.

    The assignment of SCON and TI1 IS however executed so the second UART should work but does not. Something in the system causes TI1 to always be cleared (even when explicitly set) and since i don't have the source code for MON51 i'm suspecting that MON51 somehow touches the second serial port too!

  • The problem has now been sorted out. I this morning realized that the MON51 connection is using SIO-1 and that the STDIO is using SIO-0. This means that the Keil putchar routine should not be changed (already uses the first serial port). The only thing that needs to be done (not mentioned anywhere) is to set up the baudrate source for the first UART to be timer 1 and to clear the TI and RI bits. My code snipped below shows the working solution, i hope this can help others.

    NOTE that timer 1 should not be initialized when loading the application into the FX2 board via Mon51 because the monitor already initializes the timer.

    void main()
    {
            unsigned long ul;
    
            // FX2 Serial port initialization:
            // Set up the first serial port so we can use it for the STDIO functions
            // (printf, putchar etc). NOTE that the second serial port (SIO-1) is
            // used by the Mon51 connection on the FX2 board while we use the first
            // serial port (SIO-0) for STDIO. Also note that if the monitor is in use
            // we don't have to initialize timer 1 because it has already been done by
            // the monitor. All we have to do is to set up the first serial port to
            // use timer 1.
    #ifndef MONITOR51
        TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
        TH1   = 236;                /* TH1:  reload value for 38400 baud @ 48MHz   */
        TR1   = 1;                  /* TR1:  timer 1 run                          */
    #endif
        SCON0  = 0x53;                      /* SCON0: mode 1, 8-bit UART, enable rcvr, Clr TI, RI */
    
            while(1)
            {
                    for(ul=0; ul<0xffff; ul++)
                    {
                            printf("Testing...");
                    }
            }
    }