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.

MSP430F5438 Example UART Code Not Working?

Other Parts Discussed in Thread: MSP430F5438, MAX232, MSP430F5438A

I'm trying to get started using the MSP430F5438, and I'm having some troubles.

One of the first things I need to do is get the chip communicating to me over RS232 via the UART.  To try and get this off the ground, I downloaded the 5438 example code, and loaded it onto my 5438.  Using the MSP-TS430PZ5x100 socket module, I hooked up a serial cable and connected it to my computer.  However, I'm not seeing any of the signaling coming through on the line - when i disconnect the serial cable from the 5x100 board, I can see the characters on the oscilloscope, but when I re-connect, the line is held just above ground level, with no changes.

The code I'm using is as follows (straight out of the example code set):

//******************************************************************************
//   MSP430F54x Demo - USCI_A0, 115200 UART Echo ISR, DCO SMCLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
//   USCI_A0 RX interrupt triggers TX Echo.
//   Baud rate divider with 1048576hz = 1048576/115200 = ~9.1 (009h|01h)
//   ACLK = REFO = ~32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
//   See User Guide for baud rate divider table
//
//                 MSP430F5438
//             -----------------
//         /|\|                 |
//          | |                 |
//          --|RST              |
//            |                 |
//            |     P3.4/UCA0TXD|------------>
//            |                 | 115200 - 8N1
//            |     P3.5/UCA0RXD|<------------
//
//   M Smertneck / W. Goh
//   Texas Instruments Inc.
//   September 2008
//   Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
//******************************************************************************

#include "msp430x54x.h"

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 9;                              // 1MHz 115200 (see User's Guide)
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
  __no_operation();                         // For debugger
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  switch(__even_in_range(UCA0IV,4))
  {
  case 0:break;                             // Vector 0 - no interrupt
  case 2:                                   // Vector 2 - RXIFG
    while (!(UCA0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
    UCA0TXBUF = UCA0RXBUF;                  // TX -> RXed character
    break;
  case 4:break;                             // Vector 4 - TXIFG
  default: break;
  }
}

I'm running CCS 4.3, freshly downloaded.The code compiles fine, and appears to load onto the chip perfectly.  In debug mode I can step through what little code there is, until it goes into low power mode.

I've attached wires to pins 37 (GND), 39 (TX) and 40 (RX) on the 5x100 board, with no other changes to the 5x100 board.  I am powering via the JTAG connection over a MSP-FET430UIF, and I believe this is working, as CCS appears to load the code onto the chip without errors.  I've tried swapping pins 39 & 40 to make sure I didn't get my RX/TX switched into the computer, with no changes.

The chip appear to be working - I've put it into the MSP430 experimenters board and loaded them with the User Experience code (same FET430UIF, so I know it's working as well), and it appears to work just fine - including UART functionality over USB.  I'm happy to provide any other information that might be needed to help me out.

Thanks,

Ian

  • Hi Ian,

    I'm not sure if this is your problem, but have you checked the voltage levels on the oscilloscope? Remember that the MSP430 will output a signal between 0 and 3.3V, and your computer will only recognize signals between -12V and 12V on the serial port. 

    You can try with a MAX232, which converts the logic output to -12/12V output that your computer can read.

    Regards,

    Alvaro 

  • Hrm, that's something I had forgotten about.

    When I scope the signals coming from the computer, disconnected from the 5x100 board, they are indeed +/-12V.  However, when I attach the RX line to the 430, the line is pulled to -.6V, and kept there, with no signaling present on the line from the computer.

    In addition, if I disconnect the MSP430 from the computer, and throw the following code onto the system, I don't see any signaling at all on the TX line, even though I believe it should be cycling through 0-255 repeatedly.  When I step through in debug mode, it seems to believe that it's doing just that, but there isn't any output anywhere that I can see.

     

    #include "msp430x54x.h"

     

    void main(void)

    {

      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

     

      P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD

      UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**

      UCA0CTL1 |= UCSSEL_2;                     // SMCLK

      UCA0BR0 = 9;                              // 1MHz 115200 (see User's Guide)

      UCA0BR1 = 0;                              // 1MHz 115200

      UCA0MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0

      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

      UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

     

     int i = 0;

      while(1)

      {

      for(i = 0; i < 256; i++)

      {

       while(!(UCA0IFG & UCTXIFG))

         UCA0TXBUF = (char)i;

      }

      }

    }

    Even if the signalling is wrong for MSP430 <-> Computer communications, I'd think I'd still at least be able to scope the signaling coming FROM the MSP430, as I can do with the signalling coming from the computer.  The fact that I can't makes me wonder if I'm not doing something completely wrong, but I can't really see what, since this is pretty much entirely MSP430 example code.  And even with the MSP430 connected to the computer, I'd think that I should be able to still see some signalling on the line from the computer, even if the signal levels are wrong for actual communication.

    I'll see if I can't integrate this into a breadboard layout with a MAX232 or similar, and see if that doesn't help things.  However, if there are any other thoughts or suggestions, they'd be appreciated.

    Thanks,

    Ian

  • Hey Ian,

    If you already connected the device straight to the computer without a level translator, your pins on the MSP430 might have gotten damaged... These pins cannot tolerate those voltages, and that might be why you cannot see the data with the oscilloscope. 

     Try with another device if you have anything handy. Also, I could recommend using an FTDI cable which I have tried before. This is an FTDI USB to Serial converter, but the circuitry is inside the cable, so all you gotta do is plug it into the USB port and plug the appropriate pins to your TX, RX and GND pins on the microcontroller.

    Regards,

    Alvaro

  • I considered this.  I put the micro I had been working with back in the Experimenter's board, where it appears to be working perfectly, including UART USB communications.

    I got another, fresh, MSP430 and put that in the 5x100 socket.  I then loaded to code above (UART output) and ran it through the CCS debugger while looking at the output on the O-Scope.  I still am not seeing anything on the output, while the debugger seems to think that it's executing the code as expected.  This is the only thing that's been done with this chip, so I don't believe, at this point in time, that it's hardware related.  I have another MSP430 that should be fresh as well, which I can try if hardware continues to be suspect.

    Ian

  • Ian Cyr said:
    However, when I attach the RX line to the 430, the line is pulled to -.6V, and kept there, with no signaling present on the line from the computer.

    The MSP port pins only accept voltages from 0V to VCC. If the attached voltage is larger (above VCC or below GND), then excess current flows through the clamping diodes to GND or VCC, which can even raise VCC or lower GND (depending on the regulator used for VCC). This current also breaks down the input voltage (an RS232 line does not drive high currents). I may not, however, exceed 2mA, or the diodes may be damaged, either breaking up (losing the protection) or melting down (forming a shortcut do GND/VCC).

    However, it is not only that the voltages are too high/low, but also have reversed polarity, so even a voltage divider won't work.

    Ian Cyr said:
    ven if the signalling is wrong for MSP430 <-> Computer communications, I'd think I'd still at least be able to scope the signaling coming FROM the MSP430

    If disconnected form the PC, yes, you should. Except for this little problem:

    Ian Cyr said:

    while(!(UCA0IFG & UCTXIFG))
         UCA0TXBUF = (char)i;
      }


    Here you stuff something into TXBUF if UCTXIFG is NOT set. However, after clearing SWRST, it is set and it expects something to be written to TXBUF. Which you never do then.

    The correct check in this case is

    while(UCA0IFG & UCTXIFG)

    as you want to stuff something into TXBUF as soon (or as long) as the set TXIFG bit tells you that TXBUF is empty.

  • Hi,

    I am using MSP-EXP430F5438 Board. there is a problen on uard code examples. 

    i am just using mini usb on the board for communication with PC. So that there is no problem signal level or sth like that

    when i debug the code for example usciA0_uart_03.c, (MSP430F543xA Demo - USCI_A0, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK)

    never rx interrupt is occur. i am using putty for the serial port terminal. configuration is correct and the signal on the rx(JP5) is ok.

    However the rx interrupt does not occur. i am checking it from the debug menu by using breakpoint in the interrupt function.

    İ didn't make any change on  the orginal code. can anybody help me how can i am sure the code is working correctly. anyone tested it before?

  • If I read the board schematics right, then USB_RxD and USB_TxD are connected to USCI A1.

    The demo is written for a generic MSP430F5438 and uses USCI A0. No wonder that it doesn't work :)

  • Jens-Michael Gross said:

    If I read the board schematics right, then USB_RxD and USB_TxD are connected to USCI A1.

    The demo is written for a generic MSP430F5438 and uses USCI A0. No wonder that it doesn't work :)

    Thanks Jens-Michael Gross;

    We just solved the problem as you say. that is work. i supposed that examples are given for exp430f5438 board.

  • ismail HANCI; said:
    i supposed that examples are given for exp430f5438 board

    No, examples, except if explicitely arked for use with a specific board, are for the generic chip. Usually using th elowest available timer, USCI, A/D channel etc.

  • Respected Jens-Michael Gross

    I have been trying hard to execute UART using the mini usb on the MSP430f5438A experimenter board and I am using RealTerm for seeing the output on the computer. 

    this is the code.

    int i=0;
    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P5SEL = BIT6 + BIT7; // P5.6,7 = USCI_A1 TXD/RXD
    UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
    UCA1CTL1 |= UCSSEL__ACLK; // CLK = ACLK
    UCA1BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
    UCA1BR1 = 0x00; //
    UCA1MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
    UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    UCA1IE |= UCTXIE + UCRXIE; // Enable USCI_A0 RX and TX interrupt

    __bis_SR_register(GIE); // Enter LPM3, interrupts enabled
    __no_operation(); // For debugger

    }

    // Echo back RXed character, confirm TX buffer is ready first
    #pragma vector=USCI_A1_VECTOR
    __interrupt void USCI_A1_ISR(void)
    {
    switch(__even_in_range(UCA1IV,4))
    {
    case 0:break; // Vector 0 - no interrupt
    case 2: // Vector 2 - RXIFG
    break;
    case 4:
    while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
    UCA1TXBUF = UCA1RXBUF;// TX -> RXed character
    break; // Vector 4 - TXIFG
    default: break;
    }
    }

    Nothing seems to be happening on the serial monitor.

    Can you please help me in rectifying the problem?

    Also, can you suggest a simple code for just transmitting a byte to the computer?

    Another thing i would like to know is about the pragma directive and where can we find the list of the interrupt vectors with the pragma directives? I tried hard to search for it in google but all was in vain.

    Thank you in advance for your time and support.

  • The problem is your interrupt logic.

    Currently, you have RX and TX interrupts enabled. This means, when a byte arrives, or the TX buffer becomes empty (not is empty), an interrupt is triggered.

    Now the ISR is entered. The switch statement reads the highest priority pending interrupt and clears it. In case of an RX interrupt (case 2) your code does nothing. In case of a TX interrupt, the code waits for TXIFG being set, but it has just been cleared by reading UCA1IV in the switch statement. And won’t set again, as TXBUF does not become empty again without first writing to it.
    As a result, the code hangs in the while forever.

    Now what to do: first, don’t set UCTXIE. You won’t act on incoming data, so this shouldn’t trigger an interrupt. Then your reaction to an incoming byte should happen in the RX case.
    Alternatively, you can leave the code in the TX case, set UCTXIE but not UCRXIE, and check for RXIFG in the ISR.

    However, it is a very bad concept to wait inside an ISR for an event.

    When your code just does an echo, you can assume that TXBUF is empty when a new byte has arrived, because receiving and sending happens with same speed. So in the RX case, simply copy the data over. (You could even use DMA to copy the data over when it comes in, without any CPU action.) This has, however, some risk or running into problems if the PC baudrate is slightly higher than the MSP baudrate, and the PC sends data continuously. Then eventually the higher baudrate of the PC will sum up to a complete byte transfer time.

    The better way to handle things is to decouple RX and TX. Read incoming data into a buffer, send data from an second buffer, and copy data over by CPU (or even add or remove data from the echo). This likely is the way you’ll need it later anyway.

    But for a quick test of the physical connection, the changes mentioned above will do.

**Attention** This is a public forum