Configuring and Using the MSP430 UART

Embedded applications are nowdays rarely completely standalone. You’ll usually have the system communicate with something, usually a computer. The easiest way to do so is with UART, since there are several USB to UART converter ICs out there such as the FT232 from FTDI Chip.

You still need to configure the UART module of the microcontroller to work. For the MSP430, I’ve added quite a lot of practical information on how to get UART running. Take a look at the UART chapter in my tutorial:

http://www.glitovsky.com/Tutorialv0_3.pdf

The information will allow you to communicate with a computer using the USB port

 

9/26/2012

I just announced my first release of an open source MSP430 UART driver. If you want to get started using
the MSP430 UART without all the hassles, feel free to give it a try. More information Here

3/16/2014

My company’s website www.argenox.com is now the main resource for MSP430 related tutorial. We have greatly improved the information for the MSP430 UART.

37 thoughts on “Configuring and Using the MSP430 UART

  1. Great stuff! Your MSP430 tutorial really has helped me. It does a great job putting everything in one place for a newbie like myself…

    One question… have you ever successfully used the MSP430’s I2C hardware stuff? I for the life of me can’t get it to work. I have tried both a simple I2C RTC and a more complicated pressure sensor (Bosch BMP085) and have had no luck.

    I know TI has some examples, but they only communicate with other MSP430’s as slaves and are also setup as state machines and I haven’t been able to modify for my use…

    Thanks!

    1. Jason,
      I have used I2C for a few things. I2C in the MSP430 does have some bugs, depending on what variant you’re using. Make sure to look at the Errata.
      Aside from this, do you have access to a logic analyzer or oscilloscope? The best approach is to look at it, see the timing and the bits to figure out what’s going wrong. There can be any number of issues, from misconfigured module to a hardware issue and perhaps failing to do something expected by the RTC/Pressure sensor.

      A possible solution to your problem is to connect two I2C modules on the MSP430 together, with one of them simulating the device. You can then write a driver to control the Master and see whether it works. It’s no replacement for an oscilloscope though.
      Another solution is to connect the I2C pins to GPIO on the MSP430 and use it as a sort of logic analyzer.

      What hardware are you using?

  2. Amazing work you have done with the tutorial – I’ll recommend it everybody just starting on the msp430 platform. Keep up the good work.
    Do you have an amazon wish list or similar, else I would suggest you to make one. 🙂

  3. Hi. I think your tutorial was the easiest to follow tutorial and most informative I have read about the MSP430.

    I have a question though, about UART. I am using Linux Mint, and have installed the msp430 packages using dpkg. I got that all working, and I can program the msp430g2231. However, when I try to compile code with anything reffering to the UART variables, I get errors. I don’t seem to have the ta_uart.h header file.

    Do you know where I can get this?

      1. Hello,
        I am trying to use your UART portion of your tutorial. I am using the msp430f2274. When I try to compile it states that the UART variables are not defined. Do I need to add additional files to define these variables?
        -Thanks

          1. Sorry for the delay,
            These are the variables that were undefined:
            Building configuration: Tut – Debug
            Updating build tree…
            main.c
            Error[Pe020]: identifier “ME1” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 7
            Error[Pe020]: identifier “UTXE0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 7
            Error[Pe020]: identifier “URXE0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 7
            Error[Pe020]: identifier “UCTL0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 8
            Error[Pe020]: identifier “CHAR” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 8
            Error[Pe020]: identifier “UTCTL0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 9
            Error[Pe020]: identifier “SSEL0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 9
            Error[Pe020]: identifier “UBR00” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 10
            Error[Pe020]: identifier “UBR10” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 11
            Error[Pe020]: identifier “UMCTL0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 12
            Error[Pe020]: identifier “SWRST” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 13
            Error[Pe020]: identifier “URXIE0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 14
            Error[Pe020]: identifier “UTXIE0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 14
            Error[Pe020]: identifier “UTXIFG0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 23
            Error[Pe020]: identifier “TXBUF0” is undefined C:\Users\isaac_000\Documents\workspace\Tutorial\main.c 24
            Error while running C/C++ Compiler

            Total number of errors: 15
            Total number of warnings: 0

  4. this id very good tutorial…

    but i am facing problem in interfacing MSP430f168 with BMP085 pressure sensor can u help me for this????????

  5. this is very good tutorial…

    but i am facing problem in interfacing MSP430f168 with BMP085 pressure sensor can u help me for this????????

  6. i have configured UART using your tutorial for bluetooth….

    now i am supposed to configure I2C. i am not able to understand how to configure I2C…. i am using msp430f168
    and want to interface it with BMP085 pressure sensor…..

    if possible plz provide the code …

  7. Tejas,
    Since you’re wanting to communicate with the device using I2C, the MSP430 serves as master and the BMP085 serves as slave.
    There is plenty of example code for your MSP430 here:
    http://www.ti.com/litv/zip/slac015n

    Take a look at i2c_03.c.
    This one has a nice interrupt based design and shows you how to access the RX and TX parts.

    Take a look at the User’s Guide:
    http://www.ti.com/lit/ug/slau049f/slau049f.pdf

    This page contains all the necessary information to use the I2C module. Among other things you need to do:
    1) Setup the right clock for 100kHz or 400kHz from the SMCLK or MCLK
    2) Program the address of the slave device according to BMP085 datasheet so that MSP430 writes it corrects.
    3) Write to the BMP085 by generating a start condition and then sending the data according to what the BMP085 expects. There’s code online for achieving the higher layers of communication to get the actual information.

    Gustavo

  8. we have tried a code for interfacing between MSP430f168 and bluelink(bluetooth) using UART….we also have to set baud rate to 9600 and we are not sure if did set it…clock frequency is 8MHz
    the o/p for this code on LCD is LLLy

    It is generating a TX interrupt….also the reply from bluetooth is not recieved

    #include “msp430x16x.h”
    #include “lcd1.h”

    int main( void )
    {
    // Stop watchdog timer to prevent time out reset

    WDTCTL = WDTPW + WDTHOLD;
    BCSCTL1=0x00;
    BCSCTL2=0x88;

    lcd_init();

    //configuring UART
    P3SEL |= 0XC0;
    ME2 |= 0X30;
    U1CTL = 0X10;
    U1TCTL = 0X30;
    U1BR0 = 0X41;
    U1BR1 = 0X03; //setting up the Baudrate to 9600
    U1MCTL = 0X09;
    U1CTL &= ~(0X01); //~SWRST
    IE2 |= 0X30;
    int j=4;

    P5DIR |=0x80;
    while (j)
    {
    P5OUT ^= 0x80;
    delay (1000);
    j–;
    }

    char ch[]= {‘L’,’L’,’L’,”}; //an AT command to put blueLink in command mode

    for (j = 0; j<(strlen(ch)); j++)
    {
    while(!(IFG2 & UTXIFG1));
    command (ch[j],'d'); // for displaying on LCD
    U1TXBUF=ch[j];
    }

    j=0;
    while(j<5)
    {
    _NOP();
    j++;
    }

    _EINT();
    return 0;
    }

    #pragma vector=USART1RX_VECTOR
    __interrupt void usart1_rx(void)
    {
    command ('x','d'); //for displaying 'x' using lcd1.h
    }
    #pragma vector=USART1TX_VECTOR
    __interrupt void usart1_tx(void)
    {

    command ('y','d'); //for displaying 'y'
    }

    please help us

  9. I see in your code that the configuration seems correct for the baudrate.

    What sometimes happen is that UART RX and TX are not properly connected because they need to be cross connected, TX to RX.

    It can be also be that you’re sending the wrong command.

    First make sure that the clock you’re using is correct by outputting the buffered SMCLK to a pin and looking at it with the oscillscope:

    P5DIR |= BIT4+BIT5+BIT6; // P5.6,5,4 outputs
    P5SEL |= BIT4+BIT5+BIT6; // P5.6,5,5 options

    Then use a scope to look and verify the UART timing if needed.

    Are you sure the bluetooth module is powered correctly?

    I recommend that you use the defines provided by the compiler to make the code more readable. For example, BIT0 can be used to replace 0x01. FOr a list of them look at msp430x16x.h.

    Gustavo

  10. Hi Gustavo,

    I read your book and have a better understanding especially the low level explanation of the code. I have recommended your book to my colleagues.

    I am having an issue when executing the UART code as explained in your book. I was trying to use your code in a test to communicate from MSP 430 F1612 with an external program like putty (hyperterminal) or to a java program using serial communication (RX/TX). Neither seems to be getting any outputs from the MSP. I followed rigorously the code and debugged but was unsuccessful. I will just provide some code snippets so that you can give me a better explanation where I could be faltering in my code. I also read through the slau049 – MSP 430x1xx pdf and the explanation of the registers are identical to your explanation in the book.

    First, I initialize the halInit() and also enable the interrupts. Next, I have the code as mentioned in your book
    P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD
    ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD
    UCTL0 |= CHAR; // 8-bit character
    UTCTL0 |= SSEL1 ; // UCLK = ACLK = 32.768kHz — (Tried SSEL0 )
    UBR00 = 0xD0;
    UBR10 = 0x00;
    UMCTL0 = 0x00 ;

    UCTL0 &= ~ SWRST; // Initialize USART state machine
    IE1 |= URXIE0 + UTXIE0; // Enable USART0 RX/TX interrupt

    Then I have a while loop sending a character to the terminal

    while (1)
    {
    toggleLed(1);
    setLed(1);
    delayMs(1000);
    while (!(IFG1 & UTXIFG0)); // USART0 TX buffer ready?
    TXBUF0 = 0x42;
    }

    Is this code correct? In debug mode, the loop functions and I can see the led toggling.When downloaded and executing on the device, the led is not blinking. I removed the last two statement (while and Txbuf) and added a printf stmt and it loops through. Am I missing something in this USART code?

    Appreciate your help and thanks once again for the wonderful book.

    Dave

    1. Dave,

      A few things come to mind:
      1) What is the speed of SMCLK?
      2) Are you sure that P3.4 and P3.5 are connected correctly to a PC, perhaps using a USB to UART device?

  11. Shivam,
    You’ll first have to obtain the eZ430 board Pin Header, which is not included with LaunchPad.

    The eZ430 header can be placed on J4 on the LaunchPad and allows connections to external eZ430 target boards like the eZ430-RF2500T or eZ430-T2012. The LaunchPad can be used to program these target boards or to add wireless capabilities.

    The part numbers are:

    Mouser Part# 575-500201
    Digi-Key Part# ED8650-ND

    After that, the target board can send data or received commands over UART. You’ll need to program the MSP430F2274 of the target board to allow this kind of functionality. It already sends some packets over UART, but I don’t know if that’s enough for your application.

    Gustavo

  12. hello ,
    im trying interface DS1307 with MSP430F2013,can u help me with I2C code,i need specific functions in i2c for start ,stop,write,read with (n)ACK .

  13. Gustavo,

    I have the MSP430F5438A. I am using it to perform zigbee communication using the CC2530 transceiver. Can you tell me how to go about it ? This microcontroller has UART right ?

    Thanks

    1. Akhil,

      I’d start with TI’s CC2530-Software Examples (Rev. B) :
      http://www.ti.com/litv/zip/swrc135b

      Note that the CC2530 has an 8051 microcontroller in it that can be used for user applications, but you can also just use it as a network processor with an MSP430 on the outside. You’ll likely need to add some capability to communicate with it and send commands. The software examples can show you how to get most things done.

      Gustavo

  14. hi. i read your notes. it is very useful. i have one doubt. initially i set baud rate as 9600 for sent a group of data. after certain delay i changed my baud rate as 19200 and sent another group of data. but here problem occur. first data received successfully for 9600 baud rate in hyper terminal. but second group data not received anything for any baud rate set in hyper terminal. i used reset uart setup and run. but output is not received. advice me…………..

  15. in msp430f449 i initially setup baud rate as 9600, while program is running how i change the baud rate for same port as 19200. that is different baud rate is set for different session.

  16. Mari,

    To be able to change the baud rate, you first set the module reset bit. After that, simply change the dividers appropriately. My tutorial shows how to calculate the baudrate, and if you search online you can find a few baudrate calculators as well. Remember to unset the reset bit and your UART will be ready to go.

    Gustavo

  17. Sir
    your tutorials helped me a lot to understand the basics of MSP430 programming.i have ez430rf2500 target board and i am trying to use usart on it to display on a serial LCD.i am having problem in doing so.i modified one of the sample code for msp430f2774.here is my code-

    #include “msp430x22x4.h”

    const char string1[] = { “Hello World\r\n” };
    unsigned int i=0;

    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
    P3SEL = 0x30; // P3.4,5 = USCI_A0 TXD/RXD
    P3DIR = 0xFF; // All P3.x outputs
    P3OUT = 0; // All P3.x reset
    P4DIR = 0xFF; // All P4.x outputs
    P4OUT = 0; // All P4.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**
    IE2 |= UCA0TXIE; // Enable USCI_A0 RX interrupt

    while(1);
    }

    #pragma vector=USCIAB0TX_VECTOR
    __interrupt void USCI0TX_ISR(void)
    {
    UCA0TXBUF = string1[i++]; // TX next character

    if (i == sizeof string1 – 1) // TX over?
    IE2 &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt
    }

  18. Wow! Thank you so much for this.
    This guide totally taught me what I needed to know about using the UART on the MSP430. The one I have is the MSP430F2274, so I just had to look up the registers for my model and still follow the tutorials here.

  19. Hello Gustavo,
    I’m newbie on MSP430 and could you help me.
    With the lauchpad and msp430g2553, i will to forward a received data by Uart to the SPI and the reverse, i have see that in this chip we have two USCI A and B, please could you tell me if it’s possible to use the both ?
    Many thanks.
    Christophe

  20. Pingback: lunette carrera
  21. I am trying to read a data byte from the DS1307 using MSP430 Launch pad with interrupt mechanism. But its not receiving any thing, i use the example code given in the msp430ware.
    The c file name in msp430ware is “msp430g2xx3_uscib0_i2c_01”
    i changed the slave address to 0x68.
    Please help me out.

    Here is the code:

    //******************************************************************************
    // MSP430G2xx3 Demo – USCI_B0 I2C Master to TMP100, Set P1.0 if Temp > 28C
    //
    // Description: I2C interface to TMP100 temperature sensor in 9-bit mode.
    // Timer_A CCR0 interrupt is used to wake up and read the two bytes of
    // the TMP100 temperature register every 62ms. If the temperature is greater
    // than 28C, P1.0 is set, else reset. CPU is operated in LPM0. I2C speed
    // is ~100kHz.
    // ACLK = n/a, MCLK = SMCLK = TACLK = BRCLK = default DCO = ~1.2MHz
    //
    // /|\ /|\ /|\
    // | TMP100 10k 10k MSP430G2xx3
    // | ——- | | ——————-
    // +–|Vcc SDA||P1.7/UCB0SDA XIN|-
    // | | | | | |
    // +–|A1,A0 | | | XOUT|-
    // | | | | |
    // +–|Vss SCL| LED
    // \|/ ——- | |
    //
    // D. Dang
    // Texas Instruments Inc.
    // February 2011
    // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
    //******************************************************************************
    #include “msp430g2553.h”

    unsigned int RxByteCtr;
    unsigned int RxWord;

    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P1DIR |= BIT0; // P1.0 output
    P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
    P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
    UCB0CTL1 |= UCSWRST; // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x68; // Set slave address
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    IE2 |= UCB0RXIE; // Enable RX interrupt
    TACTL = TASSEL_2 + MC_2; // SMCLK, count mode

    while (1)
    {
    RxByteCtr = 2; // Load RX byte counter
    UCB0CTL1 &= ~UCTR;
    UCB0CTL1 |= UCTXSTT; // I2C start condition
    __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
    // Remain in LPM0 until all data
    // is RX’d

    if (RxWord 28C?
    P1OUT &= ~0x01; // No, P1.0 = 0
    else
    P1OUT |= 0x01; // Yes, P1.0 = 1

    __disable_interrupt();
    TACCTL0 |= CCIE; // TACCR0 interrupt enabled
    __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
    // Remain in LPM0 until TACCR0
    // interrupt occurs
    TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled
    }
    }

    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TA0_ISR(void)
    {
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }

    // The USCIAB0TX_ISR is structured such that it can be used to receive any
    // 2+ number of bytes by pre-loading RxByteCtr with the byte count.
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    {
    RxByteCtr–; // Decrement RX byte counter

    if (RxByteCtr)
    {
    RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte
    if (RxByteCtr == 1) // Only one byte left?
    UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
    }
    else
    {
    RxWord |= UCB0RXBUF; // Get final received byte,
    // Combine MSB and LSB
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    }

Leave a Reply to Jason Cancel reply

Your email address will not be published. Required fields are marked *