首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接收数据的STM32 SPI驱动程序总是0

接收数据的STM32 SPI驱动程序总是0
EN

Stack Overflow用户
提问于 2020-12-22 04:42:51
回答 1查看 1K关注 0票数 3

我试图使用stm32 LL库(用于STML4系统)编写SPI驱动程序。我正在测试SPI驱动程序,方法是将2字节写入MOSI行,并在MISO行上侦听1字节。使用示波器,我能够验证两个字节被正确传输,SPI从设备用一个字节进行响应。见所附截图:

在图像中,我正在探测SCLK和MISO线。显然,MISO行上的最后8位是0b01110011,这是预期的数据。我写的驱动程序没有反映这一点,它总是从SPI DR寄存器中读取0。由于SPI外围设备(可能遗漏了什么),我在调试模式下运行代码时遇到问题,无法使用printf输出值(不能访问UART接口)。我希望能有一些关于什么问题的想法。

代码语言:javascript
复制
void spi_transmit_receive( SPI_TypeDef* spi, uint8_t* tx, uint8_t* rx, uint16_t size )
{

    if( !LL_SPI_IsEnabled( spi ) )
    {
        LL_SPI_Enable( spi );
    }

    if( size > 1 )
    {
        LL_SPI_SetRxFIFOThreshold( spi, LL_SPI_RX_FIFO_HALF_FULL );
    }
    else
    {
        LL_SPI_SetRxFIFOThreshold( spi, LL_SPI_RX_FIFO_QUARTER_FULL );
    }


    uint8_t* rx_ptr = rx;
    uint8_t* tx_ptr = tx;

    uint16_t tx_count = size;
    uint16_t rx_count = size;

    while( tx_count > 0 || rx_count > 0 )
    {
        if( tx_count > 0 && LL_SPI_IsActiveFlag_TXE( spi ) )
        {
            if( tx_count > 1 )
            {
                LL_SPI_TransmitData16( spi, *((uint16_t*)tx_ptr) );

                tx_ptr += sizeof( uint16_t );

                tx_count -= 2;
            }
            else
            {
                LL_SPI_TransmitData8( spi, *tx_ptr );

                tx_count -= 1;
            }
        }

        if( rx_count > 0 && LL_SPI_IsActiveFlag_RXNE( spi ) )
        {
            if( rx_count > 1 )
            {
                *((uint16_t*)rx_ptr) = LL_SPI_ReceiveData16( spi );
                rx_ptr += sizeof( uint16_t );
                rx_count -= 2;

                if( rx_count <= 1 )
                {
                    // Switch to 8 bit mode for last 8 bits
                    LL_SPI_SetRxFIFOThreshold( spi, LL_SPI_RX_FIFO_QUARTER_FULL );
                }
            }
            else
            {
                *rx_ptr = LL_SPI_ReceiveData8( spi );
                //rx_ptr += sizeof(uint8_t);
                rx_count -= 1;
            }
        }
    }

    while( LL_SPI_IsActiveFlag_BSY( spi ) ) {}

    LL_SPI_Disable( spi );
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-22 17:33:50

您没有指定特定的STM32部件,因此不可能提供特定的用户手动引用,在STM32部件的范围内至少有两个SPI外围变量,因此您的部分不可能确定,但是STM32F1xx和STM32F2xx SPI_DR的文档说明(我的重点是):

根据数据帧格式选择位( SPI_CR1寄存器中的DFF),发送或接收的数据要么是8位,要么是16位。在启用SPI以确保正确操作之前,必须进行此选择。

也就是说,在事务的中间将帧从16位更改为8位是无效的。看来您应该在8位模式下专门操作这个设备,只需发送两个字节。我认为,只有当所有传输都是16位的倍数时,使用16位帧才是合适的。

我想正在发生的事情是,设备保持16位模式,发送的数据首先在SPI_DR的MSB中结束。但由于文档表明这是一种未定义的行为,所以所有的赌注都取消了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65403359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档