ARM中SPI的位冲击

时间:2015-05-22 06:53:21

标签: c bit-manipulation spi

我正在尝试使用SPI从FXLS8471Q 3轴线性加速度计读取数据。我正在使用bit banging方法从Accelerometer读取数据。我正在使用LPC 2184 ARM处理器。我使用了以下代码。

unsigned char spiReadReg (const unsigned char regAddr)

{

  unsigned char SPICount;                               

  unsigned char SPIData;                  

  SPI_CS = 1;                                           
  SPI_CK = 0;                                           
  SPIData = regAddr;                                    

  SPI_CS = 0;                                           
  for (SPICount = 0; SPICount < 8; SPICount++)          
  {
      if (SPIData & 0x80)
         SPI_MOSI = 1;
      else
         SPI_MOSI = 0;
      SPI_CK = 1;
      SPI_CK = 0;
      SPIData <<= 1;
  }                                                     
  SPI_MOSI = 0;                                         

  SPIData = 0;
  for (SPICount = 0; SPICount < 8; SPICount++)          
  {
     SPIData <<=1;                                       
     SPI_CK = 1;                                         
     SPIData += SPI_MISO;                                
     SPI_CK = 0;         
     SPIData &=(0xFE);
  }                                                     
   SPI_CS = 1;                                           

  return ((unsigned char)SPIData);                      
}

但是我没有获得有效值0x6A,而是获得了垃圾值。 请帮我解决这个问题;

3 个答案:

答案 0 :(得分:2)

SPIData &=(0xFE);如另一个答案所指出的那样,肯定是错误的,因为它会删除你刚收到的那一位。

但是,您的代码还存在其他主要问题。 SPI从器件通过在上升或下降时钟上设置MISO的值来向您发送数据,具体取决于器件的类型。但是,您没有在代码中等待值显示在MISO上。

您可以通过将时钟设置为1和0来控制通信。datasheet of the accelerometer在第19页上说明了

  

在SCLK的上升沿采样数据,并在SCLK的下降沿设置。

这意味着为了从中读取,您的处理器需要将时钟从1更改为0,从而发信号通知加速度计将下一位发送到MISO。这意味着你做了相反的事情,你在代码中读取了你应该在下降沿读取的上升沿。将时钟设置为零后,您必须等待一段时间,直到该值出现在MISO上,然后才能读取它并将其添加到SPIData变量中。 表9,SPI时序表示您需要等待多少:至少500纳秒。这并不多,但如果您的CPU运行速度超过2 MHz,那么如果您没有使用延迟,您将尝试在加速度计有时间正确设置之前读取MISO。

你也忘记了奴隶选择,这实际上是指示数据报开始和结束所必需的。

检查数据表中的图7. SPI时序图,它表示您需要做什么以及使用SPI与设备通信的顺序。

我还建议阅读SPI的旋转寄存器是如何工作的,因为从数据表中可以看出,加速度计需要在有效数据出现在其输出之前接收到指定数量的位。不要忘记,当你向设备发送一个比特时,它也必须向你发送一些信息,所以如果它还没有解码命令,它只能发送乱码。作为主人,您的代码只能&#34;推送&#34;位,并收集&#34;弹出&#34;另一方面。这意味着您必须发送一个命令,然后发送更多位,直到所有答案都被逐位推送给您。

如果你遇到困难,我认为你会在https://electronics.stackexchange.com/获得帮助时获得更多的运气,而不是仅仅将相同的代码放在那里(似乎是从www.maximintegrated.com盲目复制而且绝对有与您尝试解决的问题无关),我强烈建议您尝试理解&#34;图7. SPI时序图&#34;我以前建议过,并相应地更改你的代码。 如果你只是因为它说'&#34; spi&#34;在标题中。

答案 1 :(得分:0)

SPIData &=(0xFE);

以上行导致了问题。这里LSB被复位为0(其中包含刚刚从MISO获取的数据位) - 基本上你正在破坏你刚读取的位。省略该行应该可以解决问题。

答案 2 :(得分:0)

确保使用NO优化编译您的函数 因为这会破坏bitbang操作。

这是spiReadReg函数的maxum站点的代码。 (看起来你得到了你的代码。

但是,这只是“一般”的指南。与格言1481部分通信的操作顺序。

加速。 part需要几个设置命令并完全不同地读取

建议阅读freescale.com上提供的应用说明和白皮书,了解具体的部件号。

这些应用笔记/白皮书将指出设置特定操作模式所需的命令序列以及如何请求/解释结果数据。

您的代码未考虑许多设备细节。

根据规格表,传输的第一位是读/写指示符,后面是8位寄存器地址,后跟7个垃圾位(建议发送所有0&#39;用于垃圾位。)后跟数据位。

根据设置命令,这些数据位可以是8位或14位,也可以是每个寄存器8位或14位的多个寄存器。

相关问题