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 change Baud Rate Dynamically?

Hello,

           Is there a way to change the baud rate in UART dynamically? like initially, the baud shud be 9600, but after receiving a flag from COMPUTER, the baud rate should be set to 115k? i am using MSP430f2xxx

Thanks,

  • Hi,

     

    I think that you will appreciate to read this application note - Automatic Baud Rate Detection on the MSP430 (SLAA215).

     

    Best Regards,

    AES

  • You can change the baudrate at any time the same way you configured it initially. Set the SWRST bit, set the new baudrate divider and clear the SWRST bit.
    The UART will, however, be unable to detect an incoming start bit while SWRST is set. So the computer side should allow some delay for the change taking place and not immediately start sending with the new baudrate. This delay is short, but if there is an output FIFO or a (bundling) USB/serial converter, the delay should be long enough so that there is a gap between the command initiating the baudrate change and the byte that follows next with the new baudrate. Or wait, until the MSP responds with an ACK byte in the new baudrate.

    The auto baudrate detection, which is implemented into the USCI module, only works with a specific bit sequence. And this is most likely not supported by the computer side.

  • EXACTLY the answer i was looking and expected!!! thanks a bunch.. i shall make sure there is nothing coming from cmputer during this re-init

    thanks

  • hello, i tried implementing the dual baud rate, and i have problems.. the program is supposed to do this: initialize in 9600 baud, wait for a known char from GUI("D") and then, change the baud rate to 921600; send '@" as start of stream,  send 4 bytes of data followed by a "stop" string for the GUI to understand that data stream is over.

    if i put a break-point in 1 (mentioned below) things work exactly the way they are supposed to, however,  if i remove the breakpoint and run the s/w in realtime, then the program terminates and there is no transfer of data... i.e. the GUI never understands "@" value at its input and hence, it never stores the following 4 bytes of data...

    could there be a problem in GUI code or uCcode? please help

     

    /**********/

    /*****************************************************************************/
        // U A R T     M A I N  //
    /*****************************************************************************/


    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog
      UART_Init();
     
      __bis_SR_register(LPM0_bits + GIE);       // Enter LPM3, interrupts enabled

      Restart: 
      switch(Recvd_Char[0])
      {
     
        case 'D':                               // Memory Upload to PC
       
        UART_HighSpeed_Clk();
        ReadPage();
        Buffer_Index = 0;
        break;
            
        default:                                // Wait for known event
        Buffer_Index = 0;
        __bis_SR_register(LPM0_bits);
        goto Restart;
     
      }
     
    }

    /*****************************************************************************/
      // I N T E R R U P T      R O U T I N E //
    /*****************************************************************************/

      #pragma vector = USCIAB1RX_VECTOR
      __interrupt void USCI1RX_ISR(void)
      {
           Recvd_Char[Buffer_Index] = UCA1RXBUF;                    // Take Data from RX Buffer
           if(Recvd_Char[Buffer_Index] == 'Z')                      // check the end of data stream from LV
           {
              __bic_SR_register_on_exit(LPM0_bits);
           }
           else
            Buffer_Index++;
      }


    /*****************************************************************************/
      // U A R T   I N I T //
    /*****************************************************************************/
    void UART_Init()
    {
      // 9600 baud//
      P3OUT &= ~(BIT6+BIT7);
      P3SEL = 0xC0;                             // P3.6,7 = USCI_A1 TXD/RXD
      P3DIR = 0x40;                             // P3.6 = o/p, P3.7 = i/p

      UCA1CTL1 |= UCSSEL_1;                     // CLK = ACLK
     
      UCA1CTL0 = UCPEN;                         // ODD Priority
      UCA1BR0 = 0x03;                           // 32kHz/1200 = 27.3 -- set baud
      UCA1BR1 = 0x00;                           // modulation bits.. acc to datasheet
      UCA1MCTL = UCBRS1 + UCBRS0;                          // Modulation UCBRSx = 2
      //end of init of registers//
      
      UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      UC1IE |= UCA1RXIE;                        // Enable USCI_A1 RX interrupt
     
    }

    /*****************************************************************************/
      // R E A D   P A G E//
    /*****************************************************************************/
    void ReadPage()
    {
     
        while (!(UC1IFG & UCA1TXIFG));                 // USCI_A1 TX buffer ready?
        UCA1TXBUF = 0x40;                                      ------BREAKPOINT
      
        for(Read_Page_Index = 0; Read_Page_Index <1 ; Read_Page_Index++)
        {
          while (!(UC1IFG & UCA1TXIFG));
          UCA1TXBUF = 0x50;
          while (!(UC1IFG & UCA1TXIFG));
          UCA1TXBUF = 0x51;
          while (!(UC1IFG & UCA1TXIFG));
          UCA1TXBUF = 0x52;
          while (!(UC1IFG & UCA1TXIFG));
          UCA1TXBUF = 0x53;
        }

        __delay_cycles(10);
      while (!(UC1IFG & UCA1TXIFG));                //send 'S'
      UCA1TXBUF = 0x53;
       
      while (!(UC1IFG & UCA1TXIFG));               //send 't'
      UCA1TXBUF = 0x74;
     
      while (!(UC1IFG & UCA1TXIFG));               //send '~'
      UCA1TXBUF = 0x7E;
     
      while (!(UC1IFG & UCA1TXIFG));              //send 'P'
      UCA1TXBUF = 0x50;
     
    }


    /*****************************************************************************/
      // U A R T    H I G H - S P E E D    C L K//
    /*****************************************************************************/
    void UART_HighSpeed_Clk()
    {
      if (CALBC1_16MHZ ==0xFF || CALDCO_16MHZ == 0xFF)                                    
      { 
         while(1);                                // If calibration constants erased
                                                  // do not load, trap CPU!!
      } 
     
      UCA1CTL1 |= UCSWRST;                        // reset the USCI model for high speed data clk
     
      BCSCTL1 = CALBC1_16MHZ;                     // Set DCO to 16MHz
      DCOCTL = CALDCO_16MHZ;
      
      BCSCTL2 = 0x00;                             // divider=4 for SMCLK and MCLK
     
      UCA1CTL0 = UCPEN;                           // ODD Priority
      UCA1CTL1 |= UCSSEL_3;                       // CLK = SMCLK

      UCA1BR0 = 0x11;                             // 16MHz clock 921600bps
      UCA1BR1 = 0x00;
      UCA1MCTL = 0x52;                            // UCBRS_6;
     
      UCA1CTL1 &= ~UCSWRST;                     // **Re-Initialize USCI state machine**
      UC1IE |= UCA1RXIE;                        // Enable USCI_A1 RX interrupt
    }

  • I don't see anything obviously wrong with your code. so what i guess is: the PC is too slow :)

    Switching from 9600Bd to 1MBd is done in a few microseconds. And TXBUF is immediately ready for transfer. The transfer of the five bytes takes only 50/921600s = 54 microseconds. Whic hi smuch less than one 9600Bd bit length.
    Does the PC switch from 9600 to 921600Bd in 54 microseconds? I guess not - with all this driver call stuff overhead you have in a typical windows environment. I think that the call for sending the 'D' has just returned in this time.

    If you place a breakpoint that is triggered right before the @ is sent, the PC has time to switch the baudrate.

    So It's not the MSP that needs to signal that it is ready, it's the PC that has to signal that it is ready too.

    Suggestion: wait for the PC sending a 'ping' byte and respond to it when received.

    PC: @ (MSP not ready)
    PC: delay
    PC: @ (MSP received it)
    MSP: $  + data.
    PC: @ (didn't see the $ yet)
    MSP ignores incoming @
    PC: detects $, discards itstops sending @ and starts receiving further data

    This way (or similar) it is ensured that both know that the other one is ready. Also, any overlap/race condition caused by drivers and FIFOs is eliminated.

  • Hello, i figured what the problem was.. it was in the pc code.. the baud rate was switching from 9600 to 921600 after every 1 byte of transfer... hence it was showing such problems... but now i changed that and things seem to be working well.. thanks..

**Attention** This is a public forum