3

我正在使用 STM32F072RB uC 在从模式下接收和传输数据,SPI2配置如下:

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

该寄存器APB1ENR也已正确配置。

当前程序只是检查RXNE标志,从中读取接收到的数据DR并将随机值写入DR.

我接收数据时的状态寄存器具有以下值:

SR = 0x1403

主机正确发送数据,我检查了从机引脚的信号(两侧的时钟相位和极性相同,NSS 信号在通过 MOSI 发送 SCK 和数据之前被清除)。

我什至将引脚配置为输入,我知道我可以读取主机可以发送的任何数字信号。在当前配置下,slave 似乎收到了一些东西,因为RXNE在 master 发送数据时设置了它,但读取的值始终为 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;
}

我究竟做错了什么?有什么我没有正确配置的吗?

提前致谢。问候,哈维尔

编辑:

我切换到软件 NSS 并从网上找到的 STM32CubeMX 示例中复制了寄存器值。我不能将这些库用于该项目,但我希望具有相同的行为。

新值是:

CR1 = 0x0278

意思是

  • fPCLK/256(适合通信速度的),
  • SPI启用和
  • SSM = 1(软件 NSS)。
CR2 = 0x1700

意思是

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

意思是

  • MISO、MOSI 和 SCK 交替功能 5 (SPI2)
  • NSS 未配置,因为现在它处于软件模式(始终选择从站)。

我仍然得到相同的结果,并且带有这些库的评估套件可以正常使用SPI1。因此,肯定还有另一个与寄存器值无关的问题。

可能有任何时钟问题,例如引脚需要获得一些时钟吗?

谢谢!

4

1 回答 1

0

问题指出了几个错误,可以解释为什么没有观察到接收:

  1. GPIO 配置指向一些错误的备用功能/模式:问题没有准确说明,但我认为

    AFRH = 0x55303500
    MODER = 0xa8a1556a
    

    指 GPIOB(否则,它对 SPI2 没有意义)。这对应于以下引脚配置(参见 参考手册,第 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 =>AF0PB13=>AF0PB10=>AF0,具体取决于您的硬件。

    为了避免这样做的错误,您应该遵循@P__J__ 的提示,并为分配给 MODER、AFRH 等的常量使用说话宏。使用 ST 提供的 HAL 库在 SO 用户中是一个真正有争议的话题,真的应该考虑至少使用stm32f072xb.hGPIO_AFRH_AFSEL15. 如果将所有配置寄存器值表示为此类宏的(按位)OR,则更容易根据数据表重新检查配置,并且著名的 橡皮鸭 将直接知道不满意的开发人员在说什么。

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

    该寄存器APB1ENR也已正确配置。

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

    此外,GPIOB 必须通电,即RCC_AHBENR必须设置第 18 位。再次参见 参考手册,秒。6.4.8 和 6.4.6。

  3. 调试期间 GPIO 引脚可能处于错误模式:

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

    请注意,对于每个 GPIO 引脚,通过MODER寄存器选择一个独特的模式。如果将其设置为“输入”( 0b00),则备用功能将断开连接,并且无法与外部信号一起使用。

于 2020-05-30T13:45:57.007 回答