STM32F4與NRF52 SPI通信

STM32F4 SPI slave與NRF52 SPI mater通信

SPI通信注意幾個設置,設置好基本沒啥問題

1、硬件布板時,SPI的幾根線阻抗要基本一致,時鐘線與數據的長度不能相差太多,布板時線不能太繞

2、SPI線要對應接對

3、兩邊的SPI模式、MSB、頻率等要設置一致

我這邊SPI設置的模式是11模式,即SPI_CPOL_High,SPI_CPHA_2Edge。

void SPI_BLE_Slave_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
    

    SPI_Cmd(BLE_SPI, DISABLE);
    SPI_I2S_DeInit(BLE_SPI);
  /* ʹÄÜ BLE_SPI ¼°GPIO ʱÖÓ */
  /*!< SPI_BLE_SPI_CS_GPIO, SPI_BLE_SPI_MOSI_GPIO, 
       SPI_BLE_SPI_MISO_GPIO,SPI_BLE_SPI_SCK_GPIO ʱÖÓʹÄÜ */
  RCC_AHB1PeriphClockCmd (BLE_SPI_SCK_GPIO_CLK | BLE_SPI_MISO_GPIO_CLK|BLE_SPI_MOSI_GPIO_CLK|BLE_CS_GPIO_CLK, ENABLE);

  /*!< SPI_BLE_SPI ʱÖÓʹÄÜ */
  BLE_SPI_CLK_INIT(BLE_SPI_CLK, ENABLE);
 
  //ÉèÖÃÒý½Å¸´ÓÃ
  GPIO_PinAFConfig(BLE_SPI_SCK_GPIO_PORT,BLE_SPI_SCK_PINSOURCE,BLE_SPI_SCK_AF); 
    GPIO_PinAFConfig(BLE_SPI_MISO_GPIO_PORT,BLE_SPI_MISO_PINSOURCE,BLE_SPI_MISO_AF); 
    GPIO_PinAFConfig(BLE_SPI_MOSI_GPIO_PORT,BLE_SPI_MOSI_PINSOURCE,BLE_SPI_MOSI_AF); 
  
  /*!< ÅäÖà SPI_BLE_SPI Òý½Å: SCK */
  GPIO_InitStructure.GPIO_Pin = BLE_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
  
  GPIO_Init(BLE_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
  
    /*!< ÅäÖà SPI_BLE_SPI Òý½Å: MISO */
  GPIO_InitStructure.GPIO_Pin = BLE_SPI_MISO_PIN;
  GPIO_Init(BLE_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
  
    /*!< ÅäÖà SPI_BLE_SPI Òý½Å: MOSI */
  GPIO_InitStructure.GPIO_Pin = BLE_SPI_MOSI_PIN;
  GPIO_Init(BLE_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);  

    /*!< ÅäÖà SPI_BLE_SPI Òý½Å: CS */
  GPIO_InitStructure.GPIO_Pin = BLE_CS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_Init(BLE_CS_GPIO_PORT, &GPIO_InitStructure);

//  /* Í£Ö¹ÐźÅBLE: CSÒý½Å¸ßµçƽ*/
//  SPI_BLE_CS_HIGH();

  /* BLE_SPI ģʽÅäÖà */
  // BLEоƬ Ö§³ÖSPIģʽ0¼°Ä£Ê½3£¬¾Ý´ËÉèÖÃCPOL CPHA
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;//SPI從機,此處是SPI_NSS_Hard
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(BLE_SPI, &SPI_InitStructure);
    /* NVIC Init */
    NVIC_config();    
    printf("\r\nNVIC_config!\r\n");    
    
    SPI_I2S_ITConfig(BLE_SPI,SPI_I2S_IT_RXNE, ENABLE);    
//    SPI_SSOutputCmd(BLE_SPI, DISABLE);
  /* ʹÄÜ BLE_SPI  */
    printf("\r\nSPI_Cmd!\r\n");    
  SPI_Cmd(BLE_SPI, ENABLE);

}

void SPI5_IRQHandler(void) 
{
    uint8_t spi_data;
    /* ½ÓÊÕÖÐ¶Ï */
    if(SPI_I2S_GetITStatus(BLE_SPI, SPI_I2S_IT_RXNE) == SET)
    { 
//        /* ½ÓÊÕµ½Êý¾Ý */
        while(SPI_I2S_GetFlagStatus(BLE_SPI, SPI_I2S_FLAG_RXNE) == RESET);
        dataBuff_flag = true;
        
        spi_data = SPI_I2S_ReceiveData(BLE_SPI);
        
        RecvSpiDataBuf[spiDataLen] = spi_data;//SPI_I2S_ReceiveData(BLE_SPI);
        spiDataLen++;
        
        if(spiDataLen>MAX_DATA_HANDLE_LEN) spiDataLen = 0;

        while(SPI_I2S_GetFlagStatus(BLE_SPI, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(BLE_SPI, SPI_RX_STA);
        /* Çå³ý½ÓÊÕÖÐ¶Ï */
        SPI_I2S_ClearITPendingBit(BLE_SPI, SPI_I2S_IT_RXNE);
    } 

}

NRF52 SPI Master程序

void ble_spi_init(void)
{
        uint32_t err_code = NRF_SUCCESS;
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = SPI_SS_PIN;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin  = SPI_SCK_PIN;

        err_code = nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_INFO("SPI example started.");
//        nrf_gpio_cfg_output(SPI_SS_PIN);
        SPI_CS_HIGH();
}

void ble_spi_send_data(uint8_t *tx_buf,uint16_t length)
{
    uint32_t err_code = NRF_SUCCESS;
    uint8_t recv;
    
    SPI_CS_LOW();
    spi_xfer_done = false;
    err_code = nrf_drv_spi_transfer(&spi, tx_buf, length, &recv, 1);
    APP_ERROR_CHECK(err_code);
    while(!spi_xfer_done);
    SPI_CS_HIGH();
}

以上程序測試沒有問題,其中的一個項目就是用的這個程序。

爲什麼不選STM32F4 SPI Mater,而NRF52 SPI 選Slave呢?主要還是爲了控制方便,STM32F4這邊的數據主要是通過NRF52通過SPI發送過來的,NRF52接收到藍牙數據就通過SPI發送給STM32F4,STM32F4接收到數據,響應應答就可。而且NRF52的接收緩存也不需要很大。

       但如果選STM32F4 SPI Mater,而NRF52 SPI 選Slave,NRF52就不會主動的發數據給STM32F4,而需要STM32F4請求數據,然後NRF52再返回對應的數據,很可能NRF52接收的緩存存滿了,都還來請求數據。

      當然最主要的還是要看怎麼控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章