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.

settings for 9600 baud rate on MSP430

hello all,

 i am having trouble setting baud rate 9600 using 1MHz DCO frequency. i am not using the internal calibrated DCO settings. I am getting interrupts from my computer, however, the value that i send is in-correct, moreover, I get UCRXERR, UCPE,UCOE bit errors, can anyone please suggest what i am doing wrong.? chip used : MSP430F2xxx. i am confident that computer sends correct character, as the setup works with 32,768 ACLK and 9600 baud. however, i would like to reduce the error%, hence increasing baud rate

code:

void main()

{

UART_Init();

while(1)

{}

}

void UART_Init()
{
 
  P3SEL = ENABLE_UART_MODE;            //enable the USCI_A0 mode
  P3DIR = ASSIGN_UART_RX_TX;                // P3.4 = o/p, P3.5 = i/p
 
  Clock_1MHz();                             // Change the clock to 1MHz
 
  UCA0CTL1 |= UCSSEL_2;                     // CLK = SMCLK
  UCA0CTL0 = UCPEN;                         // ODD Priority
 
  UCA0BR0 = 112;                           // 1.078MHz/9600 = 112
  UCA0BR1 = 0x00;     
  UCA0MCTL = UCBRS2;                      // Modulation UCBRSx = 2
  //UCA0MCTL = 0X44;
 
 
   //end of init of registers//
   
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

}

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

void Clock_1MHz()
{
        IE1 &= ~(OFIE);                 //Disable OSC fault interrupt
        DCOCTL =  DCO1;      
        BCSCTL1 = XT2OFF | RSEL2 | RSEL1 | RSEL0;
        //BCSCTL1 = XT2OFF | 7;
        BCSCTL2 = 0x00u;                //MCLK=DCO; SMCLK = DCO
        __delay_cycles(100);
        
        IFG1 &= ~(OFIFG);               //Clear the OSC flag
        IE1 |= OFIE;                    //Enable OSC fault interrupt
}

  • I'm not familiar with the product you're using and still just learning to use the MSP430 myself, so this may be a bad suggestion --  but have you tried outputting SMCLK to a pin and looking at it with a 'scope? 

    Also, I think notes here suggest that it's a good idea to execute a

                    CLR.B &DCOCTL ; Select lowest DCOx

    at the start of your Clock-1MHz function.

  • Curt Carpenter said:
    I'm not familiar with the product you're using and still just learning to use the MSP430 myself, so this may be a bad suggestion --  but have you tried outputting SMCLK to a pin and looking at it with a 'scope? 

     Hi Curt, this is a good idea forever.

    Curt Carpenter said:

                    CLR.B &DCOCTL ; Select lowest DCOx

    at the start of your Clock-1MHz function.

     This one is of no use If calibrated data is used or DCO left at default, The routine set1MHz seem to do nothing necessary to set it @1MHz. Your suggestion is in assembly so coding in c languages 

    DCOCTL =0;

     But again calibration routine is needed.

     Regards

     Roberto

  • hello,

    i did test the freq on an oscilloscope using the settings i have mentioned, i observed freq of 1.15MHz...  the good part is i was able to perform some communication from MSP430 to the computer GUI over UART. however, I have observed few things;

    1. There happens an overflow error, RXERR,

    2. there is 1 particular TX interrupt which doesn't get transmitted from MSP to the GUI

    can anyone suggest any error checking algorithm/methods?

    also, i am erasing the info memory for my application purposes, hence will not be using the internal calibrated values for setting DCO.

  • Hello MSP430 Kors:

    Have you changed your code to reflect your measured clock frequency?

    Given the clock you observe on your scope, the statement

                    UCA0BR0 = 112; 

    in your code should be

                   UCA0BR0 = 120; 

    I think , since 1.15e6/9600 = 119.8.

    The troubles you are having seem related to timing to me. 


  • @Curt Carpenter, no, i haven't changed the UCA0BR0 register. As i said, i was successful in having few RX-TX transmissions, i thought my register values were correct....

    Later, i was confused whether I should be changing the clock freq/register values in order to remove this error ... never the less, i shall try out the new UCA0BR0 values... also, my problem is somewhat like this, when i send only 'A' from gui, i do not observe any overflow/RX-ERRORS, but when i send multiple characters, like 'ABCDEFG' i observe overflow/RX-ERROR...

    even though I am able to read all the characters in RX-buffer, I would like to write an efficient code which takes care of all these errors...  how can i write one/?

  • MSP430 Kors said:
    I would like to write an efficient code which takes care of all these errors

    An efficient code should rely on a calibrated base frequency. Using a manually measured and then hardcoded baudrate divider will fail as soon as you use a different chip of the same type. That's why there are those calibration values (so you don't have to calibrate every single chip on your own) ot the possibility to use an external crystal. (well, not on the G2 family, whcih doe snot allow high-frequency crystals).

    Overflow errors appear if you don't read the last received byte before the next one has arrived. Maybe because you stopped at a breakpoint? Stopping the CPU by the debugger doesn't stop the data coming in.

    Or it has to do with the fact that you do not enable interrupts at all. I see you set UC0RXIE, but I don't see you setting GIE (by __bis_SR_register(GIE) or __enable_interrupts() or EINT()).
    So the ISR is never called and on the second received byte you get an overflow error.

    A coding hint: "ENABLE_UART_MODE' and 'ASSIGN_UART_RX_TX' sound like operations, but are just values. I woudl expect something liek
    ENABLE_UART_MODE; or even ENABLE_UART_MODE(); and not an assignment. It's not an error, but a source for confusion if some (including yourself) reads the code later.

**Attention** This is a public forum