如何减少STM32L4 HAL库的SPI开销时间

时间:2018-10-14 18:17:10

标签: accelerometer stm32 spi hal

我正在使用STM32L476RG板和HAL SPI功能:

HAL_SPI_Transmit(&hspi2, &ReadAddr, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi2, pBuffer, 4, HAL_MAX_DELAY);

我需要以最大速度从加速度计的缓冲区接收数据,但是这些功能的延迟存在问题。如您在示波器屏幕截图中所见,在几微秒内什么都没有发生。我不知道如何减小传输间隙。

enter image description here

我尝试使用HAL_SPI_Receive_DMA函数,并且此延迟更大。您是否知道如何使用HAL函数来解决此问题,或者关于如何在没有这些延迟的情况下编写SPI函数的任何指针?

3 个答案:

答案 0 :(得分:2)

TL; DR不要使用HAL,请使用参考手册编写传递函数。

对于时间紧迫的任务(以及其他任务),HAL毫无希望地变得过于复杂。只需看一下HAL_SPI_Transmit()函数,它就会超过60行代码,直到真正接触到数据寄存器为止。即使没有多任务操作系统,HAL也会首先将端口访问结构标记为忙,验证功能参数,无明显理由将其存储在hspi结构中,然后继续找出SPI处于哪种模式等等,也不必在SPI主模式下检查超时,因为主控制所有总线时序,如果在有限的时间内不能取出一个字节,则说明端口初始化是错误的周期。

没有HAL,它要简单得多。首先,找出应该放入控制寄存器中的内容,并分别设置CR1CR2

void SPIx_Init() {
    /* full duplex master, 8 bit transfer, default phase and polarity */
    SPIx->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE | SPI_CR1_SSM | SPI_CR1_SSI;
    /* Disable receive FIFO, it'd complicate things when there is an odd number of bytes to transfer */
    SPIx->CR2 = SPI_CR2_FRXTH;
}

此初始化假定从设备选择(NSSCS#)由单独的GPIO引脚处理。如果您希望CS#由SPI外设管理,请在《参考手册》中查找从机选择(NSS)引脚管理

请注意,全双工SPI连接不仅可以发送或接收,还可以同时进行。如果从设备期望一个命令字节,并以4字节数据进行应答,即5字节传输,则从设备将忽略最后4个字节,而主设备应忽略第一个字节。

一个非常简单的传递函数应该是

void SPIx_Transfer(uint8_t *outp, uint8_t *inp, int count) {
    while(count--) {
        while(!(SPIx->SR & SPI_SR_TXE))
            ;
        *(volatile uint8_t *)&SPIx->DR = *outp++;
        while(!(SPIx->SR & SPI_SR_RXNE))
            ;
        *inp++ = *(volatile uint8_t *)&SPIx->DR;
    }
}

可以在需要时通过使用SPI fifo进一步优化它,对写入和读取进行交织,从而使发送器始终保持忙碌状态。

如果速度至关重要,请不要使用通用函数,或确保在使用时可以内联它们。使用启用了链接时优化的编译器,并进行速度优化(显然是很不错的。)。

答案 1 :(得分:2)

您可以使用HAL_SPI_TransmitReceive(&hspi2, ReadAddr, pBuffer, 1 + 4, HAL_MAX_DELAY);代替HAL_SPI_TransmitHAL_SPI_Receive。这样可以避免发送和接收之间的时间。 您也可以尝试更改编译设置以优化速度。 您还可以查看加速度计的数据表,可能是您可以读取一个帧中的所有缓冲区,这是这样的: HAL_SPI_TransmitReceive(&hspi2, ReadAddr, pBuffer, 1 + (4 * numOfSamples), HAL_MAX_DELAY);

答案 2 :(得分:0)

对我有用的东西

  1. 直接读取SPI寄存器
  2. 优化速度功能

例如函数(代码);请参阅ST- Community中“ JElli.1”的解决方案>> ST Community answer