STM32F407 SPI同时读取LIS3DSH数据

STM32F407 SPI While Reading Datas of LIS3DSH

 uint8_t SPI_Rx(uint8_t address)
    {
     GPIO_ResetBits(GPIOE,GPIO_Pin_3);
     address    =   (0x80) | (address);
        
     while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_TXE));     
     SPI_I2S_SendData(SPI1,address);
     while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_RXNE));
     SPI_I2S_ReceiveData(SPI1);
        
     while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_TXE));     
     SPI_I2S_SendData(SPI1,0x00);
     while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_RXNE));
     SPI_I2S_ReceiveData(SPI1);
        
     GPIO_SetBits(GPIOE,GPIO_Pin_3);
     return SPI_I2S_ReceiveData(SPI1);

您好,您看到的是LIS3DSH传感器的SPI读取函数。首先,在我发送地址知识后,SPI RX 缓冲区接收 LIS3DSH 传感器的数据。但是为什么它需要通过发送“0x00”来接收 LIS3DSH 传感器的数据呢?简而言之,为什么在我们已经收到数据时还需要再次发送 else 数据?提前,谢谢。

从LIS3DSH的一个寄存器读取数据时,整个SPI事务是两个字节长:

  • 字节 1:主机将寄存器地址(包括 read/write 标志)发送到传感器。
  • Byte 2:传感器将寄存器值发送给主机。

但是,SPI 是一种全双工协议。对于每个位和字节,主机和从机(传感器)都发送数据。所以真正的交流实际上是这样的:

  • 字节 1
    • 主机发送寄存器地址。
    • 从站发送 0 或任何随机值。
  • 字节 2
    • Master发送0.
    • 从机发送寄存器值。

这是您在代码中看到的内容:

 while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_TXE));  // Wait for SPI bus to be ready
 SPI_I2S_SendData(SPI1,address);                    // Submit byte 1 to be sent
 while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_RXNE)); // Wait for byte 1 from slave
 SPI_I2S_ReceiveData(SPI1);                         // Retrieve byte 1 from slave and ignore it
    
 while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_TXE));  // Wait for SPI bus to be ready
 SPI_I2S_SendData(SPI1,0x00);                       // Send 0 as byte 2
 while(!SPI_I2S_GetFlagStatus(SPI1,SPI_FLAG_RXNE)); // Wait for byte 2 from slave
 SPI_I2S_ReceiveData(SPI1);                         // Retrieve byte 2 and ??

 GPIO_SetBits(GPIOE,GPIO_Pin_3);                    // Deassert CS?
 return SPI_I2S_ReceiveData(SPI1);                  // Retrieve byte 2 again and return it

最后一段有点奇怪。 SPI_I2S_ReceiveData() 最后被调用两次,可能假设它将 return 相同的值两次。如果只调用一次它可能会更干净。