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.

CCS/MSP430FR2353: CCS/MSP430FR2353

Part Number: MSP430FR2353
Other Parts Discussed in Thread: MSP430FR2355

Tool/software: Code Composer Studio

I am able to send a single characters but I want to send the strings of characters like "AMIT" to RealTerm with the help of this programs.I just want to know what kind of modification is required to send strings in this program (MSP430FR2355):-

#include <msp430.h>

void Software_Trim(); // Software Trim to get the best DCOFTRIM value
#define MCLK_FREQ_MHZ 1 // MCLK = 1MHz

unsigned char RXData = 0;
unsigned char TXData ='A';

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

__bis_SR_register(SCG0); // Disable FLL
CSCTL3 = SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_0;// DCOFTRIM=3, DCO Range = 1MHz
CSCTL2 = FLLD_0 + 30; // DCODIV = 1MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // Enable FLL
Software_Trim(); // Software Trim to get the best DCOFTRIM value
CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
// default DCODIV as MCLK and SMCLK source

PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
P1DIR |= BIT0;
P1OUT &= ~BIT0; // P1.0 out low

// Configure UART pins
P1SEL0 |= BIT6 | BIT7; // set 2-UART pin as second function

// Configure UART
UCA0CTLW0 |= UCSWRST; // Put eUSCI in reset
UCA0CTLW0 |= UCSSEL__SMCLK;
// Baud Rate calculation
UCA0BR0 = 8; // 1000000/115200 = 8.68
UCA0MCTLW = 0xD600; // 1000000/115200 - INT(1000000/115200)=0.68
// UCBRSx value = 0xD6 (See UG)
UCA0BR1 = 0;
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt

while (1)
{
while(!(UCA0IFG & UCTXIFG));
UCA0TXBUF = TXData; // Load data onto buffer

__bis_SR_register(LPM0_bits|GIE); // Enter LPM0
__no_operation(); // For debugger
}
}

void Software_Trim()
{
unsigned int oldDcoTap = 0xffff;
unsigned int newDcoTap = 0xffff;
unsigned int newDcoDelta = 0xffff;
unsigned int bestDcoDelta = 0xffff;
unsigned int csCtl0Copy = 0;
unsigned int csCtl1Copy = 0;
unsigned int csCtl0Read = 0;
unsigned int csCtl1Read = 0;
unsigned int dcoFreqTrim = 3;
unsigned char endLoop = 0;

do
{
CSCTL0 = 0x100; // DCO Tap = 256
do
{
CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
}while (CSCTL7 & DCOFFG); // Test DCO fault flag

__delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
// Suggest to wait 24 cycles of divided FLL reference clock
while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));

csCtl0Read = CSCTL0; // Read CSCTL0
csCtl1Read = CSCTL1; // Read CSCTL1

oldDcoTap = newDcoTap; // Record DCOTAP value of last time
newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value

if(newDcoTap < 256) // DCOTAP < 256
{
newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim--;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}
else // DCOTAP >= 256
{
newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
if(oldDcoTap < 256) // DCOTAP cross 256
endLoop = 1; // Stop while loop
else
{
dcoFreqTrim++;
CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
}
}

if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
{
csCtl0Copy = csCtl0Read;
csCtl1Copy = csCtl1Read;
bestDcoDelta = newDcoDelta;
}

}while(endLoop == 0); // Poll until endLoop == 1

CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
UCA0IFG &=~ UCRXIFG; // Clear interrupt
RXData = UCA0RXBUF; // Clear buffer
if(RXData != TXData) // Check value
{
P1OUT |= BIT0; // If incorrect turn on P1.0
while(1); // trap CPU
}
TXData++; // increment data byte
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
break;
case USCI_UART_UCTXIFG: break;
case USCI_UART_UCSTTIFG: break;
case USCI_UART_UCTXCPTIFG: break;
}
}

  • Hi Amit,
    as you see in your code example you're initializing TXData with "A". This is the character which is pushed into the UCA0TXBUF once the flag indicates the buffer being ready for another data transmission. In case of data reception the TXData would be incremented and thus the device would transmit the next higher character. As TXData is not changed on other instances, without receiving a byte the while 1 would transmit permanently a single "A".
    If you want to transmit a sequence of characters, one possibility would be using instead of char TXData and char array, where the array would be consisting of the characters you intend to transmit, like in your case "AMIT", so TXData[0] = 'A', TXData[1]='M' and so on. Then in the while(1) in main in the TX instruction you need to increment the pointer of TXData[i] pushing instead of TXData TXData[i] into UCA0TXBUF. Once the 4th character is reached you need to reset the pointer i to 0 and restart again with TXData[0]. This way you'l be transmitting "AMITAMITAMIT....."

    Best regards
    Peter
  • Hello Amit,
    could you please let us know about the status of your problem? Were you able to solve it? If you need further support on this please let us know. In case not, please close the thread. Many thanks in advance.

    Best regards
    Peter
  • Whenever I send strings with the help of this program,I wont get whole string on the RealTerm.eg When I try to send GANESHA strings then I got  only GSA .So please try to help me regarding this problem and tell me where I am making mistake in this program and also give me solutions because I am absolutely  new in this field of embedded systems and programming


    #include <msp430.h>

    void Software_Trim(); // Software Trim to get the best DCOFTRIM value
    #define MCLK_FREQ_MHZ 1 // MCLK = 1MHz
    unsigned int i;
    unsigned char TXData []= {"GANESHA"};

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

    __bis_SR_register(SCG0); // Disable FLL
    CSCTL3 = SELREF__REFOCLK; // Set REFO as FLL reference source
    CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_0;// DCOFTRIM=3, DCO Range = 1MHz
    CSCTL2 = FLLD_0 + 30; // DCODIV = 1MHz
    __delay_cycles(3);
    __bic_SR_register(SCG0); // Enable FLL
    Software_Trim(); // Software Trim to get the best DCOFTRIM value
    CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
    // default DCODIV as MCLK and SMCLK source

    PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
    // to activate previously configured port settings
    P1DIR |= BIT0;
    P1OUT &= ~BIT0; // P1.0 out low

    // Configure UART pins
    P1SEL0 |= BIT6 | BIT7; // set 2-UART pin as second function

    // Configure UART
    UCA0CTLW0 |= UCSWRST; // Put eUSCI in reset
    UCA0CTLW0 |= UCSSEL__SMCLK;
    // Baud Rate calculation
    UCA0BR0 = 8; // 1000000/115200 = 8.68
    UCA0MCTLW = 0xD600; // 1000000/115200 - INT(1000000/115200)=0.68
    // UCBRSx value = 0xD6 (See UG)
    UCA0BR1 = 0;
    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
    UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt

    while (1)
    {
    while(!(UCA0IFG & UCTXIFG));
    for(i=0;i<=6;i++)
    {
    UCA0TXBUF = TXData[i];// Load data onto buffer
    }

    __bis_SR_register(LPM0_bits|GIE); // Enter LPM0
    __no_operation(); // For debugger
    }
    }

    void Software_Trim()
    {
    unsigned int oldDcoTap = 0xffff;
    unsigned int newDcoTap = 0xffff;
    unsigned int newDcoDelta = 0xffff;
    unsigned int bestDcoDelta = 0xffff;
    unsigned int csCtl0Copy = 0;
    unsigned int csCtl1Copy = 0;
    unsigned int csCtl0Read = 0;
    unsigned int csCtl1Read = 0;
    unsigned int dcoFreqTrim = 3;
    unsigned char endLoop = 0;

    do
    {
    CSCTL0 = 0x100; // DCO Tap = 256
    do
    {
    CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
    }while (CSCTL7 & DCOFFG); // Test DCO fault flag

    __delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
    // Suggest to wait 24 cycles of divided FLL reference clock
    while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));

    csCtl0Read = CSCTL0; // Read CSCTL0
    csCtl1Read = CSCTL1; // Read CSCTL1

    oldDcoTap = newDcoTap; // Record DCOTAP value of last time
    newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
    dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value

    if(newDcoTap < 256) // DCOTAP < 256
    {
    newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
    if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
    endLoop = 1; // Stop while loop
    else
    {
    dcoFreqTrim--;
    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
    }
    }
    else // DCOTAP >= 256
    {
    newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
    if(oldDcoTap < 256) // DCOTAP cross 256
    endLoop = 1; // Stop while loop
    else
    {
    dcoFreqTrim++;
    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
    }
    }

    if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
    {
    csCtl0Copy = csCtl0Read;
    csCtl1Copy = csCtl1Read;
    bestDcoDelta = newDcoDelta;
    }

    }while(endLoop == 0); // Poll until endLoop == 1

    CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
    CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
    while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:
    UCA0TXBUF=UCA0RXBUF;
    UCA0IFG &=~ UCRXIFG; // Clear interrupt
    __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
    break;
    case USCI_UART_UCTXIFG: break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG: break;
    }
    }

  • Hi Amit,
    the reason, why you're experiencing this behavior is related to this instruction sequence of yours:
    while(!(UCA0IFG & UCTXIFG));
    for(i=0;i<=6;i++)
    {
    UCA0TXBUF = TXData[i];// Load data onto buffer
    }

    The function of "while(!(UCA0IFG & UCTXIFG)); " is to prevent loading the TX buffer, before it is ready to transmit the next character. So with the given instruction sequence you wait for the first time, but then with the "for" loop you push the following characters in a burst without waiting, but as fast as the CPU manages loading the TX buffer. So you need to put the wait on the buffer into your "for" loop, like e.g.
    for(i=0;i<=6;i++)
    {
    while(!(UCA0IFG & UCTXIFG));
    UCA0TXBUF = TXData[i];// Load data onto buffer
    }
    This way, the CPU will wait, before pushing the next character into the TX buffer, until the previous has been transmitted.
    As in your case you're pushing data too fast, some of the characters are being skipped, as you push multiple times, before the UART module is able to transmit the previous.
    With this change the code should solve this problem.

    Best regards
    Peter
  • Thanks for your help and support and because of you I solved my problems .Could you suggest me how could I send ADC Result to RealTerm:

    #include <msp430.h>
    void init_uart();                                               //Initilize UART Serial Communication
    unsigned int ADC_Result;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
    
        // Configure GPIO
        P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
        P1OUT &= ~BIT0;                                          // P1.0 LED off
    
        // Configure ADC A1 pin
        P1SEL0 |= BIT1;
        P1SEL1 |= BIT1;
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        // Configure ADC12
        ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks
        ADCCTL1 |= ADCSHP;                                       // ADCCLK = MODOSC; sampling timer
        ADCCTL2 &= ~ADCRES;                                      // clear ADCRES in ADCCTL
        ADCCTL2 |= ADCRES_2;                                     // 12-bit conversion results
        ADCMCTL0 |= ADCINCH_1;                                   // A1 ADC input select; Vref=AVCC
        ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt
        while(1)
        {
            while(ADCCTL1 & ADCBUSY);                                // Wait if ADC core is active
            ADCCTL0 |= ADCENC | ADCSC;                           // Sampling and conversion start
            __bis_SR_register(LPM0_bits | GIE);                  // LPM0, ADC_ISR will force exit
            __no_operation();                                    // For debug only
            while (!(UCA0IFG & UCTXIFG));          // wait for USCI_A0 TX buffer to ready
            UCA0TXBUF=ADC_Result;
            if (ADC_Result < 0x7FF)
                P1OUT &= ~BIT0;                                  // Clear P1.0 LED off
            else
                P1OUT |= BIT0;                                   // Set P1.0 LED on
            __delay_cycles(5000);
        }
    }
    void init_uart()
    {
        // Configure UART pins
        P1SEL0 |= BIT6 | BIT7;                    // set 2-UART pin as second function
        // Configure UART
        UCA0CTLW0 |= UCSWRST;                     //Sets softare reset enable
        UCA0CTLW0 |= UCSSEL__SMCLK;               // Set SMCLK as BRCLK to be used for baud rate of 115200
                                                 // Baud Rate calculation. Setting BaudRate to 115200
        UCA0BR0 = 8;                              // 1000000/115200 = 8.68 INT(N) = 8
        UCA0MCTLW = 0xD600;                       // 1000000/115200 - INT(1000000/115200)=0.68
        UCA0BR1 = 0x00;                              // UCBRSx value = 0xD6
        UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
    }
    
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
        {
            case ADCIV_NONE:
                break;
            case ADCIV_ADCOVIFG:
                break;
            case ADCIV_ADCTOVIFG:
                break;
            case ADCIV_ADCHIIFG:
                break;
            case ADCIV_ADCLOIFG:
                break;
            case ADCIV_ADCINIFG:
                ADC_Result = ADCMEM0;
                __bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from LPM0
                break;
            default:
                break;
        }
    }
    

    Where I am making mistakes in this program and please resolved my issues like previous time.

    Again thanks for ur support and help.

  • Now I am able to send ADC data to RealTerm with the help of this code:-

    #include <msp430.h>
    void init_uart();
    unsigned  long int ADC_Result;
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
        init_uart();
        // Configure GPIO
        P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
        P1OUT &= ~BIT0;                                          // P1.0 LED off
    
        // Configure ADC A1 pin
        P1SEL0 |= BIT1;
        P1SEL1 |= BIT1;
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        // Configure ADC12
        ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks
        ADCCTL1 |= ADCSHP;                                       // ADCCLK = MODOSC; sampling timer
        ADCCTL2 &= ~ADCRES;                                      // clear ADCRES in ADCCTL
        ADCCTL2 |= ADCRES_2;                                     // 12-bit conversion results
        ADCMCTL0 |= ADCINCH_1;                                   // A1 ADC input select; Vref=AVCC
        ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt
    
        while(1)
        {
         while(ADCCTL1 & ADCBUSY);                                // Wait if ADC core is active
         ADCCTL0 |= ADCENC | ADCSC;                           // Sampling and conversion start
         __bis_SR_register(LPM0_bits | GIE);                  // LPM0, ADC_ISR will force exit
         __no_operation(); // For debug only
         while (!(UCA0IFG & UCTXIFG));          // wait for USCI_A0 TX buffer to ready
         UCA0TXBUF=ADC_Result;
         if (ADC_Result < 0x7FF)
            P1OUT &= ~BIT0;                                  // Clear P1.0 LED off
         else
            P1OUT |= BIT0;                                   // Set P1.0 LED on
         __delay_cycles(5000);
        }
    }
    void init_uart()
    {
        // Configure UART pins
        P1SEL0 |= BIT6 | BIT7;                    // set 2-UART pin as second function
        // Configure UART
        UCA0CTLW0 |= UCSWRST;                     //Sets softare reset enable
        UCA0CTLW0 |= UCSSEL__SMCLK;               // Set SMCLK as BRCLK to be used for baud rate of 115200
                                                 // Baud Rate calculation. Setting BaudRate to 115200
        UCA0BR0 = 8;                              // 1000000/115200 = 8.68 INT(N) = 8
        UCA0MCTLW = 0xD600;                       // 1000000/115200 - INT(1000000/115200)=0.68
        UCA0BR1 = 0x00;                              // UCBRSx value = 0xD6
        UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
    }
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
        {
            case ADCIV_NONE:
                break;
            case ADCIV_ADCOVIFG:
                break;
            case ADCIV_ADCTOVIFG:
                break;
            case ADCIV_ADCHIIFG:
                break;
            case ADCIV_ADCLOIFG:
                break;
            case ADCIV_ADCINIFG:
                break;
            case ADCIV_ADCIFG:
                ADC_Result = ADCMEM0;
                __bic_SR_register_on_exit(LPM0_bits);            // Clear CPUOFF bit from LPM0
                break;
            default:
                break;
        }
    }
    

    But I want to plot ADC data In excel in column and since this program has 12 bit resolution but I am still getting 8 bit data not 12 bit.Where I am making mistake in the program.Please give me suggestion and advice.

  • Hi Amit,

    I understand, that from your point of view all this belongs to one project of yours, but this is not related to one and the same specific problem, but moving from one to another. Our strategy is to deal with each specific problem separately. to make ti easier for other users searching the forum for the resolution of similar problems on their side.

    So would you please set this up as a separate thread, describing the new problem you're facing, and close this for the initial problem? Many thanks in advance.

    Best regards

    Peter