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.

software serial monitor

Other Parts Discussed in Thread: MSP430WARE

Hi,

Is anybody aware about software serial monitor, which is nothing but 'C' code which is used to change the general purpose pins into UART pins. If it is there can anyone share the code to me.  

  Also i want to know the which of the following family controller comes with 2 UART  buses.

1.MSP430F2 series

2.MSP430G2 series

  • Hello Prakash,

    I imagine you are trying to find a bitbanging solution for UART.  While TI does not support any software that already does this, I did happen to find an application report (SLAA078A) that might help you get started on using a timer to implement UART.  Linked is another thread that explains the benefits of using a timer UART.

    The MSP430G2xx devices will only allow for at most one UART.  However, there are 18 devices in the MSP430F2xx/4xx family that include 2 UART, listed here.

    Regards,

    Ryan

  • Hi Ryan,

     Thanks for your information.I have read the pdf document i got some mess now. can you share me any code which is available in "C" program, because i  am not much aware in asm program.

    I think it will be most useful for lot of people.

  • I am not aware of any TI-supported software UART code written in C for the MSP430 family.  Here is a thread and a blog discussing how to create UART software for a MSP430G2xx device.  There's also an application report (SPMA017) that covers a software UART API developed for the Stellaris family of microcontrollers.

    Hope this helps,

    Ryan

  • Ryan, the (publicly available) serial BSL code uses a software UART. It is, however, rather specific, as it gets its timing from a sync byte sent by the other side, rather than taking it from any verified internal clock source. Mainly because on a bare MSP, no information about possibly attached crystals or DCO calibrations is available.
    However, if the length of a bit (in timer ticks) is determined based on a known clock source, the remaining code of the software UART can be used.

    Also, I think the demo code for the older G2 devices (before G2553) uses a software UART too (as these devices did not have a hardware UART).

  • Thanks Jens,

    Jens-Michael Gross said:
    Also, I think the demo code for the older G2 devices (before G2553) uses a software UART too (as these devices did not have a hardware UART).

    is it possible to share me the link for the demo codes.

  • They should be available from the LaunchPad product page. Probably as part of a larger package like MSP430Ware.

    But maybe as a single download as well, as this code was part of the preloaded software on older LaunchPads.

  • SLAA078A contains assembler examples. You can mixe C and asm in a project.

  • I have used the following code which was getting from MSPG2553 sample code. But for me the code is not working, i am able to get the timer interrupt , thogh a single character is not displyed in my PC terminal software. In the same hardware setup i can able to send/receive the data using UART program, but when using the timer based UART program only i can't able to get data. The code is below

    #include <msp430.h>
    
    //------------------------------------------------------------------------------
    // Hardware-related definitions
    //------------------------------------------------------------------------------
    #define UART_TXD   0x02                     // TXD on P1.1 (Timer0_A.OUT0)
    #define UART_RXD   0x04                     // RXD on P1.2 (Timer0_A.CCI1A)
    
    //------------------------------------------------------------------------------
    // Conditions for 9600 Baud SW UART, SMCLK = 1MHz
    //------------------------------------------------------------------------------
    #define UART_TBIT_DIV_2     (1000000 / (9600 * 2))
    #define UART_TBIT           (1000000 / 9600)
    
    //------------------------------------------------------------------------------
    // Global variables used for full-duplex UART communication
    //------------------------------------------------------------------------------
    unsigned int txData;                        // UART internal variable for TX
    unsigned char rxBuffer;                     // Received UART character
    
    //------------------------------------------------------------------------------
    // Function prototypes
    //------------------------------------------------------------------------------
    void TimerA_UART_init(void);
    void TimerA_UART_tx(unsigned char byte);
    void TimerA_UART_print(char *string);
    
    //------------------------------------------------------------------------------
    // main()
    //------------------------------------------------------------------------------
    int main(void)
    {
        WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer
        if (CALBC1_1MHZ==0xFF)					// If calibration constant erased
        {											
          while(1);                               // do not load, trap CPU!!	
        }
        
        DCOCTL = 0;                             // Select lowest DCOx and MODx settings
        BCSCTL1 = CALBC1_1MHZ;                  // Set DCOCLK to 1MHz
        DCOCTL = CALDCO_1MHZ;
    
        P1OUT = 0x00;                           // Initialize all GPIO
        P1SEL = UART_TXD + UART_RXD;            // Timer function for TXD/RXD pins
        P1DIR = 0xFF & ~UART_RXD;               // Set all pins but RXD to output
        P2OUT = 0x00;
        P2SEL = 0x00;
        P2DIR = 0xFF;
    
        __enable_interrupt();
        
        TimerA_UART_init();                     // Start Timer_A UART
        TimerA_UART_print("G2xx2 TimerA UART\r\n");
        TimerA_UART_print("READY.\r\n");
        
        for (;;)
        {
            // Wait for incoming character
            __bis_SR_register(LPM0_bits);
            
            // Update board outputs according to received byte
            if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01;    // P1.0
            if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08;    // P1.3
            if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10;    // P1.4
            if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20;    // P1.5
            if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40;    // P1.6
            if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80;    // P1.7
            if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40;    // P2.6
            if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80;    // P2.7
            
            // Echo received character
            TimerA_UART_tx(rxBuffer);
        }
    }
    //------------------------------------------------------------------------------
    // Function configures Timer_A for full-duplex UART operation
    //------------------------------------------------------------------------------
    void TimerA_UART_init(void)
    {
        TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'
        TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int
        TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode
    }
    //------------------------------------------------------------------------------
    // Outputs one byte using the Timer_A UART
    //------------------------------------------------------------------------------
    void TimerA_UART_tx(unsigned char byte)
    {
        while (TACCTL0 & CCIE);                 // Ensure last char got TX'd
        TACCR0 = TAR;                           // Current state of TA counter
        TACCR0 += UART_TBIT;                    // One bit time till first bit
        TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int
        txData = byte;                          // Load global variable
        txData |= 0x100;                        // Add mark stop bit to TXData
        txData <<= 1;                           // Add space start bit
    }
    
    //------------------------------------------------------------------------------
    // Prints a string over using the Timer_A UART
    //------------------------------------------------------------------------------
    void TimerA_UART_print(char *string)
    {
        while (*string) {
            TimerA_UART_tx(*string++);
        }
    }
    //------------------------------------------------------------------------------
    // Timer_A UART - Transmit Interrupt Handler
    //------------------------------------------------------------------------------
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void Timer_A0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer_A0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        static unsigned char txBitCnt = 10;
    
        TACCR0 += UART_TBIT;                    // Add Offset to CCRx
        if (txBitCnt == 0) {                    // All bits TXed?
            TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt
            txBitCnt = 10;                      // Re-load bit counter
        }
        else {
            if (txData & 0x01) {
              TACCTL0 &= ~OUTMOD2;              // TX Mark '1'
            }
            else {
              TACCTL0 |= OUTMOD2;               // TX Space '0'
            }
            txData >>= 1;
            txBitCnt--;
        }
    }      
    //------------------------------------------------------------------------------
    // Timer_A UART - Receive Interrupt Handler
    //------------------------------------------------------------------------------
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A1_VECTOR
    __interrupt void Timer_A1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer_A1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        static unsigned char rxBitCnt = 8;
        static unsigned char rxData = 0;
    
        switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
            case TA0IV_TACCR1:                        // TACCR1 CCIFG - UART RX
                TACCR1 += UART_TBIT;                 // Add Offset to CCRx
                if (TACCTL1 & CAP) {                 // Capture mode = start bit edge
                    TACCTL1 &= ~CAP;                 // Switch capture to compare mode
                    TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0
                }
                else {
                    rxData >>= 1;
                    if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch
                        rxData |= 0x80;
                    }
                    rxBitCnt--;
                    if (rxBitCnt == 0) {             // All bits RXed?
                        rxBuffer = rxData;           // Store in global variable
                        rxBitCnt = 8;                // Re-load bit counter
                        TACCTL1 |= CAP;              // Switch compare to capture mode
                        __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)
                    }
                }
                break;
        }
    }
    //-------------------------------------------------------------------------

    Any guidance would be more helpful for me.

    Thanks in advance.
  • Here is a very strange "serial monitor" for MSP430F2xx series members with 2 UARTs.

    void strange_serial_monitor_for_F2xx_members_with_two_UARTs (void)
    
    {
    
     P3SEL |= 0x0F;
    
    }

  • Hi OCY,
    I am trying to implement a timer based UART. so that i had tried in the code which is given with the launchpad kit.The same is not working for me i don't know why also i tried the code which is available in the
    https://github.com/alanbarr/msp430-launchpad/blob/master/common/src/uart1.c
    https://github.com/alanbarr/msp430-launchpad/blob/master/common/inc/uart1.h
    if any help would be more use.
  • Your code looks okay to me. How did you test it.

    Where does P1.1 (UART_TXD) go? And where is P1.2 (UART_RXD) from? What is Rev.# of your LaunchPad? How are the RXD and TXD jumpers set up? Is the Application UART interface with the PC working? (Mine does not work.)

    You said you tried to use the real UART earlier and that woks fine. Did you test it the same way?

  • Hi,
    Can anyone reply for this
  • Prakash, on G2553, the RX and TX functionality is switched for timer UART and hardware UART. So if hardware UART works, then the software UART needs the two signals swapped to work.
    The newer LaunchPads (V1.5) have a way to do this by jumpers, when using the application UART bridge.
  • Hi Jens
    I am using rev no 1.4 board. Also in that board no need to change any jumper I thought. Any how I will check it one more time.
  • On rev. 1.4 boards, the jumpers for RX and TX need to be crossed for the hardware UART. So RX on the target side must be connected to the TX pin of the FET side and v.v. (impossible with jumpers)
    On 1.5 boards, the wires on the PCB have been crossed, so the jumpers have to be both horizontally or both vertically for hardware or software UART.
    For software UART, the jumpers are fine on the 1.4 board. The 1.5 comes configured for hardware UART IIRC and needs a jumper change for software UART.

**Attention** This is a public forum