MSP430F5529 baud rate problem

Thread Starter

Hiril Patel

Joined Dec 25, 2021
31
Hello Experts,

I am working on 24 bit adc with 1ksps rate. My problem is divided into two parts here:

1. I am sending data at 115200 BPS successfully but I wish to increase its 460800 for assurance(of not having any data loss). Now I have read the data sheet and used couple of baud rate calculators but it seem what I get in the terminal is complete garbage also I used PICOSCOPE to monitor UART signal form MCU but again there was no data I coud interprette. Can someone help me with fixing this issue of changing baudrate?

2. I have written code for get data from ADC via SPI and then transferring it to PC via UART but for some reason the UART only works properly(I get meaningful data) when I add delay of 1000 cycle after each 8 bit transactions. Due to this delay my overall sample rate of ADC get hurt significantly.For eg I am scanning 4 channel of my ADC at 1000 sps(so practically I get 250 SPS for each channel) and plus the delay of 1000 cycles in mcu. so on 1 hZ sin wave I roughly get 50 data points( i should get 250, right?). SO can someone help me with removing delay of 1000 cycles from my programss

by the way I am using ADS1220 as ADC.

Here is the code the delay you can find on line 19
Code:
#include <msp430.h>
#include "ADS1220.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "BCUart.h"

unsigned int j = 0x00;
unsigned int i;
int channel;
/*variable to store single smaple read from adc*/
volatile long adc_value1;
static void putDataToUart(uint8_t byte);
static void putDataToUart(uint8_t byte){
    while (!(UCA0IFG&UCTXIFG));   // USCI_A0 TX buffer ready?
    UCA0TXBUF = byte;
    __delay_cycles(1000);    <---------------------------------------------------------- THIS DELAY
    //while (!(UCA0IFG&UCTXIFG));   // USCI_A0 TX buffer ready?

}

int main(void)
{
  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

//******************SPI****************************//
  P3SEL |= BIT0+BIT1+BIT2;                       // P3.3,4 option select
  UCB0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCB0CTL0 |= UCSYNC+UCMSB+UCMST;          // 3-pin, 8-bit SPI Master, MSB
  UCB0CTL1 |= UCSSEL_2;                    // SMCLK 16Mhz
  UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

  //***************UART********************//

  P3SEL |= BIT3+BIT4;                       // P3.3,4 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 34;                              // 1MHz 115200 (see User's Guide)
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL |= UCBRS_6 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

//*************************ADS1220*******************************//

  ADS1220Init();
  ADS1220Config();
//  ADS1220SetClockMode(ADS1220_MODE_TURBO);
  ADS1220SetPGABypass(ADS1220_PGA_BYPASS);
  ADS1220SetVoltageReference(ADS1220_VREF_SUPPLY);
  __delay_cycles(1000);
  ADS1220SendStartCommand();
  channel |= 0;
  volatile uint8_t tmp = 0;
  __delay_cycles(1000);

   int channels[4] = {ADS1220_MUX_0_G, ADS1220_MUX_1_G, ADS1220_MUX_2_G, ADS1220_MUX_3_G};
   int crChannel = 0;

while(1)
     {

     ADS1220SetChannel(channels[crChannel]);
   //  ADS1220SetPGABypass(ADS1220_PGA_BYPASS);

     ADS1220SendStartCommand();

     while(0 != P2IN & BIT6);
     adc_value1 = ADS1220ReadData();
     uint8_t tmp = ((adc_value1 >> 24) & 0xff);
     //uint8_t tmp = crChannel;
     /*put the first byte to Uart*/
     putDataToUart(tmp);

     /*prepare the third byte data*/
     tmp = ((adc_value1 >> 16) & 0xff);
     /*put the first byte to Uart*/
     putDataToUart(tmp);

     /*prepare the second byte data*/
     tmp = ((adc_value1 >> 8) & 0xff);
     /*put the first byte to Uart*/
     putDataToUart(tmp);

     /*prepare the first byte data*/
     tmp =  (uint8_t )(adc_value1 & 0x000000FF);
     /*put the first byte to Uart*/
     putDataToUart(tmp);
     j = 2;
/*
*adc                 index

*ch0                   ch1
*ch1                   ch2
*ch2                   ch3
*ch3                   ch0
*/
     if(crChannel == 3)
          {
              while (!(UCA0IFG&UCTXIFG));   // USCI_A0 TX buffer ready?
              UCA0TXBUF = 0x2F;
             // __delay_cycles(1000);
              while (!(UCA0IFG&UCTXIFG));   // USCI_A0 TX buffer ready?
              UCA0TXBUF = 0x41;
              //__delay_cycles(1000);
              while (!(UCA0IFG&UCTXIFG));   // USCI_A0 TX buffer ready?
              UCA0TXBUF = 0x2F;
              //__delay_cycles(1000);
          }
             crChannel += 1;
             crChannel %= 4;
     }
}
 

MrChips

Joined Oct 2, 2009
30,707
When testing UART serial communications for the first time I like to use a low baud such as 9600 and a known single character 'U' which is 0x55. Use a delay of about 1ms between transmissions so that you can examine the waveform on the oscilloscope. Set up the receiving end to observe the correct character 'U' received.

Look at the shape of the waveform and measure the bit width and rising and falling edges.
When you are satisfied with the waveform, try increasing the baud gradually until you can get satisfactory results at your target baud.

At higher baud, the clock divider used becomes more critical. You will get deviation from the perfect baud because of truncation in integer division. It would help if both transmitter and receiver used the same crystal frequency (or with integer ratios) in which case there should be zero error in the UART frequencies. In other words, find out what crystal frequency is used on the PC UART and select your MCU crystal to match.
 

Thread Starter

Hiril Patel

Joined Dec 25, 2021
31
Hello,, seems like the problem was entierly based on MSP430 UART here, I didn't specifically tested this since I had no access to oscillosope this week. I can tell that MSP430 was culprit because I tested the same circuit with arduino uno(without any delay) with same baud rate and it worked just fine. But I couldn't understand need of delay in MSP430 after uart.
 

MrChips

Joined Oct 2, 2009
30,707
Hello,, seems like the problem was entierly based on MSP430 UART here, I didn't specifically tested this since I had no access to oscillosope this week. I can tell that MSP430 was culprit because I tested the same circuit with arduino uno(without any delay) with same baud rate and it worked just fine. But I couldn't understand need of delay in MSP430 after uart.
Don't be too quick to put the blame on the MSP430. It would appear that the MSP430 sending serial data via a UART at 460800 is too fast for the receiver.

You cannot achieve consistent ADC sampling rates with the UART in the loop. You need to take samples and store them in a circular buffer.
 

Thread Starter

Hiril Patel

Joined Dec 25, 2021
31
can you give me with a rough example code here, maybe point out what could be done in my code? And yes Msp430 may be putting out data at 460800 but the problem is there are no example avaialble to configure the baudrate for msp430(as far as I could find) so i sticked with goodold 115200 bps which I can see on any terminal and python. But still there is need for delay after each byte send in msp430 to pc
 

Thread Starter

Hiril Patel

Joined Dec 25, 2021
31
What is the crystal frequency on your MSP430F5529?

The table on pages 952-954 of the MSP430x5xx User's Guide will show typical % errors for different clock frequencies and baud rates.
HEllo,

I never checked its current frequency, I am new with programming and I dealt with what was only needed to do my job( sorry for being ignorant)

Yes I already checked that and I tried to find how to change the clock frequency( there is no examples to see how to do it), however I found something which I don't know if this changes the frequency of the clock but here it is:


Code:
/* --COPYRIGHT--,BSD_EX
 * Copyright (c) 2012, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************
 *
 *                       MSP430 CODE EXAMPLE DISCLAIMER
 *
 * MSP430 code examples are self-contained low-level programs that typically
 * demonstrate a single peripheral function or device feature in a highly
 * concise manner. For this the code may rely on the device's power-on default
 * register values and settings such as the clock configuration and care must
 * be taken when combining code from several examples to avoid potential side
 * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
 * for an API functional library-approach to peripheral configuration.
 *
 * --/COPYRIGHT--*/
//******************************************************************************
//   MSP430F552x Demo - Software Toggle P1.1 with 12MHz DCO
//
//   Description: Toggle P1.1 by xor'ing P1.1 inside of a software loop.
//   ACLK is rought out on pin P1.0, SMCLK is brought out on P2.2, and MCLK
//   is brought out on pin P7.7.
//   ACLK = REFO = 32kHz, MCLK = SMCLK = 12MHz
//
//                 MSP430F552x
//             -----------------
//         /|\|                 |
//          | |             P1.0|-->ACLK
//          --|RST          P7.7|-->MCLK
//            |             P2.2|-->SMCLK
//            |                 |
//            |             P1.1|-->Port Pin
//
//   Bhargavi Nisarga
//   Texas Instruments Inc.
//   April 2009
//   Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************
#include <msp430.h>

int main(void)
{
  volatile unsigned int i;

  WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
  P1DIR |= BIT1;                            // P1.1 output

  P1DIR |= BIT0;                            // ACLK set out to pins
  P1SEL |= BIT0;                           
  P2DIR |= BIT2;                            // SMCLK set out to pins
  P2SEL |= BIT2;                           
  P7DIR |= BIT7;                            // MCLK set out to pins
  P7SEL |= BIT7;

  UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
  UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_5;                      // Select DCO range 24MHz operation
  UCSCTL2 = FLLD_1 + 374;                   // Set DCO Multiplier for 12MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (374 + 1) * 32768 = 12MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
  __delay_cycles(375000);
    
  // Loop until XT1,XT2 & DCO fault flag is cleared
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
  while(1)
  {
    P1OUT ^= BIT1;                          // Toggle P1.1
    __delay_cycles(600000);                 // Delay
  }
}

So I tried putting oscilloscope on the pin and it was it 12mhz. after that I tried to change the baud rate using these settings:
Code:
    UCA1CTL1 |= UCSWRST;        // Put the USCI state machine in reset
    UCA1CTL1 |= UCSSEL__SMCLK;  // Use SMCLK as the bit clock

    // Set the baudrate
    UCA1BR0 = UCA1_BR0;
    UCA1BR1 = UCA1_BR1;
    UCA1BR0 = 26;                              // 1MHz 115200 (see User's Guide)
    UCA1BR1 = 0;                              // 1MHz 115200
    UCA1MCTL |= UCBRS_0 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
according to follwoing values from datasheet:
baud rate settings.JPG

But I didn't get anything out of it(it was a week ago, i don't remeber the output of uart but all I know was it didn't work)


Pleasse tell me what I should do.
 

sagor

Joined Mar 10, 2019
903
If you are "almost" making it at that high baud rate, try making it run with 2 stop bits instead of 1. That gives a 1 bit "delay" between characters without the need for extra delay programming.
 

Thread Starter

Hiril Patel

Joined Dec 25, 2021
31
If you are "almost" making it at that high baud rate, try making it run with 2 stop bits instead of 1. That gives a 1 bit "delay" between characters without the need for extra delay programming.
Ok apart from not getting what i intend to do, i have question from your suggestion here

If i do 2 stopbits from transmission side, should i set 1 stop bit on receiving side or 2 stops? Receiving do need delays in order to work properly?
 

MrChips

Joined Oct 2, 2009
30,707
Ok apart from not getting what i intend to do, i have question from your suggestion here

If i do 2 stopbits from transmission side, should i set 1 stop bit on receiving side or 2 stops? Receiving do need delays in order to work properly?
It is the transmitter that is laying down the rules. The receiver has to keep up.
You can set the transmitter to 2 stop bits and the receiver to 1 stop bit.
 
Top