在half-duplex/simplex模式STM32F4中停用SPI的正确方法

Correct way to deactivate SPI in half-duplex/simplex mode STM32F4

我正在尝试在一定时间后将 STM32F4 从从机更改为主机,以主机身份发送消息,然后返回到从机。我发现将 SPI 配置为 slave_rxonly 并启用 SPI 将导致时钟在我将设备配置回主控时意外发送时钟。没有我发送任何数据。我假设是因为我错误地初始化了外围设备或错误地取消了它

这是我的主循环。

  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
      MX_SPI1_Init(); /* This configures master */
      HAL_Delay(10);
 
      sendHelloWorld();
      configSlave(); /* Configures slave mode */
      __HAL_SPI_ENABLE(&hspi1); /* Enabling the device in this mode generates a continous clock during master init */
 
      HAL_Delay(100);
 
      HAL_SPI_DeInit(&hspi1);   /* Disables SPI and de-initializes the peripheral */
  }

我的主配置:

  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();
  }

我的奴隶配置:

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();
    }
 
}

这是我的逻辑分析仪的波形。一旦我 运行 函数 MX_SPI1_Init() 在启用 SPI 作为从设备后,就会生成时钟。橙色是时钟,正如您所见 - 从 10 毫秒的延迟开始 - 它在初始化为主机后立即启用。

有什么想法吗?我已经为这个问题奋斗了一个多星期,并尝试了很多东西

可能是垃圾HAL函数不小心暂时变成了master rx-only。各种 HAL 函数在写入寄存器的顺序上都很幼稚,并会产生这样的故障。在重新配置之前尝试调用 HAL_SPI_DeInit。或者干脆放弃 HAL。

Master RX-only 总是要盲目输出时钟。如果您想控制何时发送时钟,请使用主 tx 和 rx 模式,然后写入与您要读取的相同数量的虚拟数据。如果您希望 MOSI 保持三态并且不发送虚拟数据,那么您可以在执行此操作时将引脚更改为 GPIO 模式。