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.

Simplex UART communication

Other Parts Discussed in Thread: MSP430G2553

Hi,

I'm new to MSP430 programming.  I have two MSP430G2553's, and I'm trying to get the first one to talk to the other one via hardware (USCI) UART.  It's working fine if I have the first controller's UCA0TX (P1.2) hooked up to the second controller's UCA0RX (P1.1) AND the first RX hooked up to the second TX.  But as soon as I disconnect the second wire, the transmission fails to occur.  Can someone explain to me why this is when I'm only communicating in one direction?  Is there a way to overcome this issue, inasmuch as I'd prefer in my final product to use just one wire?

Thanks,

Christopher

  • Christopher Taylor97359 said:
    I'm new to MSP430 programming.  

    Are you familiar with programming any other small microcontroller(s)? With programming in general?

    as soon as I disconnect the second wire, the transmission fails to occur

    Are you sure that it's the transmission that stops - or is it the reception?

    Or both?

  • I'm new to microcontrollers, but I'm very familiar with Linux and Windows programming.  To clarify my earlier account, I believe that the transmission continues, but that the second controller's USCI is refusing to receive.

  • When you mention the communication stops when the second wire is disconnected, I assume there is still a common ground between the two devices?

  • From the information available, can't determine the reason for failure.

    Can you post the code?

  • Christopher Taylor97359 said:
    I believe that the transmission continues

    What steps have you taken to determine whether that belief is true or not?

  • OK, the code in its most basic form is attached below.  For various reasons I can tell that it works fine when I've got both wires connected:  the LED's on both LaunchPads go on at the end, and if I have the debugger hooked up to controller #2 and a breakpoint set at the point indicated in the code, I can see that the correct value (an arbitrary 0x66) has appeared in global "rxMsg".  But when the second wire is removed (#1-RX to #2-TX), the second controller hangs during the loop where it's waiting for the end-of-rx interrupt.  Meanwhile the LED has gone on on the first controller, suggesting that that controller is satisfied that it transmitted successfully.

    Thanks all,

    Christopher

    P.S. One of the many things I've tried is modifying the lines where I setup P1SEL and P1SEL2, in both routines.  I thought it might make sense to leave unset the bits corresponding to the line that has been disconnected;  but it didn't seem to help.

    // Simple version of code for simulation of the communication between microcontroller #1 & microcontroller #2.
    // The first main() routine and accompanying ISR's are for uc #1. This main() doesn't really get going
    // till user hits the Launchpad button on P1.3. Then we send out a 1-byte message via hardware
    // UART (on UCA0TXD = P1.2). After we get the end-of-tx interrupt, illuminate the LED on P1.6 for visual feedback and halt.
    // The second batch of routines is for uc #2. After setting up, it waits around for a transmission from #1 on
    // UCA0RXD(P1.1). Once the end of rx-interrupt occurs, we light the LED and halt.

    #include "msp430g2553.h"

    #define false 0
    #define true 1

    char txUnderway = false;
    char waitForButton = true;

    void main(void) {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    // Setup clock
    BCSCTL1 = CALBC1_1MHZ; // Initialize DCOCLK (1 MHz)
    DCOCTL = CALDCO_1MHZ;
    BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1MHz
    // Setup USCI for 115200 baud UART
    P1SEL = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2; // SMCLK
    UCA0BR0 = 8; // 1MHz 115200
    UCA0BR1 = 0; // 1MHz 115200
    UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5
    UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    IE2 |= UCA0TXIE; // Enable an interrupt for when the 1-byte transmission completes.
    // Configure Push Button (input on P1.3)
    P1DIR &= ~BIT3;
    P1OUT |= BIT3; // Enable pull-up
    P1REN |= BIT3; // resistor...
    P1IES |= BIT3; // Want an interrupt when P1.3 goes low...
    P1IFG &= ~BIT3;
    P1IE |= BIT3;
    // Ensure that the LED on P1.6 is off:
    P1DIR |= BIT6;
    P1OUT &= ~BIT6;

    // Initial loop: wait for a button press
    while (waitForButton)
    __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

    // Transmit!
    txUnderway = true;
    UCA0TXBUF = 0x66;
    while (txUnderway)
    __bis_SR_register(CPUOFF + GIE);

    // Illuminate LED and halt
    P1OUT |= BIT6;
    while (1)
    __bis_SR_register(CPUOFF + GIE);
    }

    // ISR for changes on port 1. Used while we're waiting for the initial button press
    #pragma vector=PORT1_VECTOR
    __interrupt void PORT1_ISR(void) {
    if (P1IFG & BIT3)
    waitForButton = false, // Got our button press!
    P1IE &= ~BIT3;
    P1IFG = 0;
    __bic_SR_register_on_exit(LPM3_bits); // Resume main() on return
    }

    // ISR for transmit complete
    #pragma vector=USCIAB0TX_VECTOR
    __interrupt void TX_ISR(void) {
    txUnderway = false;
    IFG2 &= ~UCA0TXIFG;
    __bic_SR_register_on_exit(LPM3_bits);
    }


    // ROUTINES FOR UC #2:

    char rxUnderway = false;
    char rxMsg;

    void main(void) {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    // Setup clock
    BCSCTL1 = CALBC1_1MHZ; // Initialize DCOCLK (1 MHz)
    DCOCTL = CALDCO_1MHZ;
    BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1MHz
    // Setup USCI for 115200 baud UART
    P1SEL = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2; // SMCLK
    UCA0BR0 = 8; // 1MHz 115200
    UCA0BR1 = 0; // 1MHz 115200
    UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5
    UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    IE2 |= UCA0RXIE; // Enable an interrupt each time a byte reception completes.
    // Ensure that the LED on P1.6 is off:
    P1DIR |= BIT6;
    P1OUT &= ~BIT6;

    rxUnderway = true;
    while (rxUnderway)
    __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

    // Turn on LED and halt
    P1OUT |= BIT6; // BREAKPOINT HERE TO TEST rxMsg
    while (1)
    __bis_SR_register(CPUOFF + GIE);
    }

    // ISR for receive complete
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void RX_ISR_MASTER(void) {
    rxUnderway = false;
    rxMsg = UCA0RXBUF; // Reading this clears IFG2.UCA0RXIFG
    __bic_SR_register_on_exit(LPM3_bits);
    }
  • The code looks good. And for the second (receiver) it shouldn't make any difference whetehr its TX is connected to the senders rx or not.

    So I think it is a hardware problem. Two possibilities: there is no common GND between the two (so the second connection is required for the current backflow, resulting an a more coincidentally working connection), or you twisted RX and TX and when you think you open the not needed connection, you're in fact breaking up the needed one. Sounds silly, but has happened for the most experienced people.

  • Thanks for thinking the situation over.  I had an electronics buddy look over my setup, and sure enough I didn't have the grounds hooked up right.  Guess that's what happens when programmers get started in this business...

  • Christopher Taylor97359 said:
    Guess that's what happens when programmers get started in this business...

    Things liek this happen. At least you had a GND connection (even if defective).

    I've seen people believing that a 1-wire interface really needs only one wire, so they connected two completely independent modules (with own power supplies) with exactly one wire and wondered why it didn't work.

**Attention** This is a public forum