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接收的缓存存满了,都还来请求数据。
当然最主要的还是要看怎么控制。