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

problem when transmitting the a string data to GPS interface with 8051 uC

void main(void)
{
        unsigned short  l_us_temp;
        //Disable watchdog timer
        WDTCN = 0xDE;
   WDTCN = 0xAD;

        ExtCrystalOsc_Init();

        //Initialise crossbar and GPIO
        Port_Init();

        EMIF_Init();

        //Initialise Timer 0
        Timer0_Init();

        //Initialise Timer 2
        Timer2_Init();

        //Initialise Timer 4
        Timer4_Init();

        //Initialise UART0
        UART0_Init();

        //Initialise UART1
        UART1_Init();

        //Initialise ADC
        ADC0_Init();

        //Initialise DAC
        DAC0_Init();
        DAC1_Init();

        //Initialise PCA0
        PCA0_Init();

        //Initialise INT0_N & INT1_N
        Ext_Interrupt_Init();

//lsl : 04 Jan 2011 : 0852hrs : disable Watchdog timer temporarily
        //Initialise Watchdog Timer
//      Watchdog_Init();

        //Initialise SPI0
        SPI0_Init();

        //------------------------
        //Reset IMU-A, IMU-B & GPS

   SFRPAGE = CONFIG_PAGE;

        IMU_A_CS = 1;
        IMU_B_CS = 1;

        IMU_A_RST = 0;
        IMU_B_RST = 0;

        GPS_RST = 0;

        delay_ms(1);

        IMU_A_RST = 1;
        IMU_B_RST = 1;

        GPS_RST = 1;

        delay_ms(1);

        //---------------------------------------------------------
        //lsl : 31 Dec 2010 : 1046hrs: Initialise variables : begin

        g_us_rx0_ptr = 0;
        g_us_tx0_ptr = 0;
        g_us_rd0_ptr = 0;

        for (l_us_temp = 0 ; l_us_temp < RX_BUFFER_SIZE ; l_us_temp++)
        {
                g_c_rx0_buffer[l_us_temp] = 0;
        }

        g_us_rx1_ptr = 0;
        g_us_tx1_ptr = 0;
        g_us_rd1_ptr = 0;

        for (l_us_temp = 0 ; l_us_temp < RX_BUFFER_SIZE ; l_us_temp++)
        {
                g_c_rx1_buffer[l_us_temp] = 0;
        }

        //lsl : 05 Jan 2011 : 1916hrs : tested
        UART1_Buffer = "\rlog version\r\n";
        g_us_tx1_cmd_length = 14;

        //lsl : 06 Jan 2011 : 1916hrs : tested ok
        //UART1_Buffer = "frequencyout enable 2 4\r\n";
        //g_us_tx1_cmd_length = 25;

        g_uc_gps_init = 0;

        //Enable global interrupts
        EA = 1;

        //-----------------------------------------------------------------------------
        // Start of WHILE LOOP
        //-----------------------------------------------------------------------------

   while (1)
        {
                //Toggle LED_1 & LED_2
           SFRPAGE = CONFIG_PAGE;
                LED_1 ^= 1;
                LED_2 ^= 1;

                           }

        //-----------------------------------------------------------------------------
        // End Of WHILE LOOP
        //-----------------------------------------------------------------------------
}

I could not able to transmit the data through the UART when i run the program. But when i put a breakpoint, it seems working fine. May i know where is the problem? i seems like i could not find it. thanks

Parents
  • If you can't find it when you have all the code and the hardware right there in front of you, how on earth do you expect anyone else to find it who does not have the code, and does not know your hardware??

    You have not shown any code that has anything to do with transmitting from the UART!

            //lsl : 06 Jan 2011 : 1916hrs : tested ok
            //UART1_Buffer = "frequencyout enable 2 4\r\n";
            //g_us_tx1_cmd_length = 25;
    


    What does "tested ok" mean here?

    Did it work once, and you have broken it?

            //lsl : 05 Jan 2011 : 1916hrs : tested
            UART1_Buffer = "\rlog version\r\n";
            g_us_tx1_cmd_length = 14;
    


    Again, what does "tested" mean here?
    What test? What was the result of the test?

    Why are you setting the length as a "Magic Number"?
    This is asking for trouble!
    Why not use strlen instead??

    "when i put a breakpoint, it seems working fine"

    Suggests a timing problem, don't you think...?

Reply
  • If you can't find it when you have all the code and the hardware right there in front of you, how on earth do you expect anyone else to find it who does not have the code, and does not know your hardware??

    You have not shown any code that has anything to do with transmitting from the UART!

            //lsl : 06 Jan 2011 : 1916hrs : tested ok
            //UART1_Buffer = "frequencyout enable 2 4\r\n";
            //g_us_tx1_cmd_length = 25;
    


    What does "tested ok" mean here?

    Did it work once, and you have broken it?

            //lsl : 05 Jan 2011 : 1916hrs : tested
            UART1_Buffer = "\rlog version\r\n";
            g_us_tx1_cmd_length = 14;
    


    Again, what does "tested" mean here?
    What test? What was the result of the test?

    Why are you setting the length as a "Magic Number"?
    This is asking for trouble!
    Why not use strlen instead??

    "when i put a breakpoint, it seems working fine"

    Suggests a timing problem, don't you think...?

Children
  • Sorry if i had miss out some information. I m using a novatel gps receiver OEMV - 1 - L1 interface with Sillicon Lab 8051 mircontoller. For the tested part, it is where i use the breakpoint over there and i run it. the output data is correct. I did tried to change the timer but it still does not work.

  • So how about giving that information?

    In particular, show the UART transmission code!

    "I did tried to change the timer"

    What timer?

    What change(s) did you "try"?

    What, exactly, were you expecting those changes to achieve?

    What, exactly, did those changes to achieve?

    "i use the breakpoint"

    Again, if inserting a breakpoint makes it "work", does that not suggest that you have a timing issue??

  • 
    void UART1_ISR (void) interrupt 20
    {
            //Save current SFR page
       char SFRPAGE_SAVE = SFRPAGE;
    
       SFRPAGE = UART1_PAGE;
    
       if (RI1 == 1)
       {
                    //Clear receive interrupt flag
          RI1 = 0;
    
                    //Read a character from UART0 Data Buffer
                    g_c_rx1_buffer[g_us_rx1_ptr] = SBUF1;
    
                    g_us_rx1_ptr++;
    
                    if (g_us_rx1_ptr > RX_BUFFER_SIZE)
                    {
                            g_us_rx1_ptr = 0;
                    }
       }
    
            //-----------------------------------
            //lsl : 05 Jan 2011 : 1629hrs : begin
    
            if (TI1 == 1)                                                   // Check if transmit flag is set
       {
                    TI1 = 0;                                                                // Clear interrupt flag
    
                    if (g_us_tx1_cmd_length != 0)   // If buffer not empty
                    {
                            SBUF1 = UART1_Buffer[g_us_tx1_ptr];     // Transmit to Hyperterminal
    
                            g_us_tx1_ptr++;            // Update counter
    
                            g_us_tx1_cmd_length--;       // Decrease array size
                    }
                    else
                    {
             g_us_tx1_cmd_length = 0;               // Set the array size to 0
          }
            }
    
            //lsl : 05 Jan 2011 : 1629hrs : end
            //-----------------------------------
    
            //Restore SFR page
            SFRPAGE = SFRPAGE_SAVE;
    }
    void UART1_Init(void)
    {
            //Save current SFR page
       char SFRPAGE_SAVE = SFRPAGE;
    
            //Switch to UART1
       SFRPAGE = UART1_PAGE;
    
       SCON1 = 0x10;
    
               SFRPAGE = TIMER01_PAGE;
    
       TMOD &= 0x0F;
       TMOD |= 0x20;
    
       if (UART1_BR2 < 1)
            {
          TH1 = -(UART1_BR1);
          CKCON |= 0x10;                   // T1M = 1; SCA1:0 = xx
       }
            else if (UART1_BR2 < 4)
            {
          TH1 = -(UART1_BR1 / 4);
          CKCON &= ~0x13;                  // Clear all T1-related bits
          CKCON |=  0x01;                  // T1M = 0; SCA1:0 = 01
       }
            else if (UART1_BR2 < 12)
            {
          TH1 = -(UART1_BR1 / 12);
          CKCON &= ~0x13;                  // T1M = 0; SCA1:0 = 00
       }
            else
            {
          TH1 = -(UART1_BR1 / 48);
          CKCON &= ~0x13;                  // Clear all T1-related bits
          CKCON |=  0x02;                  // T1M = 0; SCA1:0 = 10
       }
    
            //Initialize Timer 1
       TL1 = TH1;
    
            //Start Timer 1
       TR1 = 1;
    
            //Initialise Timer 1 : end
            //--------------------------
    
            //Switch to UART1
       SFRPAGE = UART1_PAGE;
    
            //Indicate TX1 ready
       TI1 = 1;
    
            //Set ES1 to enable UART1 interrupt
            EIE2 |= 0x40;
    
            //PS1 = 0 -> to set UART1 interrupt to low-priority
            EIP2 &= 0xBF;
    
            //PS1 = 1 -> to set UART1 interrupt to high-priority
            //EIP2 |= 0x40;
    
            //Restore SFR page
       SFRPAGE = SFRPAGE_SAVE;
    }
    void UART0_Init(void)
    {
       char SFRPAGE_SAVE;
    
            //Save current SFR page
       SFRPAGE_SAVE = SFRPAGE;
    
            //Switch to Timer 3
       SFRPAGE = TMR3_PAGE;
    
            //Timer 2 in 16-bit auto-reload up timer mode
       TMR3CN = 0x00;
    
            //SYSCLK is time base; no output, up count only
       TMR3CF = 0x08;
    
            //Setting reload value
       RCAP3 = - ((long)SYSCLK/BAUDRATE_0/16);
    
       TMR3 = RCAP3;
    
            //Start Timer 3
       TR3 = 1;
    
            //Switch to UART0
       SFRPAGE = UART0_PAGE;
    
            //8-bit variable baud rate, 9th bit ignored; RX enabled, clear all flags
       SCON0 = 0x50;
    
            //Clear all flags; enable baud rate doubler (not relevant for these timers)
            //Use Timer 3 as RX and TX baud rate source;
       SSTA0 = 0x1A;
    
            //Indicate TX0 ready
       TI0     = 1;
    
            //Enable UART0 interrupt
    //   ES0 = 1;
    
            //IP: Interrupt Priority
    
            //Bits 7–6:     UNUSED. Read = 11b, Write = don't care.
    
            //Bit 5:                PT2: Timer 2 Interrupt Priority Control.
            //This bit sets the priority of the Timer 2 interrupt.
            //0: Timer 2 interrupt set to low priority.
            //1: Timer 2 interrupt set to high priority.
    
            //Bit 4:                PS0: UART0 Interrupt Priority Control.
            //This bit sets the priority of the UART0 interrupt.
            //0: UART0 interrupt set to low priority.
            //1: UART0 interrupts set to high priority.
    
            //Bit 3:                PT1: Timer 1 Interrupt Priority Control.
            //This bit sets the priority of the Timer 1 interrupt.
            //0: Timer 1 interrupt set to low priority.
            //1: Timer 1 interrupts set to high priority.
    
            //Bit 2:                PX1: External Interrupt 1 Priority Control.
            //This bit sets the priority of the External Interrupt 1 interrupt.
            //0: External Interrupt 1 set to low priority.
            //1: External Interrupt 1 set to high priority.
    
            //Bit 1:                PT0: Timer 0 Interrupt Priority Control.
            //This bit sets the priority of the Timer 0 interrupt.
            //0: Timer 0 interrupt set to low priority.
            //1: Timer 0 interrupt set to high priority.
    
            //Bit 0:                PX0: External Interrupt 0 Priority Control.
            //This bit sets the priority of the External Interrupt 0 interrupt.
            //0: External Interrupt 0 set to low priority.
            //1: External Interrupt 0 set to high priority.
    
            //Set UART0 interrupt to low-priority
       IP &= 0xEF;
    
            //Set UART0 interrupt to high-priority
       //IP |= 0x10;
    
            //Restore SFRPAGE
       SFRPAGE = SFRPAGE_SAVE;
    }
    void UART0_ISR (void) interrupt 4
    {
            //Save current SFR page
       char SFRPAGE_SAVE = SFRPAGE;
    
       SFRPAGE = UART0_PAGE;
    
       if (RI0 == 1)
       {
                    //Clear receive interrupt flag
          RI0 = 0;
    
                    //Read a character from UART0 Data Buffer
                    g_c_rx0_buffer[g_us_rx0_ptr] = SBUF0;
    
                    g_us_rx0_ptr++;
    
                    if (g_us_rx0_ptr > RX_BUFFER_SIZE)
                    {
                            g_us_rx0_ptr = 0;
                    }
       }
    
            //-----------------------------------
            //lsl : 04 Jan 2011 : 1125hrs : begin
    
            if (TI0 == 1)
            {
                    //TI0 = 0;
                    g_us_tx0_ptr++;
            }
    
            //lsl : 04 Jan 2011 : 1125hrs : end
            //-----------------------------------
    
            //Restore SFR page
            SFRPAGE = SFRPAGE_SAVE;
    }
    


    I m using UART 1 to transimt my commands to the GPS receiver.

    the changes i made is that at the main program on my first post, i mask off the timer 0 and the UART 0 for this case. but i still get the same problem.

    Can you enlighten me on the timing problem issue u mention? is it my timer have some problem?

    thanks

  • The indentation of your code is all messed-up!

    Never use TAB characters in source code - precisely because the interpretation of TAB characters is entirely unreliable!
    Use only space characters - then your layout can be relied upon to always work!

    Any decent programmers editor (including the one in uVision) can be set to insert spaces when you press the TAB button.

    Any decent programmers editor (including the one in uVision) will have a facility to convert TABs to spaces.

  • 
    //-----------------------------------------------------------------------------
    // UART0_Init   Variable baud rate, Timer 3, 8-N-1
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // Configure UART0 for operation at <> 8 data bits, No parity, 1 stop bit using Timer 3 as baud rate source
    //
    //-----------------------------------------------------------------------------
    
    void UART0_Init(void)
    {
       char SFRPAGE_SAVE;
    
        //Save current SFR page
        SFRPAGE_SAVE = SFRPAGE;
    
        //Switch to Timer 3
        SFRPAGE = TMR3_PAGE;
    
        //Timer 2 in 16-bit auto-reload up timer mode
        TMR3CN = 0x00;
    
        //SYSCLK is time base; no output, up count only
        TMR3CF = 0x08;
    
        //Setting reload value
        RCAP3 = - ((long)SYSCLK/BAUDRATE_0/16);
    
        TMR3 = RCAP3;
    
        //Start Timer 3
        TR3 = 1;
    
        //Switch to UART0
        SFRPAGE = UART0_PAGE;
    
        //8-bit variable baud rate, 9th bit ignored; RX enabled, clear all flags
        SCON0 = 0x50;
    
        SSTA0 = 0x1A;
    
        //Indicate TX0 ready
        TI0     = 1;
    
    
        //Set UART0 interrupt to low-priority
        IP &= 0xEF;
    
       //Set UART0 interrupt to high-priority
       //IP |= 0x10;
    
            //Restore SFRPAGE
        SFRPAGE = SFRPAGE_SAVE;
    }
    
    //-----------------------------------------------------------------------------
    // UART1_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // Configure the UART1 using Timer1, for <BAUDRATE_1> and 8-data, No parity, 1-stop.
    //
    //-----------------------------------------------------------------------------
    
    void UART1_Init(void)
    {
        //Save current SFR page
        char SFRPAGE_SAVE = SFRPAGE;
    
        //Switch to UART1
        SFRPAGE = UART1_PAGE;
    
    
        SCON1 = 0x10;
    
        SFRPAGE = TIMER01_PAGE;
    
    
        TMOD &= 0x0F;
        TMOD |= 0x20;
    
    
        if (UART1_BR2 < 1)
        {
          TH1 = -(UART1_BR1);
          CKCON |= 0x10;                   // T1M = 1; SCA1:0 = xx
        }
        else if (UART1_BR2 < 4)
        {
          TH1 = -(UART1_BR1 / 4);
          CKCON &= ~0x13;                  // Clear all T1-related bits
          CKCON |=  0x01;                  // T1M = 0; SCA1:0 = 01
        }
        else if (UART1_BR2 < 12)
        {
          TH1 = -(UART1_BR1 / 12);
          CKCON &= ~0x13;                  // T1M = 0; SCA1:0 = 00
        }
        else
        {
          TH1 = -(UART1_BR1 / 48);
          CKCON &= ~0x13;                  // Clear all T1-related bits
          CKCON |=  0x02;                  // T1M = 0; SCA1:0 = 10
        }
    
        //Initialize Timer 1
        TL1 = TH1;
    
        //Start Timer 1
        TR1 = 1;
    
        //Initialise Timer 1 : end
        //--------------------------
    
        //Switch to UART1
        SFRPAGE = UART1_PAGE;
    
        //Indicate TX1 ready
        TI1 = 1;
    
    
        //PS1 = 0 -> to set UART1 interrupt to low-priority
        EIP2 &= 0xBF;
    
    
        //Restore SFR page
        SFRPAGE = SFRPAGE_SAVE;
    }
    <\pre>
    
    Sorry. that is my bad. I have re-paste my code on the UART 0 and UART 1 above. I have tried many times in transmitting the valid command such as "log version" as well as invaild command such as "a". It went through transmit to the GPS receiver but i could not able to receive the desired output. Take for example as invaild command such as "a", the ouput is "<invalid message ID>.
    
    I will show you my receving code in the next post.
    
    
    

  • void UART0_ISR (void) interrupt 4
    {
       //Save current SFR page
       char SFRPAGE_SAVE = SFRPAGE;
    
       SFRPAGE = UART0_PAGE;
    
       if (RI0 == 1)
       {
          //Clear receive interrupt flag
          RI0 = 0;
    
          //Read a character from UART0 Data Buffer
          g_c_rx0_buffer[g_us_rx0_ptr] = SBUF0;
    
          g_us_rx0_ptr++;
    
          if (g_us_rx0_ptr > RX_BUFFER_SIZE)
          {
             g_us_rx0_ptr = 0;
          }
       }
    
      if (TI0 == 1)
      {
          //TI0 = 0;
          g_us_tx0_ptr++;
      }
    
      //Restore SFR page
       SFRPAGE = SFRPAGE_SAVE;
    }
    
    void UART1_ISR (void) interrupt 20
    {
       //Save current SFR page
       char SFRPAGE_SAVE = SFRPAGE;
    
       SFRPAGE = UART1_PAGE;
    
       if (RI1 == 1)
       {
          //Clear receive interrupt flag
          RI1 = 0;
    
          //Read a character from UART0 Data Buffer
          g_c_rx1_buffer[g_us_rx1_ptr] = SBUF1;
    
          g_us_rx1_ptr++;
    
          if (g_us_rx1_ptr > RX_BUFFER_SIZE)
          {
            g_us_rx1_ptr = 0;
          }
       }
    
            //-----------------------------------
            //lsl : 05 Jan 2011 : 1629hrs : begin
    
       if (TI1 == 1)        // Check if transmit flag is set
       {
         TI1 = 0; // Clear interrupt flag
    
         if (g_us_tx1_cmd_length != 0)   // If buffer not empty
         {
             SBUF1 = UART1_Buffer[g_us_tx1_ptr]; // Transmit to Hyperterminal
    
            g_us_tx1_ptr++;            // Update counter
    
            g_us_tx1_cmd_length--;       // Decrease array size
         }
         else
         {
             g_us_tx1_cmd_length = 0;               // Set the array size to 0
         }
       }
    
    
            //Restore SFR page
            SFRPAGE = SFRPAGE_SAVE;
    }
    

  • In your original post, you just show writing to the buffer:

            //lsl : 05 Jan 2011 : 1916hrs : tested
            UART1_Buffer = "\rlog version\r\n";
            g_us_tx1_cmd_length = 14;
    

    But you haven't shown anything that will actually start the transmission!

    Also, just as an aside, the 'else' clause is pointless here:

         if (g_us_tx1_cmd_length != 0)   // If buffer not empty
         {
             SBUF1 = UART1_Buffer[g_us_tx1_ptr]; // Transmit to Hyperterminal
    
            g_us_tx1_ptr++;            // Update counter
    
            g_us_tx1_cmd_length--;       // Decrease array size
         }
         else
         {
             g_us_tx1_cmd_length = 0;               // Set the array size to 0
         }
    


    Isn't it ?!

    Won't cause any problems - it's just pointless.

  • First i store the command in the UART1 Buffer after that when it receive the command it will set it to T1 =1; so that it will go into the loop above you mention.

    
    
    char putchar(char l_c_txdata)
    {
       //Save current SFR Page
       char SFRPAGE_SAVE = SFRPAGE;
    
       if (l_c_txdata == '\n')
       {
          //Carriage Return
            l_c_txdata = 0x0D;
       }
       else if (l_c_txdata == '\r')
       {
          //Line Feed
          l_c_txdata = 0x0A;
       }
    
       if (g_uc_uart == 0)
       {
          //Use UART0
          SFRPAGE = UART0_PAGE;
    
          //Wait for transmit complete
          while (!TI0);
    
          //Clear TI0 flag
          TI0 = 0;
    
          //Send character
          SBUF0 = l_c_txdata;
       }
       else if (g_uc_uart == 1)
       {
          //Use UART1
          SFRPAGE = UART1_PAGE;
    
          //Wait for transmit complete
          while (!TI1);
    
          //Clear TI1 flag
          TI1 = 0;
    
          //Send character
          SBUF1 = l_c_txdata;
    
          g_us_tx1_ptr++;
       }
    
       //Restore the SFRPAGE
       SFRPAGE = SFRPAGE_SAVE;
    
       return l_c_txdata;
    }
    
    //-----------------------------------------------------------------------------
    // _getkey
    //-----------------------------------------------------------------------------
    //
    //
    // This routine overloads the standard _getkey() library function to support
    // either UART0 or UART1, depending on the state of the global variable <g_uc_uart>.
    //
    //-----------------------------------------------------------------------------
    
    char _getkey()
    {
       char c;
       char SFRPAGE_SAVE = SFRPAGE;
    
       if (g_uc_uart == 0)
       {
          SFRPAGE = UART0_PAGE;
    
          while (!RI0);      // Wait for byte to be received
          c = SBUF0;        // Read the byte
          RI0 = 0;
       }
    
       else if (g_uc_uart == 1)
       {
          SFRPAGE = UART1_PAGE;
    
          while (!RI1);       // Wait for byte to be received
          c = SBUF1;          // Read the byte
          RI1 = 0;
       }
    
       //Restore the SFRPAGE
       SFRPAGE = SFRPAGE_SAVE;
    
       return (c);
    }
    


    Hmmm.. if i have any wrong mistake in writing in transmission of the command, could you guide me where should i change?

    thanks

  • "First i store the command in the UART1 Buffer"

    Yes, you've shown that.

    "after that when it receive the command"

    What what "receives" the command?

  • After sending the command of the through the transmit untill my end of the command. i would wait for the GPS receiver to send me data through UART 1 where the receive flag anknowledge a "1". therefore i will read from the uC memory from the the UART rx buffer.

  • But you said, in your original post, that your problem is that nothing is sent!

  • today i did proble the transmit port from the uC and i could able to see the command send through oscillscope. At first, my guess was the transmit part got problem but i seems like not. I m totally lost about this because i not really sure where my problems lies at.

  • If you're lost when you have all the code and the hardware and all the information in front of you, how do you expect anyone else to know what's going on when we can't even see all of your code?!

    Where did the code come from? Presumably, you didn't write it yourself?
    Can you contact the original author?

    You seem to have basic problems with the operation of your buffered UART "driver".
    You really need to isolate that part and concentrate on understanding it and getting it working. The GPS unit and everything else are just unnessary distractions & complications at this point.