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.

MSP430G2553 Serial ADC Trouble

Other Parts Discussed in Thread: MSP430G2553, ADS8321


I am new to the MSP430 and I was hoping someone could help me out a bit. I'm trying to connect a SPI ADC (ADS8321) to a MSP430G2553 on the LaunchPad (I really want to learn the way to set up SPI, and I have the ADC). I've been trying to go through the code examples available to learn about SPI and UART, and I'm trying to put two of them together to allow UART to communicate on USCIA0 and SPI with the ADC on USCIB0.  The LED on P1.0 is blinking sporadically and as the input changes, which leads me to believe that something is working. My UART_tx() function also gives me a signel "y" character with an umlaut on it. Again, I'm new to this and any suggestions would be helpful and appreciated!

#include <msp430.h>

unsigned char MST_Data, SLV_Data, txData;

void UART_tx(unsigned char byte);

int main(void)
  volatile unsigned int i;

	WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

	//Pin Setup
	P1OUT = BIT1;                             // P1 setup for LED & reset output
	P1DIR |= BIT1 + BIT0;              		  //P1.1 for UART_Tx, BIT0 for LED and BIT4 for
	P1SEL = BIT1 + BIT5 + BIT6 + BIT7;
	P1SEL2 = BIT5 + BIT6 + BIT7;

	//Setup SPI on USCI_B0
	UCB0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC;  // 3-pin, 8-bit SPI master
	UCB0CTL1 |= UCSSEL_2;                     // SMCLK
	UCA0BR0 |= 0x02;                          // /2
	UCA0BR1 = 0;                              //
	UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
	IE2 |= UCB0RXIE;                          // Enable USCI0 RX interrupt

	//Setup UART on USCI_A0
	UCA0CTL1 |= UCSSEL_2; 					  // SMCLK
	UCA0BR0 = 104; 							  // 1MHz/9600 = 104.., lower 8 bit (UCA0BR = 16bit long)
	UCA0BR1 = 0; 							  // 1MHz/9600 = 104.., higher 8 bit
	UCA0MCTL = UCBRS0; 						  // Modulation UCBRSx = 1
	TA0CCTL0 = OUT;							  //Timer for transmit UART operation
	TA0CCTL1 = SCS + CM1 + CAP;				  //Set TXD Idle as Mark = '1'
	TA0CTL = TASSEL_2 + MC_2;				  //SMCLK, start in continuous mode

	P1OUT &= ~BIT7;                           // Now with SPI signals initialized,
	P1OUT |= BIT7;                            // reset slave

	__delay_cycles(75);                 	  // Wait for slave to initialize

	MST_Data = 0x01;                          // Initialize data values
	SLV_Data = 0x00;

	UCB0TXBUF = MST_Data;                     // Transmit first character

	__bis_SR_register(LPM0_bits + GIE);       // CPU off, enable interrupts


//UART Transmit
void UART_tx(unsigned char byte){		//Outputs one byte using the Timer_A UART

	while(TACCTL0 & CCIE);		//Ensure last char got TX'd
	TA0CCR0 = TAR;				//Current state of the TA counter
	TA0CCR0 += 104;				//One bit time till first bit
	txData = byte;				//Load transmit data, e.g. 'A' = 01000001
	txData |= 0x100;			//Add mark stop bit, e.g. 101000001
	txData <<= 1;				//Add space start bit, e.g. 1010000010
	TA0CCTL0 = OUTMOD0 + CCIE;	//Set TXD on, enable counter interrupt

// Test for valid RX and TX character
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIA0RX_ISR(void)
  volatile unsigned int i;

  while (!(IFG2 & UCA0TXIFG));              // USCI_B0 TX buffer ready?

  if (UCB0RXBUF == SLV_Data)                // Test for correct character RX'd
    P1OUT |= BIT0;                          // If correct, light LED
    P1OUT &= ~BIT0;                         // If incorrect, clear LED

  UCB0TXBUF = MST_Data;                     // Send next value

  __delay_cycles(50);                     // Add time between transmissions to
}                                           // make sure slave can keep up

  • P1SEL = BIT1 + BIT5 + BIT6 + BIT7;
    P1SEL2 = BIT5 + BIT6 + BIT7;

    Hmmm, you set P1.1 to TA0.0 output. Also, your UART_tx funciton is set up for timer-based software UART. Why that? THe USCI has a hardware UART module that does all this for you. In this case, UCA0TX is on P1.2
    Nevertheless, your posted code does not contain any ISR for the software UART. You enable the timer interrupt (TA0CCTL0 = OUTMOD0 + CCIE;) but when a bit is sent and the timer calls for its ISR, the CPU jumps into the void, eventually resetting the MSP.
    Effectively, you only send a start bit and then the PC will receive garbage as the MSP resets.

    BTW: your RX ISR won't work too. It was written for an UART eacho (byte received from PC-> return it to PC). You really shouldn't busy-wait for TXIFG inside the RX ISR. That's a death sin and even superfluous for the demo code and dangerous (wasted time) in a generic RX ISR.

    But there is more:

        UCB0CTL1 |= UCSSEL_2;                     // SMCLK
        UCA0BR0 |= 0x02;                          // /2
        UCA0BR1 = 0;                              //
        UCB0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**

    Don't you think it should read "UCB0BR0"?

    And for UCA0, you never clear SWRST.

    And there's much more.

    It really looks like you have copied code snippets from many different code samples together without really understanding what they do.
    The code samples are no libraries where you can simply copy the code into your project. They are samples that show you how a specific applicaiton could be implemented, in order to help you understand how things work (in conjunciton with the users guide). They shall enable you to write your own code based on the insights you got by understanding the samples.

  • Thanks for your response, Jens! Again, I'm new to the MSP430 and I'm trying to get a handle on everything through experimenting with what I've read about. Over the past few days I've better defined what I want to do with the UART/SPI interface and how the MSP430 could handle it and I think I'm getting the hang of it. Again I appreciate your help! Thanks!

**Attention** This is a public forum