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 SPI master mode

Other Parts Discussed in Thread: MSP430G2553

I have a question about this code. I was trying to use the demo to setup an msp430g2553 as an spi master. But, I also added code so that the uC will wait until the button is pressed. I tried running the code, but it gets stuck waiting for the button press and nothing happens when I press the button.

Here is my code:

//SPI Master Test script

#include "msp430g2553.h"

unsigned char MST_Data, SLV_Data;

void main(void)
{
volatile unsigned int i;

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1OUT &= ~BIT0 + ~BIT1 + ~BIT2 + ~BIT4 + ~BIT5 + ~BIT6; // P1 setup for LED & reset output
P1DIR |= BIT0 + BIT5 + BIT6; //
P1SEL = BIT1 + BIT2 + BIT4;
P1SEL2 = BIT1 + BIT2 + BIT4;

//code for button interrupt

P1DIR &= ~BIT3;
P1SEL &= ~BIT3; // Select Port 1 P1.3 (push button)
P1REN |= BIT3; // Enable Port P1.3 (push button) pull-up resistor
P1IE |= BIT3; // Port 1 Interrupt Enable P1.3 (push button)
P1IFG &= ~BIT3; // Clear interrupt flag


__bis_SR_register(LPM0_bits + GIE); // wait for button interrupt

UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 |= 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI0 RX interrupt
P1OUT |= BIT6;

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

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

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

UCA0TXBUF = MST_Data; // Transmit first character

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

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

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

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

MST_Data++; // Increment master value
SLV_Data++; // Increment expected slave value
UCA0TXBUF = MST_Data; // Send next value

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

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {

P1IFG &= ~0x08; // P1.3 Interrupt Flag cleared
_bic_SR_register_on_exit(LPM0_bits);
}

  • First thing is that you configure the pullup on teh pushbutton pin as pulldown. To make it a pullup, you'll have to set P1OUT |= BIT3.

    But another problem is this one:

    Stuart Miller said:
    P1OUT &= ~BIT0 + ~BIT1 + ~BIT2 + ~BIT4 + ~BIT5 + ~BIT6; // P1 setup for LED & reset output

    It surely won't do what you think it should.

    ~BIT1 is 0xFFFE, ~BIT2 is 0xFFFD etc. If you ADD all these values, you'll get something, but not what you want.

    Make it

    P1OUT &= ~(BIT0|BIT1|BIT2|BIT4|BIT5|BIT6).

    Don't use an arithmetic operator like + on a binary (bit logic) operation. It won't cause a compiler error since the compiler treatsbit values and numerical values as being the same, but in combinaiton with other bit operators like ~ or & or |. the outcome is often something completely different and unintended.

  • gud eve..

    Thn cud u say wats wrong in this code?

    Master code:

    #include "msp430g2553.h"
    unsigned int i=0;
    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD;

    P1DIR = 0X01;
    P1REN |= 0X08;
    P1OUT |= 0X08;
    P1SEL |= 0x16;
    P1SEL2 |= 0X16;

    UCA0CTL1 = UCSWRST+UCSSEL_2;
    UCA0CTL0 |= UCCKPL + UCMSB + UCSYNC+UCMST;
    UCA0CTL1 &= ~UCSWRST;
    while(1)
    {
    if((P1IN & 0X08)==0)
    UCA0TXBUF = 0X09;
    else
    UCA0TXBUF = 0X08;
    }
    }

    Slave Code:

    #include "msp430g2553.h"
    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD;

    P1DIR = 0X01;
    P1REN = 0X08;
    P1OUT - 0X08;
    P1SEL = 0X16;
    P1SEL2 = 0X16;

    UCA0CTL1 = UCSWRST+UCSSEL_2; // **Put state machine in reset**
    UCA0CTL0 |= UCCKPL + UCMSB + UCSYNC; // 3-pin, 8-bit SPI master
    UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    IE2 |= UCB0RXIE; // Enable USCI0 RX interrupt
    __bis_SR_register(LPM4_bits + GIE); // Enter LPM4, enable interrupts
    while(1)
    {
    }
    }

    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCI0RX_ISR (void)
    {
    // if((P1IN & 0X08)==0)
    // {
    if(UCA0RXIFG)
    P1OUT = UCA0RXBUF;
    // }
    }

  • Hi!

    You should describe your problem a little bit more in detail. And it would be nice if you could edit your post and insert code lines via the Syntaxhighlighter that is available in rich formatting mode.

    Dennis
  • I jus wanna interface switch with msp430g2553 using spi communication.

    I ve tried code of my own.

    The result I got was, slave red led was glowing and master was idle. When I press the switch there was no reaction...

    Could You please help me to get thru it..
  • There are several problems with your code.
    The once that stick out on first glance are:

    - The master just fires 0x08 or 0x09 into TXBUF, no matter whether a tranfer is alread ongoing or TCBUF is full. It also doesn't take care for input switch bouncing. This isn't critical for this simple application but will be for anythign beyond.
    - In the slave, you don't need to set UCCSEL_2, as the slave gets its clock from the master through P1.4/UCA0CLK.
    But more critical, is that you aparently use UCA0 on the slave too (at least you did set--up P1.2/P1.2 and P1.4 for module use) but you set UCB0RXIFG, not UCA0RXIFG. While UCB0 and UCA0 share the same interrupt vector, they do NOT use the same enable bit.
    And you probably meant 'P1OUT = 0x08;' not 'P1OUT-0x08;", which would be valid but meaningless and probably optimized-away code (except that it reads P1OUT, which may have a side-effect on some registers but not on P1OUT)
    You don't need to check for UCA0RXIFG inside the ISR - it is the only interrupt you can have in your application and if the ISR was entered, then this interrupt happened adn you got a byte.

    I don't know on which pin you have your glowing red LED. Or whether it is sourced/powered by the pin or drained by the pin. So I can't say anything about what it means when it is 'glowing'.
    And how do you know the master is idle? Did you check the signals on the bus lines? With the code you posted, the master can't be idle as it is constantly running circles in the while(1) loop, pushing 0x09 or 0x08 into TXBUF. Without ever waiting for anything.

**Attention** This is a public forum