是否有HAL库ISR功能,当STM32L4xx上SPIx的接收缓冲区接收到字节时,该功能会自动触发?

是否有HAL库ISR功能,当STM32L4xx上SPIx的接收缓冲区接收到字节时,该功能会自动触发?,stm32,spi,hal,isr,nucleo,Stm32,Spi,Hal,Isr,Nucleo,我想知道在HAL库中是否有一个用户可定义的内置ISR函数,该函数在STM32L4xx MCU的SPIx Rx缓冲区中接收到一个字节后立即触发?例如,作为启动测试,我想通过SPI2将一个字节(0xBC)从主STM32L452核子板发送到从STM32L452核子板。一旦从板接收到字节,它将闪烁LED2,并将另一个字节(0xCD)发送回主板。一旦主机收到字节,它将闪烁LED2作为确认。我已将两个板初始化为主/从板,启用DMA和全局中断,使用MXcube每次传输8位。我可以使用HAL_SPI_Trans

我想知道在HAL库中是否有一个用户可定义的内置ISR函数,该函数在STM32L4xx MCU的SPIx Rx缓冲区中接收到一个字节后立即触发?例如,作为启动测试,我想通过SPI2将一个字节(0xBC)从主STM32L452核子板发送到从STM32L452核子板。一旦从板接收到字节,它将闪烁LED2,并将另一个字节(0xCD)发送回主板。一旦主机收到字节,它将闪烁LED2作为确认。我已将两个板初始化为主/从板,启用DMA和全局中断,使用MXcube每次传输8位。我可以使用HAL_SPI_Transmit_DMA()和HAL_SPI_Receive_DMA()函数以及写入主例程的while(1)部分的延迟来实现我想要的(如下所示)。但是,我希望使用ISR函数实现同样的功能,该函数在SPI Rx缓冲区接收到字节后自动执行

主代码:

   uint8_t spiDataReceive = 0;
   uint8_t spiDataTransmit = 0xBC;

   while(1) {
       if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
             //Transmit byte 0xBC to Slave and Receive Response
             HAL_SPI_Transmit_DMA(&hspi2, &spiDataTransmit, 1);
             HAL_Delay(20);
             HAL_SPI_Receive_DMA(&hspi2, &spiDataReceive, 1);

             if(spiDataReceive == 0xCD) {
                 flashLED2();
                 spiDataReceive = 0x00;
             }
        }
   }
 uint8_t spiDataReceive = 0;
 uint8_t spiDataTransmit = 0xCD;

 while(1) {
      HAL_SPI_Receive_DMA(&hspi2, &spiDataReceive, 1);
      HAL_Delay(10);

      if(spiDataReceive == 0xBC) {
         HAL_SPI_Transmit_DMA(&hspi2, &spiDataTransmit, 1);
         flashLED2();
         spiDataReceive = 0x00;
      }
 }
从代码:

   uint8_t spiDataReceive = 0;
   uint8_t spiDataTransmit = 0xBC;

   while(1) {
       if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
             //Transmit byte 0xBC to Slave and Receive Response
             HAL_SPI_Transmit_DMA(&hspi2, &spiDataTransmit, 1);
             HAL_Delay(20);
             HAL_SPI_Receive_DMA(&hspi2, &spiDataReceive, 1);

             if(spiDataReceive == 0xCD) {
                 flashLED2();
                 spiDataReceive = 0x00;
             }
        }
   }
 uint8_t spiDataReceive = 0;
 uint8_t spiDataTransmit = 0xCD;

 while(1) {
      HAL_SPI_Receive_DMA(&hspi2, &spiDataReceive, 1);
      HAL_Delay(10);

      if(spiDataReceive == 0xBC) {
         HAL_SPI_Transmit_DMA(&hspi2, &spiDataTransmit, 1);
         flashLED2();
         spiDataReceive = 0x00;
      }
 }

不需要图书馆。您需要在SPI CR寄存器中设置RNIE位,并在NVIC中启用中断。2行代码。不需要图书馆


唯一需要的资源是STM网站上的参考手册。

是的,HAL提供用户回调。为了使用它们,您必须在NVIC中激活相应的中断,并让中断向量表调用HAL处理程序(也请查看
stm32l4xx_it.c

<>但是在你这样做之前,你应该考虑以下问题:

  • 如果您对ST HAL图书馆的复杂性感到困惑或沮丧,请阅读参考手册并遵循p_uuJ_uu的建议(参见其他答案)。 如果您对硬件接口的复杂性感到困惑或沮丧,请遵循当前的答案

  • HAL\u SPI\u Transmit\u DMA()
    HAL\u SPI\u Transmit\u IT()
    都支持可变数量的传输字节。 如果您需要的只是一个字节的传输,那么HAL函数可能是一个多余的功能。 它们的优点是,您可以运行一些C库函数,而无需在C中处理HW寄存器访问(如果这对您来说是非常新的,来自arduino生态系统)。当然,在扩展应用程序时,要通过同一接口传输多个字节

  • 您应该决定是要从绑定到UART的DMA获取中断,还是要避免DMA并从UART本身获取中断。从我的观点来看,您真的不应该通过用于启动DMA传输以获取数据的相同中断事件触发ISR

  • 与您在中找到硬件寄存器描述的方式相同 和 对于控制器,您可以在中找到有关HAL(分层概念、使用要求等)的文档 (参见第70节和第102节以及第3章)。 当然,这个接口主要是为了抽象和可移植性,而直接寻址硬件接口通常可以在延迟/CPU负载和ROM/RAM使用方面获得更好的效率。“低级”库驱动程序旨在实现某种折衷,但如果您不熟悉整个主题,并且不确定从何开始,则应该从HW register接口或便携式HAL库API开始

  • 如果规范文档(HW或Lib描述)对您来说过于抽象,并且您更喜欢一些实际操作的信息源,那么您可能需要首先查看STM32Cube固件示例。 这些还包括SPI数据交换用例(
    SPI\u FullDuplex\u ComIT
    ),可用于核仁L4532RE(和其他),如(第16页)所述


除了中断选择/处理外,还应检查程序的两个方面:

  • 如果硬件中断,则没有理由调用
    HAL\u Delay()

  • 请记住,在SPI上,当主设备传输数据(可能是零数据)时,您只能将数据从从设备“返回”到主设备。 否则,从机端的“传输”调用将只将数据放入TX寄存器,SPI外围设备将无限期地等待来自主机的SCK触发器


如果您想接收1个字节,则不应使用DMA。@P\u J\u-我同意。但是…-假设DMA已经用于在所需的应用程序中传输多个字节,为了简单起见,OP开始使用单个字节测试设置。这将证明在这里使用不必要的DMA是合理的…嗨,你能更具体一点吗?如何访问SPI CR寄存器,并且NVIC已使用MXcube启用。还有,我在哪里写我的中断服务程序?@dm123这是HAL和arduino的主要问题。人们认为他们可以在不知道自己的平台和工具链的情况下编程uCs。