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/MSP430G2553: How to send a string over RX UART? I can send a character, but not a full string.

Part Number: MSP430G2553
Other Parts Discussed in Thread: LM35

Tool/software: Code Composer Studio

Hello TI forum. I've been working on a project that uses an LM35 thermal sensor and changes the speed of a fan (PWM) according to the current ADC10 value. Also, the error difference between the preset temperature value and the currently-read temperature value prints successfully to my PC using the program called CoolTerm over TX UART. However, I want to set the preset temperature value over RX UART as well, and the only way I can do that is to send commands that are more than one character long. In the code below, I have omitted around 100 lines of code to show the portions that control the data-sending through RX UART. When running my full code, entering something like r, R, g, G, 1, 2, 3, etc works perfectly. Can someone review my code and show me what needs to be changed to allow me to send a full string of characters before the UART code reacts? I'm pretty sure that the lines: 5, 26-34, 57, 83, are the lines that need reviewing.

Also as you can expect, how can I set the SETtemperror value to the number that I input from RX UART? For example, if I input Set Temp = 500, how can I translate the 500 string to an integer value for the line SETtemperror = (RX UART number string)? This will make my code simpler, instead of having case statements for every possible number input.

#include <msp430g2553.h>
#include <stdio.h>

/*** Initialize UART-Related Code ***/
static char data; 
void UARTSendArray(unsigned char *TxArray, unsigned char ArrayLength);
//Lots of function prototypes and global variables omitted.

/*** Initialize Temperature Variables ***/
int SETtemperror = 450;
//Lots of function prototypes and global variables omitted.

void init_uart() 
{
	P1SEL  = BIT1 + BIT2;	// P1.1 = RXD, P1.2 = TXD
	P1SEL2 = BIT1 + BIT2;	// P1.1 = RXD, P1.2 = TXD
	UCA0CTL1 |= UCSSEL_2;	// SMCLK
	UCA0BR0 = 104;			// see baud rate divider above
	UCA0BR1 = 0;
	UCA0MCTL = UCBRS0;		// modulation UCBRSx = 1
	UCA0CTL1 &= ~UCSWRST;	// ** initialize USCI state machine **
	IE2 |= UCA0TXIE;		// Enable USCI_A0 TX interrupt
}
//Lots of functions omitted.

void UARTSendArray(unsigned char *TxArray, unsigned char ArrayLength) 
{
    while(ArrayLength--) { // Loop until StringLength == 0 and post decrement
        while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for new data
        
        UCA0TXBUF = *TxArray; //Write the character at the location specified py the pointer
        TxArray++; //Increment the TxString pointer to point to the next character
    }
}

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    //Lots of peripherals omitted.
	
    for (;;)
    {
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
        current = ADC10MEM;
        error = previous - SETtemperror;   // Calculate error difference from preset temperature. abs() removed.
        IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
		
		//Lots of code omitted.
    }    

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    data = UCA0RXBUF;
    UARTSendArray("Received command: ", 18);
    UARTSendArray(&data, 1); //should be 14 characters long
    UARTSendArray("\n\r", 2);

    switch(data){
        case 'Set Temp = 450': {
            SETtemperror = 450;
        }
        break;
        case 'Set Temp = 475': {
            SETtemperror = 475;
        }
        break;
        case 'Set Temp = 490': {
            SETtemperror = 490;
        }
        break;
        case 'Set Temp = 500': {
            SETtemperror = 500;
        }
        break;
		case 'G': { //works fine
            SETtemperror = 500;
        }
        break;
        default: {
            UARTSendArray("Unknown Command: ", 17);
            UARTSendArray(&data, 1);
            UARTSendArray("\n\r", 2);
        }
        break;
    }
}

  • Since you only get one Rx character each time in the ISR, you need to save them somewhere outside the ISR (global). Declare a "command buffer" with an index, and each time a character comes in store it with something like "cmdbuf[cmdi++] = UCA0RXBUF;" (don't forget to check the buffer bounds). When you get a carriage return ('\r'), signal and wake up main() and have it process the command.

    To interpret a string as an integer, use strtoul(). If (for purposes of this experiment) you don't care about error-checking , you can use something like "value=strtoul(str,0,0);".

**Attention** This is a public forum