已回答假定已回答

ADIS164888使用SPI读取数据时好时坏

ambest 在 2014-9-19 詢問的問題
最後回覆由adi_rock於2014-9-26提供

我使用STM32单片机与ADIS16488通过SPI通信,连接图和官方手册一样,其中23引脚实时时钟电源和9引脚数据就绪我没有接,因为我不需要用外部时钟和数据就绪信号,我是在初始化各个引脚后,先去用SPI读取传感器的PROD_ID,按照手册上写的,如果读取为0X4068,则代表SPI协议读取正确。
问题在于,我同样的连线,有时传感器初始化不成功,表现为读取PROD_ID为0xFFFF或0x0,有时传感器初始化可以成功,读取PROD_ID为0x4068。

大多情况是如果几天不用,再次使用时,不能正确读取PROD_ID,过几个小时,偶然间就可以正确读取了,之后就一直正确的,不管断电重启还是怎样。但如果间隔一两天不使用就会读取错误。下面是我ADIS16488的SPI初始化程序

void SPI_FLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable SPI1 and GPIO clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  /*!< SPI_FLASH_SPI Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

  /*!< Configure SPI_FLASH_SPI pins: SCK MISO MOSI*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* SPI1 configuration */
  // W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.
  // Data on the DO and DIO pins are clocked out on the falling edge of CLK.
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);

  /* Enable SPI1  */
  SPI_Cmd(SPI1, ENABLE);
}

读取PROD_ID的程序

uint16_t SPI_FLASH_ReadDeviceID(void)
{
  u16 Temp = 0;
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "PROD_ID " instruction */
  SPI_FLASH_SendTwoByte(0X7E00);

  /* Read two bytes from the FLASH */
  Temp = SPI_FLASH_SendTwoByte(0xFFFF);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  return Temp;
}

main程序

USART1_Config();
/* ADIS spi初始化 */
SPI_FLASH_Init();
/* Get SPI Flash Device ID */
PROD_ID = SPI_FLASH_ReadDeviceID();
if (PROD_ID != 0x4068)
   {
    printf("\r\n     PROD_ID = 0x%X ", PROD_ID);
    printf("\r\n     ADIS16488初始化失败");
    while(PROD_ID != 0x4068)
         {
          PROD_ID = SPI_FLASH_ReadDeviceID();
          printf("\r\n     PROD_ID = 0x%X ", PROD_ID);
          } 
    }
printf("\r\n     PROD_ID = 0x%X ", PROD_ID);
printf("\r\n     ADIS16488初始化成功");


在读取正确的时候,6号CS片选端的电压为3.10V或更低到2.9V,读取错误的时候,片选端电压为3.28V,和电源电压一样。
这个问题很奇怪,一直在困扰我,我想问问是不是某些细节被我疏忽了。

結果