c - STM32F4 SPI问题: master cannot write data

标签 c embedded driver stm32 spi

我正在尝试为STM32F407 MCU编写SPI驱动程序,并使用该驱动程序将数据发送到Arduino。

下面是应用程序向 Arduino 发送数据的部分。 (STM32F4作为主机,采用硬件从机管理。)

int main (void)
{
    /*initilize green led on PD12*/
    green_led_init();

    /*Initialize user button on PA0*/
    user_button_init();

    /*Initilize SPI2 on PB15:PB12*/
    SPI2_GPIO_pin_init();
    SPI2_init();
    SPI_NSS_pin_ctr(SPI2,ENABLE);

    char *dataPtr = "HelloWorld";
    uint8_t dataLength = strlen(dataPtr);

    while(1){
        if(user_button_read()){
            green_led_on();
            SPI_periph_ctr(SPI2,ENABLE);

            /*send to Arduino size of data to receive. then send the data*/
            SPI_send_data(SPI2,&dataLength,1);
            SPI_send_data(SPI2,(uint8_t*)dataPtr,dataLength);

            /*check whether SPI2 is still busy. if not, disable SPI2*/
            while(SPI_busy_check(SPI2));
            SPI_periph_ctr(SPI2,DISABLE);
        }else{
            green_led_off();
        }
    }

这里是发送数据的API

void SPI_send_data (SPI_TypeDef *SPIxPtr, uint8_t *txBufferPtr, uint32_t Length)
{
        uint8_t temp = 0;
        while(Length){
            /* wait until tx buffer is empty*/
            while(!SPIxPtr->SR & SPI_SR_TXE);

            if(!(SPIxPtr->CR1 & SPI_CR1_DFF)){
                /*8 bit data frame*/
                SPIxPtr->DR = *txBufferPtr;
                txBufferPtr++;
                Length--;
            }else{
                /*16 bit data frame*/
                SPIxPtr->DR = *((uint16_t*)txBufferPtr);
                txBufferPtr+=2;
                Length-=2;
            }
        }
}

当我尝试将数据写入 DR 寄存器时,DR 寄存器的值保持为 0xFF,并且 SR 寄存器位中的 RXNE 位保持设置(请按照此链接查看图像 https://imgur.com/a/wSc8Wig )。由于此应用程序仅向 Arduino 发送数据,并且由于正在发送数据,因此我认为 TXE 位应该被清除,而不是 RXNE 被设置。

我还是不明白为什么会出现上述情况。任何帮助或建议将不胜感激。

最佳答案

在使用 SPI 时将 SPI 保持在调试器上,我强烈建议不要这样做,因为调试器将继续读取 DR 注册表以更新 IDE 中的 GUI,这会弄乱状态标志。

即使不使用 ST 的 HAL 库,您也可以随时将其用作引用

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
...........
   while (hspi->TxXferCount > 0U)
    {
      /* Wait until TXE flag is set to send data */
      if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
      {
        *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
        pData += sizeof(uint8_t);
        hspi->TxXferCount--;
      }
      else
      {
        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
        }
      }
    }
...........
 /* Wait until TXE flag */
  if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
  {
    errorcode = HAL_TIMEOUT;
    goto error;
  }

  /* Check Busy flag */
  if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
  {
    errorcode = HAL_ERROR;
    hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
    goto error;
  }

  /* Clear overrun flag in 2 Lines communication mode because received is not read */
  if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
  {
    __HAL_SPI_CLEAR_OVRFLAG(hspi);
  }
...........
}

关于c - STM32F4 SPI问题: master cannot write data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57317946/

相关文章:

c++ - atoi 只返回 char* 参数的第一个数字

c - 输出不会在某个值之后出现

c - C 中的 OOP。类的默认值

c - 为什么这些嵌入式 C 代码的安排表现如此不同?

mongodb - 如何在 go(lang) 中连接到 mlab mongodb 数据库?

windows - Winsock Kernel的 "WskSendTo"函数在Win7 SP1上导致 "DRIVER_IRQL_NOT_LESS_OR_EQUAL"BSOD

java - 如何获取元素的最后一个索引。 (元素重复几次)JAVA

c - 在不同编译器上具有显式宽度成员的结构对齐

c - 生产者和消费者在 Linux c 中使用信号量

c - 为何存在 Unresolved 包容性?