This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to send a string via serial port?

I have the following codes to send one single character via serial port and hear back from the device.

     if(!(IFG2&UCA1RXIFG)  )
      {
     

      DelayMs(100);
   
      if (UCA1RXBUF == '1'  ) 
       
      { 
        
                 DelayMs(1000);
              UCA1TXBUF = '\n';
               DelayMs(1000);
                UCA1TXBUF = '\r';
               DelayMs(1000);
              UCA1TXBUF = '@';
            
      
      }
     
      }
       
    

So as you can see, if you send 1 via serial port, you well get the character "@". Now, I would like to know how I can send two digits let's say 12 to get the same character back?

if I write 

if (UCA1RXBUF == '1'  ) 
       
      { 
  if (UCA1RXBUF == '2'  ) 
       
      { 

does not work. Because there is not enough time to get the second digit. And even with enough delay is too hard to get the second one. So, is there any solution for this? Any idea on that?

Thanks!
  • You need a while loop to wait on the UCA1RXIFG flag being active again.

    if(!(IFG2&UCA1RXIFG)  )
    {
      // If you got the flag, why are you waiting 100ms?
      DelayMs(100);
       
      if (UCA1RXBUF == '1'  ) 
      { 
        while(!(IFG2&UCA1RXIFG)) {;} // wait for next RX-ready IFG
        if (UCA1RXBUF == '2'  ) 
        { 
          UCA1TXBUF = '\n';
          // This is better way to wait for ok to send next char:
          while(!(IFG2&UCA1TXIFG)){;}
          UCA1TXBUF = '\r';
          while(!(IFG2&UCA1TXIFG)){;}
          UCA1TXBUF = '@';
        }
      }
    }
    

  • Brian, Thanks for reminding me using the While loop instead of for loop. However, don't you think if I use the while it interrupts other jobs to be processed? This small portion of the code is part of a huge code. It just needs to see 12 and sends me @ and gets back to what it was doing.
    I put delay because I noticed that there was not enough time to get '1'. I am using break-point to see what the problem is! I will keep you update soon again!
  • No while-loop inside an ISR. But you could use a state-machine in your ISR that sets a flag when something special has been received, or when a specific number of bytes were received. The processing can be done in the main() then.

    Edit: I think I misunderstood your response. But yes, it interrupts the program until something is received again. That is what interrupts are for. Save the data in the interrupt and use flags to process them in the main().

    Dennis

  • Denis, I used Brian's code. There must be something to modified. It does not get 12 at all!
  • However, the following code works.

          
           if(!(IFG2&UCA1RXIFG)  )
    {
      
       
      while (UCA1RXBUF == '1'  ) 
      { 
       
        if (UCA1RXBUF == '2'  ) 
        { 
          UCA1TXBUF = '\n';
          
          UCA1TXBUF = '\r';
          DelayMs(100);
          UCA1TXBUF = '@';
        }
      }
    }
        

    But, sometimes not! :(

  • I think Brian has a typo in the first line:

    if( !(IFG2 & UCA1RXIFG) )

    should be

    if( IFG2 & UCA1RXIFG )
  • The way you changed it now is humbug. This will be coincidence if it works.
  • Doh! I copied and pasted CA's code as an initial start.

    I didn't actually test that code, but the general idea is there and CA should be able to take that as a starting point for a polled-mode checking loop.

    One thing to consider is that it will wait forever if a '2' never comes in from the terminal. So may want to consider adding a timeout feature.
  • Sorry, CA's Code?! What is that?

    Yes, like break or jump!
  • CaEngineer said:
    Sorry, CA's Code?! What is that?

    CA == you. Because I'm being too lazy to type out your whole username. "CA's code" == your code from your OP (original post) that I copied/pasted into the editor to draft my reply with.

  • Oh Understood Brian! Thanks!
  • " while (UCA1RXBUF == '1' )
    {
    if (UCA1RXBUF == '2' ) "

    This will work only by coincidence.
    If '2' is received before the while is checked, the code won't go to the IF. If it is received right after the IF test, it also won't respond.
    If you have a two-letter code, then you can use two global variables, lastbyte and currentbyte.
    When you receive a byte, currentbyte is moved into lastbyte, and the freshly received byte goes into currentbyte. Then you can check whether lastbyte is 1 and currentbyte is 2.
    BTW: usually, \r is sent before \n. And between two writes to TXBUF, you should check for RXIFG, to see whether TXBUF is ready for the next byte. Else you're overwriting the previous write before it is sent.

**Attention** This is a public forum