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.

cc430f6137 spi

Other Parts Discussed in Thread: TMP124, CC430F6137

Hi! I'm programming cc430f6137 SPI to use micro as master and communicate with tmp124 temperature sensor. My problem is the clock UCA0CLK. On the clock spi PIN there's nothing. The code is the following:


#include <CC430F6137.h>

double received= 0;

void main(void)
{
  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

  PMAPPWD = 0x02D52;                        // Get write-access to port mapping regs 
  P2MAP0 = PM_UCA0SIMO;                     // Map UCA0SIMO output to P2.0
  P2MAP2 = PM_UCA0SOMI;                     // Map UCA0SOMI output to P2.2
  P2MAP4 = PM_UCA0CLK;                      // Map UCA0CLK output to P2.4
  PMAPPWD = 0;                              // Lock port mapping registers 
  
  P1DIR=0x80;
  P1OUT |= 0x80;                          
  P2SEL |= BIT0 + BIT2 + BIT4;
  P2DIR |= BIT0 + BIT2 + BIT4;             

  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;    // 3-pin, 8-bit SPI master
                                            // Clock polarity high, MSB
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 0x02;                           // /2
  UCA0BR1 = 0;                              //
  UCA0MCTL = 0;                             // No modulation
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCTXIE;
 __bis_SR_register(LPM0_bits + GIE);     

__delay_cycles(1000); 
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
  while(1)
  {
    P1OUT &= ~0x80;                           // Port 2.7
    P2SEL |= BIT0 + BIT2 + BIT4;
    while (!(UCA0IFG&UCTXIFG));            // USART0 TX buffer ready?
    received= UCA0RXBUF;
//  __delay_cycles(17);
    P1OUT |= 0x80;                            // Port 2.7
  __no_operation();
   }
 
}

thanks

Dan

 

  • First, when remapping function pins, you should disable the same fuinction on the original location. Jus tto be sure there are no locking effects.

    Dan MAz said:
      P1DIR=0x80;
      P1OUT |= 0x80;                          

    You should swap these lines or you might experience a low glitch on this line that maybe irritates the slave.

    Dan MAz said:
    __delay_cycles(1000); 

    Just for your info: don't set a breakpoint here - it will be triggered before the ISR is called and the LPM is entered. Insert a NOP before.

    Dan MAz said:
      while(1)

    THis causes an endless loop inside your ISR. the ISR will never exit, it will never 'wait' for another interrupt, it simply makes no sense.

    Dan MAz said:
    P1OUT &= ~0x80;                           // Port 2.7

    Some slaves require a certain minimum delay between asserting their CS signal and start of the transfer. You go straight on.

    Dan MAz said:
        P2SEL |= BIT0 + BIT2 + BIT4;

    This is superfluous, you already did it when initializing the SPI.

    Dan MAz said:
    P2DIR |= BIT0 + BIT2 + BIT4;             

    Not needed. The USCI controls the direction by itself. But it don't hurt. Luckily, as SOMI must be input and you set it to output.

    Dan MAz said:
    while (!(UCA0IFG&UCTXIFG));            // USART0 TX buffer ready?

    After clearing SWRST, this one is always set until you write something into TXBUF. And this is the cause why the ISR was entered at all. That's the reason why there are ISRs.

    Dan MAz said:
    received= UCA0RXBUF;

    Who said that there is data received? Nobody. You didn't check for UCRXIFG. So you read, well, something, a random value, garbage. Because...

    Dan MAz said:
    On the clock spi PIN there's nothing

    Why should it? If you check your code, you did nothing that tells the SUCI module to start receiving. Since SPI is synchronous and you're the master, you need to provide the clock for the transfer. And to do so, you must star tthe transfer. And this is done by writing something to TXBUF. MAybe a dummy value or a NOP command.

    This is how SPI works: you send something and you receive something. If you don't send, no clock impulses are generated and the slave won't send too.

    Dan MAz said:
        P1OUT |= 0x80;                            // Port 2.7

    Here you de-assert the slave CS signal. This happens immediately after you , well, not started the transfer. But if you had stasrted it, this would immediately stop the transfer again and render the slave silent. Surely not what you want. You need to check whether the transfer has finished by checking the UCBUSY bit. (well, since no transfer was ever started, this bit will be clear)

    How things work usually:

    in main, you configure the SPI hardware. If you only want to receive, you only activate the receive interrupt (UCRXIE). Then you assert CS, wait as the slave requires, then write something to TXBUF to start the transfer and go to sleep.

    The ISR is then called when a byte is received. It reads the byte into a global buffer, which must be declared volatile (so main will detect the change) and of course must not be a double type (RXBUF gives an unsigned cahr value). I fmore bytes are to be received, the ISR writes anothe rbyte to UCTXBUF and exits. If not, it clears UCRXIE (so no more interrupts are coming, well, they won't if nothing is written to TXBUF) and wakes up main from LPM.

    Main checks whether the transfer is complete (UCBUSY) and de-asserts CS and then uses whatever was received.


  • Thank you very much, sorry but i'm new to programming. Your explain is perfect.

    thanks

    Dan

**Attention** This is a public forum