首页 > 解决方案 > 在运行时 STM32F4 使用 HAL 从 SPI Slave 更改为 Master

问题描述

我试图通过在准备发送消息时更改谁是主节点,使两个带有 HAL 的 STM32F4 通过 SPI Simplex 模式进行通信。两个平台都从从站开始,然后它们变为主站以发送消息,然后返回从站。

 while (1)
  {
      configSlave();

      while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_RX);
      HAL_SPI_Receive(&hspi1, (uint8_t *)buff, 13, 1000);       /* Including this line generates the issue */

      HAL_Delay(10);

      configMaster();
      
      HAL_Delay(10);

      sendHelloWorld();
      HAL_Delay(10);
  }

在不调用接收例程的情况下使用configMaster()after更改 SPI 配置效果很好。但是,如果我在两者之间添加接收例程,我的问题就来了。configSlave()HAL_SPI_Receive()

如果我HAL_SPI_Receive()在将节点更改为主节点时添加配置之间的内容,则节点将开始通过 CLK 引脚发送恒定时钟并将 DATA 引脚拉低,直到我发送 Hello World 消息。那么为什么会发生这种情况呢?是非初始化问题吗?

我确保在重新配置到每种模式之前取消初始化 SPI 外设,并通过调试模式检查 SPI 寄存器在取消初始化期间是否为 0。同样,我确保每次全局 SPI 处理程序都重置为 0,这样它就不会保留其他模式的某些配置。

在此处输入图像描述

供参考,这些是我的configMaster()configSlave()例程

static void configMaster(void)
{
    if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
    {
        memset(&hspi1, 0, sizeof(SPI_HandleTypeDef));

        /* SPI1 parameter configuration*/
        hspi1.Instance = SPI1;
        hspi1.Init.Mode = SPI_MODE_MASTER;
        hspi1.Init.Direction = SPI_DIRECTION_2LINES;
        hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
        hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
        hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
        hspi1.Init.NSS = SPI_NSS_SOFT;
        hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
        hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
        hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
        hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
        hspi1.Init.CRCPolynomial = 10;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
        {
            Error_Handler();
        }
    }
}

static void configSlave(void)
{
    if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
    {
        /* SPI1 parameter configuration*/
        hspi1.Instance = SPI1;
        hspi1.Init.Mode = SPI_MODE_SLAVE;
        hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
        hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
        hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
        hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
        hspi1.Init.NSS = SPI_NSS_SOFT;
        hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
        hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
        hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
        hspi1.Init.CRCPolynomial = 10;

        if (HAL_SPI_Init(&hspi1) != HAL_OK)
        {
            Error_Handler();
        }

    }
}

主机开始发送时钟的确切点也发生在这里:HAL_SPI_Init()

  /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
  /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
  Communication speed, First bit and CRC calculation state */
  WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
                                  hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
                                  hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation));

欢迎任何建议。谢谢

标签: armstm32communicationspihal

解决方案


推荐阅读