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.

msp430g2553 send string by uart

Other Parts Discussed in Thread: MSP430G2553

         Hi, everyone , I want to transmit many strings to my computer super terminal by msp430g2553,  I can send and receive data with TI example code (“msp430g2xx3_uscia0_uart_06_9600),but it sends one string to PC by UART. I want to make subroutine to send many string ,  my code:

#include "msp430g2553.h"
char string1[]={"||**Hello world^_^**||\n\n\r"};
char string2[]={"You are right\n\r"};
char string3[]={"Thank you!\n\r"};
char string4[]={"Good luck \n\r"};
void send(char []);
unsigned int i;
char string[];
char *var;

void send(char string[])
{
   var=string;
    i = 0;
    IE2 |= UCA0TXIE;                                                 // Enable USCI_A0 TX interrupt
     UCA0TXBUF = var[i++];
}
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                      // Stop WDT
    P1DIR = 0xFF;                                                         // All P1.x outputs
    P1OUT = 0;                                                              // All P1.x reset
    P2DIR = 0xFF;                                                         // All P2.x outputs
    P2OUT = 0;                                                              // All P2.x reset
    P1SEL = BIT1 + BIT2 ;                                           // P1.1 = RXD, P1.2=TXD
    P1SEL2 = BIT1 + BIT2 ;                                       // P1.1 = RXD, P1.2=TXD
    P3DIR = 0xFF;                                                       // All P3.x outputs
    P3OUT = 0; // All P3.x reset
    UCA0CTL1 |= UCSSEL_1;                               // CLK = ACLK
    UCA0BR0 = 0x03;                                                // 32kHz/9600 = 3.41
    UCA0BR1 = 0x00;                                               //
    UCA0MCTL = UCBRS1 + UCBRS0;           // Modulation UCBRSx = 3
    UCA0CTL1 &= ~UCSWRST;                       // **Initialize USCI state machine**
    _EINT();

    send(string1);
    send(string2);
    send(string3);
    send(string4);
    //_DINT();
    while(1);
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
      UCA0TXBUF = var[i++];             // TX next character
      if (i == sizeof var - 1)                  // TX over?
       IE2 &= ~UCA0TXIE;                 // Disable USCI_A0 TX interrupt
}

My question is as follow:

(1) when I did not add   //_DINT();  the msp430 did not stop sending data to super terminal, the PC receive data is messy code. My target is that msp430 send string1[]~string4[] and stop , but the process did not follow order.

(2) when I add   //_DINT();  to code, the super terminal only receive one byte and is not right. I don’t know where the problem

(3)Did there have many examples to send string by subroutine?

Thank you very much for your answers!

  • Hi, 

    Please use code blocks when posting code. That way your post will be much easier to read.

    I can recommend two things here:

    I hope this materials will help you,
    Maciej 

  • Ouch... lot of errors. What I noticed (perhaps this is not all):

    Variable "i" is not defined as volatile.

    Send() function does not check whether it's ok to write TXBUF (is it free or not). Maybe previous char is still in transmission?

    You made interrupt-based transmission which means that each send() function return before sting is sent. send() calls don't wait for previous string transmission to complete.

    paul cai said:
          if (i == sizeof var - 1)                  // TX over?

    This is ultraweird. Copy&paste error? Intention was "if (i == (sizeof(var) -1))" ? This effectively means "if (i == 1)" because size of char * pointer is 2. This is not the way you check length of char string!

    paul cai said:
    char string4[]={"Good luck \n\r"};

    Char array do not have '\0' string terminator which could used to determine length of each string. For strings you shall use:

    char *string4 ="Good luck \n\r";

    Then send() function shall search for end of the string by searching '\0' character, then set global transmission_length variable for ISR.

  •        Thank you, Ilmars ,I have solved those problems with your help.
    Just like what you said, I did not check the string to be completed. in addition, when functions transfer array,sizeof() is not right way to calculate array length , I use the strlen () to realize the function.

  • could you please put your final code, whit all your problems solved please

  • hey check this one Thou I am not a professional, hope it will help you.

    #include "msp430g2553.h"
    char data1[]={"lets play \r\n"};
    char data2[]={"hello guys how are you \r\n"};
    void uart_init( void )
    {
    UCA0CTL1 = UCSWRST;
    UCA0CTL1 |= UCSSEL_2;
    UCA0BR0 = 104;
    UCA0BR1 = 0x00;
    UCA0MCTL = UCBRS0;
    P1SEL = BIT1 + BIT2;
    P1SEL2= BIT1 + BIT2;
    UCA0CTL1 &= ~UCSWRST;
    }

    void uart_send_byte( unsigned char data )
    {
    while (!(IFG2&UCA0TXIFG)) ;

    UCA0TXBUF = data;
    }
    void main(void)
    {
    unsigned int i=0,j=0;
    WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog timer

    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;

    uart_init();

    while( 1 )
    {
    for (i=0; i<14; i++)
    {
    uart_send_byte( data1[i] );
    }
    for(j=0;j<25;j++)
    {
    uart_send_byte(data2[j]);

    }
    __bis_SR_register( LPM3_bits + GIE );
    }
    }

  • this my code plz help me thank in advance....


    #include "msp430g2553.h"


    #define LED1 BIT0
    #define LED2 BIT6
    #define TXD BIT2
    #define RXD BIT1

    unsigned int rec_data;

    void InitUART(void)
    {
    DCOCTL = CALDCO_1MHZ;
    P2DIR |= 0xFF; // All P2.x outputs
    P2OUT &= 0x00; // All P2.x reset
    P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD
    P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD
    P1DIR |= LED1 + LED2;
    P1OUT &= 0x00;
    UCA0CTL1 |= UCSSEL_2; // SMCLK
    UCA0BR0 = 104; // 1MHz 9600
    UCA0BR1 = 0; // 1MHz 9600
    UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    // UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt
    // __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ int until Byte RXed
    }

    void SendByteSerially(unsigned char Byte)
    {
    int i;
    while(!UCA0TXIE);
    UCA0TXBUF= Byte;
    }

    void SendStringSerially(const unsigned char* st)
    {
    while(*st)
    SendByteSerially(st[i]);

    }



    unsigned char ReceiveByteSerially(void) // Reads a character from the serial port
    {
    // UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt
    while(UCA0RXIE==0);
    rec_data = UCA0RXBUF;
    return rec_data; //return the received data
    }



    int main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    DCOCTL = 0; // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_1MHZ; // Set DCO
    InitUART();
    // SendStringSerially("PMPKSAMY");
    SendByteSerially('p');
    while (1)
    {
    ReceiveByteSerially();
    if(rec_data=='Z')
    {
    P1OUT |= LED1;
    P1OUT &= ~LED2;
    SendByteSerially('X'); ///<-------------------------------------- i am stack here many char print on screen
    // SendStringSerially("LED1 ON\r\nLED2 OFF\r\n"); <-------------------------------------- i am stack here many char print on screen
    }
    if(rec_data=='X')
    {
    P1OUT |= LED2;
    P1OUT &= ~LED1;
    SendByteSerially('Y'); ///<-------------------------------------- i am stack here many char print on screen
    // SendStringSerially("LED2 ON\r\nLED1 OFF\r\n"); <-------------------------------------- i am stack here many char print on screen

    }
    }
    }
  • In your receive function, you should wait for UCA0RXIFG, which indicates i received byte. UCA0RXIE is a flag that you control, to enable or disable calling an interrupt function based on UCA0RXOFG.
    If you don't set it, it will never be set and your while will never wait. If you set it, it will crash the system, as you don't have an ISR. :)
    Due to this mistake, you never wait for incoming data and execute your main loop as fast as possible as soon as the first time an 'Z' or 'X' was received (as it then remains in RXBUF until the next byte is received).

    However, your request was an independent case. Better start a new thread next time.
    Also, please use the code pasting tool in the rich text editor to paste code.
    And please make a better description of your problem.

**Attention** This is a public forum