【问题标题】:STM32F072RB does not receive/send data over SPI in slave modeSTM32F072RB 在从机模式下不通过 SPI 接收/发送数据
【发布时间】:2017-11-24 09:51:27
【问题描述】:

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

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

寄存器APB1ENR也配置正确。

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

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

SR = 0x1403

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

我什至将引脚配置为输入,并且我知道我可以读取主机可以发送的任何数字信号。 在当前配置下,slave 似乎收到了一些东西,因为在 master 发送数据时设置了 RXNE,但读取的值始终为 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位数据和
  • 如果 FIFO 级别大于或等于 1/4(8 位),则生成 RXNE 事件。
AFRH = 0x55303500
MODER = 0xa8a1556a

意思是

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

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

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

谢谢!

【问题讨论】:

  • "CR1 = 0x0078, CR2 = 0x0700, AFRH = 0x55353500, MODER = 0xa2a0556a" 首先让您的问题和配置易于阅读。尊重我们的时间。
  • 你的主人是否生成时钟。如果不是,您将不会发送任何内容。如果要发送字节,则需要将 DR 转换为字节。
  • 是的,主机正确生成时钟并且接收到该时钟使 SPI 激活 RXNE 标志。
  • 我认为拥有寄存器值对于任何愿意提供帮助的人都会很有用。我应该解释一下每个寄存器的每一位是什么意思吗?谢谢。
  • 我编辑了问题以提供一些其他人发现缺失的信息。没有称为 STM32072RB 的 mcu,而只有 STM32F072RB*STM32L072RB(分别带有“F”或“L”)。仅使用问题和答案中给出的信息,我首先认为这两个控制器可能都是有意义的。但是,只有在F0上,SPI_CR2寄存器占用8位以上,而SPI_SR提供9位以上,所以STM32F072RB一定是指. => 相应地编辑了标题和标签。

标签: stm32 spi stm32f0


【解决方案1】:

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

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

    AFRH = 0x55303500
    MODER = 0xa8a1556a
    

    指的是 GPIOB(否则,它对 SPI2 没有意义)。 这对应于以下引脚配置(参见 Reference Manual, 秒。 8.4.1、8.4.10 和 Datasheet, 表 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=>AF0PB14=>AF0PB13=>AF0PB10 =>AF0,取决于您的硬件。

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

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

    寄存器APB1ENR也配置正确。

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

    此外,GPIOB 必须通电,即。例如,必须设置RCC_AHBENR 的第 18 位。 再看看 Reference Manual, 秒。 6.4.8 和 6.4.6。

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

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

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

【讨论】:

    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 2019-11-17
    • 2018-09-18
    • 1970-01-01
    • 2018-06-11
    • 2015-04-21
    • 2015-07-07
    • 2021-12-14
    相关资源
    最近更新 更多