Beginner MSP430SPI communication

Made a simple translation of the User's guide and added some of my own understanding.
I have written SPI with analog IO before, and today I will try to learn the built-in SPI module
1. Basic
1.1 SPI operation mode
 In SPI mode, serial data will be accepted by multiple devices through a shared clock provided by the master and send. An additional pin, UCxSTE, provides transmit and transmit enable.
 Three or four pins can be set for SPI data exchange
 UCxSIMO: slave in, master out
 UCxSOMI: slave out, master in
 UCxCLK: SPI clock
 UCxSTE: slave transfer enable
  when four pins are enabled Multiple devices share one bus, not used in 3-pin mode
1.2 SPI initialization and reset
  are the same as UART settings, USCI is reset by PUC or UCSWRST. When configuring, first UCSWRST=1, then configure the port, then UCSWRST=0, and finally enable the interrupt.
1.3 Master mode (Master mode)
   The schematic diagram of both master mode and slave mode is very simple...
insert image description here
1.4 Slave mode
insert image description here
1.5 Transmit enable and receive enable
 In master mode, when data is written into UCxTXBUF, the clock is generated, Data transfer starts.
 In slave mode, transfers occur when the master provides the clock.
 The SPI accepts data when a transmit is enabled, and the receive and transmit can occur simultaneously.
1.6 Clock control.
 UCxCLK is provided by the host, when UCMST=1, bit CLK is provided by UCxCLK pin. When UCMST=0, the clock is provided by the master (this time it is a slave). When transmitting, both sending and receiving use the same clock and the same speed.
16-bit clock rate control registers: UCxxBR1 and BR0, same as UART mode. But this is bit clkock. Modulation is not needed in SPI mode. In USCI_A, UCAxMTL should be cleared.
 The calculation formula is:
 fbit-clock=fBRCLK/UCBRx

1.7 Polarity and phase
insert image description here
 SPI has four modes, the difference is polarity and phase, which can be simply regarded as the difference between transmitting or receiving data at the rising or falling edge.
 For details, you can go to this blog https://www.cnblogs.com/shangdawei/p/4752476.html,
 which is very clear.
 We only need to pay attention to the UCCKPH UCCKPL in this, which determines how the data is transmitted. When looking at the data sheet of the component, you need to observe the given timing diagram to determine how to configure it.
1.8 Interrupt
 The interrupt is basically similar to UART, which was mentioned when writing UART before.

2. Register
 This is not the same as the register that UART needs to configure, but the difference is mainly on CTL0.
2.1UCAxCTL0
  UCCKPH, UCCKPL, timing configuration.
  UCMSB: Transmit from LSB or MSB when transmitting
  UC7BIT: Select seven-bit data or eight-bit data
  UCMST: Select master or slave
  UCMODEx: Three-pin four-pin mode selection
  UCSYNC: Communication mode, 0 for asynchronous communication (UART)
            1 for Synchronous communication (SPI)
       must be configured as 1 at this time.
  Others are relatively simple and will not be described in detail.
Third, the code can look at the routine.
The routine is also relatively simple, you can use two 430 microcontrollers for SPI communication experiments.
(A specific example may be placed in a few days)

/*
MSP430F55xx_uscia0_spi_09
主机模式
主机发送一个数据,从机返回,用LED来表征
*/
#include <msp430.h>

unsigned char MST_Data,SLV_Data;
unsigned char temp;

int main(void)
{
  volatile unsigned int i;

  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

  P1OUT |= 0x02;                            // Set P1.0 for LED
                                            // Set P1.1 for slave reset
  P1DIR |= 0x03;                            // Set P1.0-2 to output direction
  P3SEL |= BIT3+BIT4;                       // P3.3,4 option select
  P2SEL |= BIT7;                            // P2.7 option select
  
  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 |= UCRXIE;                         // Enable USCI_A0 RX interrupt

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

  for(i=50;i>0;i--);                        // Wait for slave to initialize

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

  while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
  UCA0TXBUF = MST_Data;                     // Transmit first character

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

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  volatile unsigned int i;

  switch(__even_in_range(UCA0IV,4))
  {
    case 0: break;                          // Vector 0 - no interrupt
    case 2:                                 // Vector 2 - RXIFG
      while (!(UCA0IFG&UCTXIFG));           // USCI_A0 TX buffer ready?

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

      MST_Data++;                           // Increment data
      SLV_Data++;
      UCA0TXBUF = MST_Data;                 // Send next value

      for(i = 20; i>0; i--);                // Add time between transmissions to
                                            // make sure slave can process information
      break;
    case 4: break;                          // Vector 4 - TXIFG
    default: break;
  }
}

//

/*
MSP430F55xx_uscia0_spi_10
从机模式
将主机传来的数据发送回去
*/
#include <msp430.h>

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

  while(!(P2IN&0x80));                      // If clock sig from mstr stays low,
                                            // it is not yet in SPI mode
  P3SEL |= BIT3+BIT4;                       // P3.3,4 option select
  P2SEL |= BIT7;                            // P2.7 option select
  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL0 |= UCSYNC+UCCKPL+UCMSB;          // 3-pin, 8-bit SPI slave,
                                            // Clock polarity high, MSB
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4, enable interrupts
}

// Echo character
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(UCA0IV,4))
  {
    case 0:break;                             // Vector 0 - no interrupt
    case 2:                                   // Vector 2 - RXIFG
      while (!(UCA0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
      UCA0TXBUF = UCA0RXBUF;
      break;
    case 4:break;                             // Vector 4 - TXIFG
    default: break;
  }
}

Guess you like

Origin blog.csdn.net/PolypolyA/article/details/100998521