-1

我正在尝试使用 SPI 通信读取 ADC( ADS8320 ) 值。我正在为 ARM 和 SM470R1B1 控制器使用 IAR 嵌入式工作台。在数据表中,它说前 6 位是虚拟读取,接下来的 16 位是 actval 数据。我正在尝试读取 24 位并忽略前 6 位和后 2 位。当我尝试使用以下代码时,我得到了错误的值。

unsigned int readADC8320(void)  
{                 
   value = AD8320_16(0xFFFFFF);              // read registe    
   return value;
}

unsigned int AD8320_16(unsigned int value) 
{ 
unsigned int data; 
AD8320_CS_Status(0);
SW_Delay(DELAY_10US);
while(GIODOUTA&X2);
data = spi2(value >> 16);     //read high 8 bits
data = (data << 6)| spi2(value >> 8);   //read next 8 bits but 6+8 =14
data = (data << 8)| spi2(value >> 2);   //add last two bits only
SW_Delay(DELAY_10US);
AD8320_CS_Status(1);
return data; 
} 

unsigned char spi2(unsigned char data)
 {
// Write byte to SPI2DAT1 register
SPI2DAT1 = data;    

while(!(SPI2CTRL3 & 0x01)){}        // Wait for RxFlag to get set   
return (SPI2BUF & 0x000000FF);      // Read SPIBUF 
  }

谁能建议我在哪里做错了。我的轮班操作很差。

4

1 回答 1

2

您的代码看起来很不稳定。例如,有什么目的value

您链接到的数据表表明 22 个时钟周期就足够了(并且 24 个时钟周期是可以的),不需要额外的延迟,假设 SPI 时钟在限制范围内(我相信最多 2.4 MHz)。所以,我希望你的代码看起来更像

void AD8320_setup(void)
{
    /* TODO:
     *  - Set SPI2 clock frequency, if programmable (max. 2.4 MHz)
     *  - Set SPI2 transfer size, if programmable (8 bits per byte)
     *  - Set SPI2 to latch data on the falling edge of clock pulse
     *  - Set SPI2 to pull clock high when inactive
     *  - Set AD8320 chip select pin as an output
     *  - Set AD8320 chip select pin high (it is active low)
     *  - Ensure AD8320 is powered 
    */
}

uint16_t AD8320_16(void)
{
    uint16_t result;

    /* TODO: Set AD8320 chip select pin 0/LOW (to select it)
    */

    /* TODO: Clear SPI2 FIFO if it has one,
     *       so that we get actual wire data,
     *       not old cached data.
    */

    result = ((uint16_t)(spi2_read() & 3U)) << 14;
    result |= ((uint16_t)spi2_read()) << 6;
    result |= ((uint16_t)spi2_read()) >> 2;

    /* TODO: Set AD8320 chip select pin 1/HIGH (to deselect it)
    */

    return result;
}

的原型spi2_read通常是unsigned char spi2_read(void);,但它可能是可以正确表示所有八位值的任何整数类型(0 到 255,包括在内)。上面,我将结果——在用二进制 AND 运算屏蔽掉任何不相关的位(如果有的话)之后——uint16_t转换到结果中的正确位置之前,这样无论spi2_read()返回类型如何,我们都可以使用它来构造我们的 16 位值。

第一个spi2_read()读取前 8 位。我假设您的设备 SPI 总线首先发送和接收最高有效位;这意味着 6 个虚拟位是最高有效位,而 2 个最低有效位是结果的最高有效位。这就是为什么我们只保留第一个字节的两个最低有效位,并将其传输到剩下的 14 位——这样我们就可以将它们置于最高有效位置。

第二个spi2_read()读取接下来的八位。这些是数据的第 13..6 位;这就是为什么我们将这个字节左移 6 位,并与现有数据进行 OR。

最后spi2_read()读取接下来的八位。最后两位将被丢弃,因为只有前 6 位(最高有效位)包含我们感兴趣的其余数据。因此,我们将其向下移动 2 位,并与现有数据进行或运算。

准备 spi2 涉及字长(8 位)、数据速率(如果可编程)等。

AD8320 的芯片选择只是一个通用输出引脚,它只是低电平有效。这就是为什么它在数据表中被描述为 ^CS/SHDN:低电平时选择芯片,高电平时关闭。

该芯片是微功率芯片,因此需要不到 2mA 的电流,因此您可以想象从许多微控制器上的输出引脚为其供电。如果您要这样做,您还必须记住将该引脚设置为输出和 1/high_setup()功能。

于 2015-08-11T16:20:24.217 回答