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.

Help!Transmit a "Hello" word to PC through RS-232 using MSP430FG4618

Other Parts Discussed in Thread: MSP430FG4618, MAX232

I want to transmit a "hello" word to pc through RS-232 using MSP430FG4618 microcontroller. So for that wht code i have to write in CCS, please guide me.

  • On the product page (click on the link that is auto-created on teh processor name in your own post) you'll find links to applicaiton notes and demo code.

    There should be a code demo for basic UART transfer (UART echo).

    You'll need to read and understand the UART and Clock system chapters of the users guide, to understand how the demo works. But then you should be able to alter it for your hello world purpose.

  • Hello friends, I just try to create a code of UART for transmit a word "A" to PC in RS-232 protocol. As i already said that i use my MSP430FG4618/F2013 Experimenter's board.Now i give you the code below which give me no error when i "Build" it in CCS.

    =================================================================================================================

    #include  <msp430xG46x.h>

    void main(void)
    {
      volatile unsigned int i;

      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                              // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                                     // Clear OSCFault flag
      for (i = 0; i <=0x47FF; i++);                      // Time for flag to set
      }
      while ((IFG1 & OFIFG));                           // OSCFault flag still set?

      P4SEL |= 0x0C0;                                   // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                                // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                              //
      UCA0MCTL = 0x06;                             // Modulation
      UCA0CTL1 &= ~UCSWRST;                 // **Initialize USCI state machine**
     
      IE2 |= UCA0RXIE;                               // Enable USCI_A0 RX interrupt

      _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, interrupts enabled
    }

    void USCIA0_UART_Transmit(unsigned char A)
    {

        while(!(IFG2 & UCA0TXIFG));             // Wait until transmit buffer is empty
        UCA0TXBUF = A;                          // Transmit character "A"
        return;

    }
    =====================================

    Now when i run this program i can't get any value in my hyper terminal. I run this code in my Laptop and see the output in desktop PC.

    Please give a solution for this.

  • Well you should call USCIA0_UART_Transmit() at some point in your program.

    So maybe do something like:

    for (;;)
    {
    for(char test = 0x20; test < 0x7E; test++)
    {
    USCIA0_UART_Transmit(test)
    }
    }

    This will send out the displayable ASCII codes in a loop forever.

    Just for sending out you won't need to enable the RX interrupt also if you send continuously without using the TX interrupt you won't need the LPM. (so no IE2 |= UCA0RXIE and _BIS_SR())

     

    And just because it's out of a horrible code example: get rid of the for (i = 0; i <=0x47FF; i++); and replace it with a _delay_cycles(50000); - now if you are new to programming you might wonder why, as the for() is a nice delay loop. What can get (and will) get you is the optimizer which will take a look at the for() loop and because it's doing nothing it replaces it with something far better: nothing - saves a lot of time.

    _delay_cycles() is different as it's an intrinsic telling the compiler to place an assembly at that position which will also do nothing but use exactly the number of clock cycles given. And the optimizer can't get rid of it

    souvik metia said:
    Now when i run this program i can't get any value in my hyper terminal. I run this code in my Laptop and see the output in desktop PC.

    .

    That confused me a bit - do you mean you debug your MSP from your laptop and have it connected to your PC via UART? Or are you trying to relay something like you type something on your laptop, the MSP receives it and then sends it on to the PC? That would need a different solution (2 UARTs involved)

  • I mean, i just debug my MSP from my laptop and it connected to my PC via UART.

  • It shows me an error "expected a declaration". And the code is below......

    ===========================================

    #include  <msp430xG46x.h>

    void main(void)
    {
      volatile unsigned int i;
      volatile unsigned char test;
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
     // for (i = 0; i <=0x47FF; i++);             // Time for flag to set
     _delay_cycles(50000);
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    }
    for(;;)
    {
        for (test = 0x20; test < 0x7E; test ++)
        {
            USCIA0_UART_Transmit(test);
        }
    }

    ==========================================================

  • You placed the for() loops outside of the main closing bracket, it should be like:

    void main(void)
    {
    volatile unsigned int i;
    volatile unsigned char test;
    WDTCTL = WDTPW+WDTHOLD; // Stop WDT
    FLL_CTL0 |= XCAP14PF; // Configure load caps

    do
    {
    IFG1 &= ~OFIFG; // Clear OSCFault flag
    // for (i = 0; i <=0x47FF; i++); // Time for flag to set
    _delay_cycles(50000);
    }
    while ((IFG1 & OFIFG)); // OSCFault flag still set?

    P4SEL |= 0x0C0; // P4.7,6 = USCI_A0 RXD/TXD
    UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
    UCA0BR0 = 0x03; // 32k/9600 - 3.41
    UCA0BR1 = 0x00; //
    UCA0MCTL = 0x06; // Modulation
    UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

    for(;;)
    {
    for (test = 0x20; test < 0x7E; test ++)
    {
    USCIA0_UART_Transmit(test);
    }
    }

    }

     

  • Now it show me the error of "Unresolved symbol USCIA0_UART_Transmit, first referenced in ./UART.obj"

  • Then the forward declaration of your USCIA0_UART_Transmit method is missing. So at the top of your program, after the #include you need to write the signature of your method, so add:

    void USCIA0_UART_Transmit(unsigned char A);

    This will allow the compiler and linker to know "there is a method called  USCIA0_UART_Transmit around and it returns void (nothing) and needs an unsigned char as input".  And I didn't post it, but of course the method must still be in your file - otherwise it won't know what to do if you call USCIA0_UART_Transmit().

  • The main problem is that USCIA0_UART_Transmit originally was an ISR, whcih is called when a hardware event happens (UCA0TXIFG is set).
    The demo code used the RX interrupt event to foward the jsut received byte back to TXBUF.

    While removing the receive part, the implicit call to this ISR was also removed. (the #pragma line identifying it as an RX ISR)

    But with all the hintes already posted, an 'inlined' version, that does not rely on interrupts, is already almost done.

     

    p.s.: when an ISR is called because UCA0TXIFG was set, no while loop is needed to wait for TCIFG is set. it is set, or else the ISR wouldn't have been called. (Well, there are exceptions, e.g. with I2C)

    And in the original demo code, the wait was superfluous too, since the ISR was called when a byte arrived, and since RX and TX have the same baudrate, it implied that the previously to TXBUF written byte must have been sent in the same time, so TXBUF must be always clear. (again, there will be exceptions, if there are other ISRs active that may cause a jitter in handling the RX interrupt, but not in this demo code.)

  • Ok.... I want to transmit a single character "A" which is in hex is 0x41. Now i write the following program without any error i run it but still i am not able to see any character or garbage value in my hyper terminal. Just check my program and please tell me the problem of it.

    ===============================================================================================

    #include  <msp430xG46x.h>

    void main(void)
    {
      //volatile unsigned int i;
      //volatile unsigned char test;
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
     // for (i = 0; i <=0x47FF; i++);             // Time for flag to set
     _delay_cycles(50000);
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

    UCA0TXBUF = 0x41;                                
    }

  • Looks good so far.

    The only thing is that your code falls out of main while the data isn't transferred yet.

    Depending on the compiler you use this may have various effects. There is no OS where msin could return to. So some compilers add code that enters LPM4 when main exits (this would stop ACLK and therefore the sending process), some assume that main never returns and do nothing, so if main reutrns, the MSP will jump into the void, eventually resetting.

    Try adding a "while(1);" at the end of main.

    Of course there is a lways a chance of a hardware error. Did the original demo properly echo the characters? (or did you just see a 'local' echo of what you typed)

  • Hi Jens-Michael Gross thank you for your reply. I just do whatever u told but the problem is same i can't see any output at the hyper terminal. Here is my little modified code.

    =======================================

    #include  <msp430xG46x.h>

    void main(void)
    {
      //volatile unsigned int i;
      //volatile unsigned char test;
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
     // for (i = 0; i <=0x47FF; i++);             // Time for flag to set
     _delay_cycles(50000);
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

     while(1)
     {
     UCA0TXBUF = 0x41;
     }
     }
    ===================================================

    "Did the original demo properly echo the characters? (or did you just see a 'local' echo of what you typed)".....as u told i also run the TI code which also run but i can't see anything. I can't understand what you told as"local echo of what you typed".

    and the TI code is that....

    ======================================================

    //******************************************************************************
    //   MSP430xG46x Demo - USCI_A0, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK
    //
    //   Description: Echo a received character, RX ISR used. Normal mode is LPM3,
    //   USCI_A0 RX interrupt triggers TX Echo.
    //   ACLK = BRCLK = LFXT1 = 32768, MCLK = SMCLK = DCO~1048k
    //   Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 3.41 (0003h 03h )
    //   //* An external watch crystal is required on XIN XOUT for ACLK *//   
    //
    //
    //                MSP430xG461x
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 | 32kHz
    //          --|RST          XOUT|-
    //            |                 |
    //            |     P4.7/UCA0RXD|------------>
    //            |                 | 9600 - 8N1
    //            |     P4.6/UCA0TXD|<------------
    //
    //   K. Quiring/ M. Mitchell
    //   Texas Instruments Inc.
    //   October 2006
    //   Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
    //******************************************************************************
    #include  "msp430xG46x.h"

    void main(void)
    {
      volatile unsigned int i;

      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      for (i = 0x47FF; i > 0; i--);             // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

      _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, interrupts enabled
    }

    //  Echo back RXed character, confirm TX buffer is ready first
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR (void)
    {
      while(!(IFG2&UCA0TXIFG));
      UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
    }
    ==============================================

    please reply with a solution.

  • Hi friend's i continued my post by saying that i have tested the RS-232 cable with DVM which pass  the continuity test of the RS-232 cable. And also i short the cable pin RX and TX and then type something which then echoed and displayed in the hyper terminal, that means the RS-232 cable is good. Now i short the pin5 and pin6 of H4 which is actually P2.4 and P2.5 pin of the MSP430FG4618, in the pin access of MSP430FG4618/F2013 experimenter's board which are UCA0TXD and UCA0RXD respectively and at the same time i do not run the program only power on the board and type something which again displayed in the hyper terminal of my PC, that means the isolated RS-232 Communication part is OK. But whenever i run the program of "echo" of TI code which actually short the pins(RX and TX) via software didn't work. It displays nothing. I am now confusing what i have to do, i did some short of testing what i know and also i explain details here. If there is some testing of hardware and software is missing please reply me and give me a good solution of this mess because i stuck it for some days.

    here is the TI code of "echo"....

    =======================================================

    //******************************************************************************
    //   MSP430xG46x Demo - USCI_A0, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK
    //
    //   Description: Echo a received character, RX ISR used. Normal mode is LPM3,
    //   USCI_A0 RX interrupt triggers TX Echo.
    //   ACLK = BRCLK = LFXT1 = 32768, MCLK = SMCLK = DCO~1048k
    //   Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 3.41 (0003h 03h )
    //   //* An external watch crystal is required on XIN XOUT for ACLK *//   
    //
    //
    //                MSP430xG461x
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 | 32kHz
    //          --|RST          XOUT|-
    //            |                 |
    //            |     P4.7/UCA0RXD|------------>
    //            |                 | 9600 - 8N1
    //            |     P4.6/UCA0TXD|<------------
    //
    //   K. Quiring/ M. Mitchell
    //   Texas Instruments Inc.
    //   October 2006
    //   Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
    //******************************************************************************
    #include  "msp430xG46x.h"

    void main(void)
    {
      volatile unsigned int i;

      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      for (i = 0x47FF; i > 0; i--);             // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

     //P2SEL |=0x30;                              // P2.4,5 = USCI_A0 RXD/TXD
      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

      _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, interrupts enabled
    }

    //  Echo back RXed character, confirm TX buffer is ready first
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR (void)
    {
      while(!(IFG2&UCA0TXIFG));
      UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
    }
    =============================================================

    And here is the schematic of the board. I circled two portion of the schematic with green line which are tested by me.

  • souvik metia said:
     //P2SEL |=0x30;                              // P2.4,5 = USCI_A0 RXD/TXD
      P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD

    Why are you using the P4SEL? From the schematic I take it that only the P2.4 and P2.5 are connected to the isolated RS232 connector.

    If you try to connect P4.7 and P4.6 directly to the RS232 port of your computer - that won't work as the MSP puts out something like TTL signals and not the required negative and positive voltage expected by RS232.

    You can also set a breakpoint in your ISR, then you notice if something was received.

  • Thank you Bernhard Weller for your reply. But in TI code they only give the P4SEL |= 0x0C0; but when it doesn't work,i see the pin diagram properly,and  i found that there are another two pins which are also used for RXD(P2.4) and TXD(P2.5). then i write it on that program. After add the P2SEL |= 0x030; in the TI code, then also i found it doesn't work. then i add it( P2SEL |= 0x030;) in my own program which work properly. I think there may be some mistakes in TI code.

    Here is the TI code below which is not work after i add the port2(in blue color)

    ============================================================ 

    //******************************************************************************
    //   MSP430xG46x Demo - USCI_A0, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK
    //
    //   Description: Echo a received character, RX ISR used. Normal mode is LPM3,
    //   USCI_A0 RX interrupt triggers TX Echo.
    //   ACLK = BRCLK = LFXT1 = 32768, MCLK = SMCLK = DCO~1048k
    //   Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 3.41 (0003h 03h )
    //   //* An external watch crystal is required on XIN XOUT for ACLK *//   
    //
    //
    //                MSP430xG461x
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 | 32kHz
    //          --|RST          XOUT|-
    //            |                 |
    //            |     P4.7/UCA0RXD|------------>
    //            |                 | 9600 - 8N1
    //            |     P4.6/UCA0TXD|<------------
    //
    //   K. Quiring/ M. Mitchell
    //   Texas Instruments Inc.
    //   October 2006
    //   Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
    //******************************************************************************
    #include  "msp430xG46x.h"

    void main(void)
    {
      volatile unsigned int i;

      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      for (i = 0x47FF; i > 0; i--);             // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?

      //P4SEL |= 0x0C0;                           // P4.7,6 = USCI_A0 RXD/TXD

      P2SEL |= 0x030;
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 3.41
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

      _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0, interrupts enabled
    }

    //  Echo back RXed character, confirm TX buffer is ready first
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCIA0RX_ISR (void)
    {
      while(!(IFG2&UCA0TXIFG));
      UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
    }
    ===========================================================

    And here in below is my code based on that. Which works properly.

    ===========================================================

    #include  <msp430xG46x.h>

    void main(void)
    {
      //volatile unsigned int i;
      //volatile unsigned char temp[]="HELLO";
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      FLL_CTL0 |= XCAP14PF;                     // Configure load caps

      do
      {
      IFG1 &= ~OFIFG;                           // Clear OSCFault flag
      //for (i = 0; i <=0x47FF; i++);             // Time for flag to set
      _delay_cycles(50000);
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?
        P2SEL |= 0x30;                         // P2.4,5 = USCI_A0   RXD/TXD
     
      //P4SEL |= 0x0C0;                         // P4.7,6 = USCI_A0 RXD/TXD
      UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
      UCA0BR0 = 0x03;                           // 32k/9600 - 13.65
      UCA0BR1 = 0x00;                           //
      UCA0MCTL = 0x06;                          // Modulation
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

     while(1)
     {
         //for(i = 0; i<=5; i++)
       // UCA0TXBUF = temp[i];
        _delay_cycles(1000);
         UCA0TXBUF = 0x41;
     }
     }
    ===========================================================

    I want to know that if i want to show a single character it gives me proper value but when i want to write a "HELLOWORD" in my above program it shows me garbage value though it take less than 13 bit.Please reply

     

     

  •  Is it necessary to connect a crystal clock to the pins. Is it possible to do this using the internal clock?

    Another doubt: Should I give a max232 in between rs232 and the microcontroller?

    Thanks in advance.

  • Hi Venkatraman, actually you don't need to connect any crystal clock if you use the on-board crystal clock, you can use VCO also. and you don't need max232 in between rs232 and micro controller because in MSP430FG4618/F2013 has optical isolation in rs232 which can manage the logic voltage level difference. 

  • Actually I tried the sample code and nothing is happening. I typed in the hyperterminal and nothing is happening. 

    Please clear my two doubts.

    Is it necessary to give an external clock separately for that sample code for uart?

    The msp that I am having is this- msp430fg4618/f2013. It has an in built rs232. So you mean I should plug the wire directly into the db9 and I don't need max232 in between at all?

    This is what I did- I copied that code into the code composer and burnt the msp. Then I simply connected the wire from my computer to the rs232 of the msp.

    Now if I type in Hyperterminal nothing is happening.

    Could you please help me?

    Thanks in advance

  • please read this thread, you can understand the problem....

**Attention** This is a public forum