天天看点

CC3200 与 CC2530的SPI通信

目的:实现CC2530作为master,CC3200作为slave的SPI 通信

连接图如下

/*——————————————————————————–

Master Slave

————- ————-

| | | |

|P1_4 SSN |———>|SSN 8|

| | | |

|P1_5 SCK |———>|SCK 5|

| | | |

|P1_6 MOSI|———>|MOSI 7|

| | | |

|P1_7 MISO|<———|MISO 6|

| | | |

—-CC2530——— ——CC3200——-

硬件连接图:

CC3200 与 CC2530的SPI通信

过程:

CC2530方面:

基本的SPI初始化:

void init_port(void)
{
   IO_FUNC_PORT_PIN(, , IO_FUNC_GIO);    //将P1_0设置为普通的IO口
   IO_DIR_PORT_PIN(, , IO_OUT);          //设置为输出

   IO_FUNC_PORT_PIN(, , IO_FUNC_GIO);    //将P1_1设置为普通的IO口
   IO_DIR_PORT_PIN(, , IO_OUT);          //设置为输出

   PERCFG |= ;        // PERCFG.U1CFG = 1 
   P1SEL |= ;         // P1_7, P1_6, and P1_5 are peripherals 
   P1SEL &= ~;        // P1_4 is GPIO (SSN) 
   P1DIR |= ;         // SSN is set as output 
           

主要看时间相位,极性,MSB first or LSB first,波特率的设置。作为主设备,要为从设备提供时钟,而且决定了从设备的波特率

void init_Baudrate(void)
{
  // Set baud rate to max (system clock frequency / 8) 
  // Assuming a 26 MHz crystal (CC1110Fx/CC2510Fx), 
  // max baud rate = 26 MHz / 8 = 3.25 MHz.  
  //U1BAUD = 0x00;   // BAUD_M = 0 
  //U1GCR |= 0x11;   // BAUD_E = 17
  U1BAUD = ;   // BAUD_M = 59  9600 F=32M
  U1GCR |= ;   // BAUD_E = 8
}
           

这里CC2530的晶振是选择了32M的,波特率设为9600,关于波特率的设置,可以查看用户手册。

下面分析主函数

void main(void)
{
  halMcuInit();  // 选择32MHz晶体振荡器作为系统时钟源(主时钟源)//设置时钟源32MHZ
  init_port();      //初始化端口
  init_Baudrate();  //初始化波特率


  // SPI Master Mode 
  U1CSR &= ~;   //选择为SPI为Master

  **//注意相位,极性,和MSB的设置,因为在从设备上要设置为一样的。**
  // Configure phase, polarity, and bit order 
  U1GCR &= ~;      // CPOL = CPHA = 0 SHANG SHENG YAN CAI YANG
  U1GCR |= ;       // ORDER = 1  MSB first


  LED1=;

  unsigned char i;
  char txBufferMaster[]="hello world";
  while()
  {
    for (i = ; i <= sizeof(txBufferMaster); i++) 
    { 
      SSN = LOW; 
      U1DBUF = txBufferMaster[i]; //加入要发送的数据
      while (!U1TX_BYTE); 
      SSN = HIGH; 
      U1TX_BYTE = ;
    }
    LED1=~LED1;
    halMcuWaitMs();
  }
}
           

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

下面分析从设备的设置

主要就是SPI的初始化要与主设备相匹配,然后在接受到数据之后,通过串口打印出来,已验证是否接受成功。

//*****************************************************************************
void SlaveMain()
{
    //
    // Initialize the message
    //
    memcpy(g_ucTxBuff,SLAVE_MSG,sizeof(SLAVE_MSG));

    //
    // Set Tx buffer index
    //
    ucTxBuffNdx = ;
    ucRxBuffNdx = ;

    //
    // Reset SPI
    //
    MAP_SPIReset(GSPI_BASE);

    //
    // Configure SPI interface
    //
   /* MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
                     SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
                     (SPI_HW_CTRL_CS |
                     SPI_4PIN_MODE |
                     SPI_TURBO_OFF |
                     SPI_CS_ACTIVEHIGH |
                     SPI_WL_8));
    */
    //注意,片选为软件控制SPI_SW_CTRL_CS,低电平有效SPI_CS_ACTIVELOW,且CC3200的spi为MSB first
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
                     SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
                     (SPI_SW_CTRL_CS |
                     SPI_4PIN_MODE |
                     SPI_TURBO_OFF |
                     SPI_CS_ACTIVELOW |
                     SPI_WL_8));
    //
    // Register Interrupt Handler
    //
    MAP_SPIIntRegister(GSPI_BASE,SlaveIntHandler);

    //
    // Enable Interrupts
    //
    MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);

    //
    // Enable SPI for communication
    //
    MAP_SPIEnable(GSPI_BASE);

    //
    // Print mode on uart
    //
    Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
}

//*****************************************************************************
在从设备中,采用中断方式,当接受寄存器满了之后,就将数据读取,并通过串口打印出来。
           

//*******************************************************************

//

//! SPI Slave Interrupt handler

//!

//! This function is invoked when SPI slave has its receive register full or

//! transmit register empty.

//!

//! \return None.

//

//*******************************************************************

static void SlaveIntHandler()

{

unsigned long ulRecvData;

unsigned long ulStatus;

ulStatus = MAP_SPIIntStatus(GSPI_BASE,true);

MAP_SPIIntClear(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);

/*if(ulStatus & SPI_INT_TX_EMPTY)
{
    MAP_SPIDataPut(GSPI_BASE,g_ucTxBuff[ucTxBuffNdx%TR_BUFF_SIZE]);
    ucTxBuffNdx++;
}
*/
if(ulStatus & SPI_INT_RX_FULL)
{
    MAP_SPIDataGetNonBlocking(GSPI_BASE,&ulRecvData);
    g_ucTxBuff[ucRxBuffNdx%TR_BUFF_SIZE] = ulRecvData;
    Report("%c",ulRecvData);
    ucRxBuffNdx++;
}
           

}

//*******************************************************************

至此,基本实现了二者的通信。
![传送:hello world](https://img-blog.csdn.net/20161201214236768)
           

在实现SPI通信的过程中,遇到的问题:

1、硬件上,一定要确认好连接通了,连接对了,MISO与MISO连接

2、一开始以为从设备也要设置波特率,一直找不到怎么设置,其实从设备的波特率有主设备决定

3、把波特率调到9600做实验,会好些

后记:现在看起来,这玩意虽然很简单,不过的确是我搞通的一次信息传输,所以值得纪念。接下里,还有更多的功能要去探究和学习,从浅到深,加油!

继续阅读