STM32F072RB在从模式下不能通过SPI接收数据。

问题描述 投票:3回答:1

我使用的是 STM32F072RBuC来接收和传输数据。SPI2 在从属模式下,配置如下。

CR1 = 0x0078
CR2 = 0x0700
AFRH = 0x55353500
MODER = 0xa2a0556a

寄存器 APB1ENR 也是正确配置的。

目前的程序只是检查 RXNE 标志,从 DR 并发送一个随机值写到 DR.

当我接收数据时,状态寄存器的值如下。

SR = 0x1403

主站正确地发送数据,我检查了从站引脚的信号(两边的时钟相位和极性相同,在通过MOSI发送SCK和数据之前,NSS信号已被清除),我甚至将引脚配置为输入,我知道我可以读取任何主站可以发送的数字信号。

我甚至将这些引脚配置为输入,我知道我可以读取主控发送的任何数字信号。RXNE 是在主站发送数据时设置的,但读取的值总是0x00.我试过不同的配置(软硬件NSS,不同的数据大小等),但我总是得到0x00.此外,我在读取数据后发送的随机值是0x00.。

我试过不同的配置(软硬件NSS,不同的数据大小等),但我总是得到0x00。DR 不被发送到输出端。

这是我当前的函数,它被连续调用。

unsigned char spi_rx_slave(unsigned char spiPort, unsigned char *receiveBuffer)
{
    uint8_t temp;
    static unsigned long sr;
    if (!spi_isOpen(spiPort))
    {
        sendDebug("%s() Error: spiPort not in use!\r\n",__func__);
        return false;
    }
    if (spiDescriptor[spiPort]->powerdown == true)
    {
        sendDebug("%s() Error: spiPort in powerdown!\r\n",__func__);
        return false;
    }
    /* wait till spi is not busy anymore */
    while((spiDescriptor[spiPort]->spiBase->SR) & SPI_SR_BSY)
    {
        sendDebug("SPI is busy(1)\r\n");
        vTaskDelay(2);
    }
    sendDebug("CR1 = 0x%04x, ", spiDescriptor[spiPort]->spiBase->CR1);
    sendDebug("CR2 = 0x%04x, ", spiDescriptor[spiPort]->spiBase->CR2);
    sendDebug("AFRH address = 0x%08x, AFRH value = %08x, ", (unsigned long*)(GPIOB_BASE+0x24), *(unsigned long*)(GPIOB_BASE+0x24));
    sendDebug("MODER address = 0x%08x, MODER value = %08x\r\n", (unsigned long*)(GPIOB_BASE), *(unsigned long*)(GPIOB_BASE));
    sr = spiDescriptor[spiPort]->spiBase->SR;
    while(sr & SPI_SR_RXNE)
    {
        /* get RX byte */
        temp = *(uint8_t *)&(spiDescriptor[spiPort]->spiBase->DR);
        spiDescriptor[spiPort]->spiBase->DR = 0x53;
        sendDebug("-------->DR address = 0x%08x, data received: 0x%02x\r\n", &spiDescriptor[spiPort]->spiBase->DR, temp);
        sendDebug("SR = 0x%04x\r\n", sr);
        vTaskDelay(1);
        sr = spiDescriptor[spiPort]->spiBase->SR;
    }
    while((spiDescriptor[spiPort]->spiBase->SR) & SPI_SR_BSY)
    {
        sendDebug("SPI is busy(2)\r\n");
        vTaskDelay(2);
    }
    return true;
}

我到底做错了什么? 我有什么地方没有配置好吗?

先谢谢你!Regards,Javier

编辑。

我改用软件NSS,并从网上找到的STM32CubeMX例子中复制了寄存器值。我不能在这个项目中使用这些库,但我希望有同样的行为。

新的值是

CR1 = 0x0278

这意味着

  • fPCLK256(适合通信速度的)。
  • 启用SPI,并且
  • SSM=1(软件NSS)。
CR2 = 0x1700

这意味着

  • 8位数据和
  • RXNE 如果FIFO级别大于或等于14(8位),则会产生事件。
AFRH = 0x55303500
MODER = 0xa8a1556a

这意味着

  • MISO、MOSI和SCK交替功能5(SPI2)
  • NSS没有配置,因为现在它是在软件模式下(从属总是被选中)。

我还是得到了同样的结果,而带有这些库的评估套件在使用这些库时也能正常工作。SPI1 因此,一定有另一个与寄存器值无关的问题。

会不会是时钟的问题,比如说引脚需要一些时钟?

谢谢!我使用的是STM32F072RB的uC。

stm32 spi stm32f0
1个回答
0
投票

这个问题指向了几个错误,可能解释了为什么没有观察到接收。

  1. GPIO配置指向一些错误的交替功能模式:问题没有准确说明,但我假设:

    AFRH = 0x55303500
    MODER = 0xa8a1556a
    

    指的是GPIOB(否则,它与SPI2就没有意义了)。参考手册第8.4.1、8.4.10节和第8.4.2节。8.4.1、8.4.10和《联合国宪章》的规定。技术资料,表16)。)

    PB15 - Alternate Function - AF5 = [INVALID]
    PB14 - Alternate Function - AF5 = [I2C2_SDA]
    PB13 - Alternate Function - AF3 = [TSC_G6_IO3]
    PB12 - GP Input (reset state)
    PB11 - Alternate Function - AF3 = [TIM_CH4]
    PB10 - Alternate Function - AF5 = [SPI2_SCK / I2S2_CK]
    PB09 - GP Input (reset state)
    PB08 - GP Output
    PB07 - Alternate Function - (unknown which, see register AFRL)
    PB06 - GP Output
    PB05 - Alternate Function - (unknown which, see register AFRL)
    PB04 - GP Output
    PB03 - GP Output
    PB02 - Alternate Function - (unknown which, see register AFRL)
    PB01 - Alternate Function - (unknown which, see register AFRL)
    PB00 - Alternate Function - (unknown which, see register AFRL)
    

    这显然不是软件需要做的事情。

    解决办法。确保配置 PB15=>AF0, PB14=>AF0,要么 PB13=>AF0PB10=>AF0,这取决于你的硬件。

    为了避免这样做的错误,你应该按照@P__J__的提示,对MODER、AFRH等分配的常量使用speaking macros.使用ST提供的HAL库在SO用户中确实是一个有争议的话题。不过 一个人应该真正考虑使用至少一个头,如 stm32f072xb.h 与宏,如 GPIO_AFRH_AFSEL15.如果将所有配置寄存器的值表示为这种宏的(位智)OR,则更容易根据数据表重新检查配置,著名的是橡皮鸭会直接知道一个不开心的开发商在说什么。

  2. 其他的时钟激活可能会缺失:问题证实了

    登记册 APB1ENR 也是正确的配置。

    这是正确的(只要位14被设置)。

    此外,GPIOB 必须被供电,也就是说,GPIOB 的位 18 必须被设置。RCC_AHBENR 必须设置。参考手册6.4.8和6.4.6。6.4.8 和 6.4.6.

  3. 在调试过程中,GPIO引脚可能处于错误的模式下,我甚至将引脚配置为输入,我知道我可以读取任何主站可以发送的数字信号。

    我甚至将这些引脚配置为输入,我知道我可以读取主控端发送的任何数字信号。在目前的配置下,似乎从机接收到了一些东西,因为当主机发送数据时,RXNE被设置,但读取值总是0x00。

    请注意,每一个GPIO引脚都有一个独特的模式,通过下面的命令来选择 MODER 寄存器,如果将其设置为 "输入"( 如果将其设置为 "输入"(0b00),备用功能被断开,无法与外部信号配合。

© www.soinside.com 2019 - 2024. All rights reserved.