如何减少 STM32L4 HAL 库的 SPI 开销时间 [英] How to decrease SPI overhead time for STM32L4 HAL library

查看:44
本文介绍了如何减少 STM32L4 HAL 库的 SPI 开销时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 STM32L476RG 板和 HAL SPI 功能:

I am using a STM32L476RG board and HAL SPI functions:

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

我需要以最大速度从加速度计的缓冲区接收数据,但这些函数存在延迟问题.正如您在示波器屏幕截图中看到的那样,有几微秒没有任何反应.我不知道如何最小化传输间隙.

I need to receive data from accelerometer's buffer with maximum speed and I have a problem with delay in these functions. As you can see on the oscilloscope screenshots, there are several microseconds during which nothing happens. I have no idea how to minimize the transmission gap.

我尝试使用 HAL_SPI_Receive_DMA 函数,但这个延迟更大.你知道如何使用 HAL 函数解决这个问题,或者任何关于如何在没有这些延迟的情况下编写 SPI 函数的指针吗?

I tried using HAL_SPI_Receive_DMA function and this delay was even bigger. Do you have any idea how to solve this problem using HAL functions or any pointers on how I could write my SPI function without these delays?

推荐答案

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

TL;DR Don't use HAL, write your transfer functions using the Reference Manual.

HAL 对于时间紧迫的任务(以及其他任务)来说过于复杂,无可救药.看看 HAL_SPI_Transmit() 函数,它有 60 多行代码,直到它真正接触到数据寄存器.即使没有多任务操作系统,HAL 也会首先将端口访问结构标记为忙碌,验证函数参数,无缘无故地将它们存储在 hspi 结构中,然后继续弄清楚什么模式SPI in等.SPI master模式下也不需要检查timeouts,因为master控制所有的总线时序,如果在有限的时间内不能取出一个字节,那么端口初始化是错误的,周期.

HAL is hopelessly overcomplicated for time-critical tasks (among others). Just look at the HAL_SPI_Transmit() function, it's over 60 lines of code till it gets to actually touching the Data Register. HAL will first mark the port access structure as busy even when there is no multitasking OS in sight, validates the function parameters, stores them in the hspi structure for no apparent reason, then goes on figuring out what mode SPI is in, etc. It's not necessary to check timeouts in SPI master mode either, because master controls all bus timings, if it can't get out a byte in a finite amount of time, then the port initialization is wrong, period.

没有 HAL,事情就简单多了.首先,弄清楚应该进入控制寄存器的内容,相应地设置CR1CR2.

Without HAL, it's a lot simpler. First, figure out what should go into the control registers, set CR1 and CR2 accordingly.

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) 引脚管理.

This initialization assumes that Slave Select (NSS or CS#) is handled by separate GPIO pins. If you want CS# managed by the SPI peripheral, then look up Slave select (NSS) pin management in the Reference Manual.

请注意,全双工 SPI 连接不能只是发送或接收,它总是同时进行.如果从机需要一个命令字节,并以 4 个字节的数据作为应答,即 5 字节传输,从机将忽略最后 4 个字节,主机应忽略第一个.

Note that a full duplex SPI connection can not just transmit or receive, it always does both simultaneously. If the slave expects one command byte, and answers with four bytes of data, that's a 5-byte transfer, the slave will ignore the last 4 bytes, the master should ignore the first one.

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

A very simple transfer function would be

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,交错写入和读取,以便发送器始终保持忙碌.

It can be further optimized when needed, by making use of the SPI fifo, interleaving writes and reads so that the transmitter is always kept busy.

如果速度很重要,请不要使用通用函数,或者确保在使用时可以内联它们.使用启用链接时优化的编译器,并优化速度(很明显).

If speed is critical, don't use generalized functions, or make sure they can be inlined when you do. Use a compiler with link-time optimization enabled, and optimize for speed (quite obviously).

这篇关于如何减少 STM32L4 HAL 库的 SPI 开销时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆