ADXL362 初次使用总结(使用stm32 HAL 库)

ADXL362 初次使用总结

最近的一次项目中使用到了ADI的三轴加速度传感器ADXL362,出现了一些问题,这里做一下总结,问题包括这几点:
1. 从spi读取的数据一直为0
2. 随后读取芯片ID正常,但是读取加速度一直为0
3. 第一次读取加速值为0,第一次之后就正常了
以上的问题,都跟spi配置相关。
ADXL362是一款不错的三轴加速度传感器,他的特性包括:
* 1.8 µA @ 100 Hz ODR、2.0 V电源
* 3.0 µA @ 400 Hz ODR、2.0 V电源
* 270 nA运动唤醒模式
* 10 nA待机电流
* 分辨率 1mg/LSB
可谓是功耗非常低,ADLX362支持SPI的通信方式。本节内容讨论ADLX362 SPI的相关配置内容。

ADXL基本情况

通过数据手册可以知道ADLX362 SPI遵循模式为* CPHA = CPOL = 0 *(不工作时,时钟状态是低电平;在上升沿即第一个时钟沿采样数据)
ADXL362 初次使用总结(使用stm32 HAL 库)_第1张图片
数据手册中还提到,SPI操作使用多字节结构,第一个字节是命令。
* 0x0A 写入寄存器
* 0x0B 读取寄存器
* 0x0D 读取FIFO
也就是说在配置寄存器时,要先发送0x0A,紧接着是地址,然后是所要写入的内容,这样设备才能够确认是要写入寄存器。
而要读出寄存器内容时,要先发送0x0B,然后是地址,这样才能读出寄存器内容(以往好多设备是以地址的最高位来判断读写的,通常最高位是1就是读;最高位是0,表示写,这里有点不同)
如果是从fifo中读取加速度的值,需要先发送0x0D,紧接着就是读取数据了。

使用STM32l4xx HAL库配置SPI

本适合使用stm32 提供的HAL库,初始化函数为:

void spi1_init(void)
{
    SpiHandle_1.Instance               = SPI1;
    SpiHandle_1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; //2.5MHZ
    SpiHandle_1.Init.Direction         = SPI_DIRECTION_2LINES;
    SpiHandle_1.Init.CLKPhase          = SPI_PHASE_1EDGE;  //SPI_PHASE_1EDGE
    SpiHandle_1.Init.CLKPolarity       = SPI_POLARITY_LOW; //SPI_POLARITY_LOW
    SpiHandle_1.Init.DataSize          = SPI_DATASIZE_8BIT;
    SpiHandle_1.Init.FirstBit          = SPI_FIRSTBIT_MSB;
    SpiHandle_1.Init.TIMode            = SPI_TIMODE_DISABLE;
    SpiHandle_1.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
    SpiHandle_1.Init.CRCPolynomial     = 7;
    SpiHandle_1.Init.CRCLength         = SPI_CRC_LENGTH_8BIT;
    SpiHandle_1.Init.NSS               = SPI_NSS_SOFT;
    SpiHandle_1.Init.NSSPMode          = SPI_NSS_PULSE_DISABLE;
    //master mode
    SpiHandle_1.Init.Mode = SPI_MODE_MASTER;
    if(HAL_SPI_Init(&SpiHandle_1) != HAL_OK)
    {
        /* Initialization Error */
        Error_Handler();
    }
}

以及包括

/**
  * @brief SPI MSP Initialization 
  *        This function configures the hardware resources used in this example: 
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration  
  * @param hspi: SPI handle pointer
  * @retval None
  */
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

  if(hspi->Instance == SPI1)
  {     
    /*##-1- Enable peripherals and GPIO Clocks #################################*/
    /* Enable GPIO TX/RX clock */
    SPI1_SCK_GPIO_CLK_ENABLE();
    SPI1_MISO_GPIO_CLK_ENABLE();
    SPI1_MOSI_GPIO_CLK_ENABLE();
    /* Enable SPI clock */
    SPI1_CLK_ENABLE(); 

    /*##-2- Configure peripheral GPIO ##########################################*/  
    /* SPI SCK GPIO pin configuration  */
    GPIO_InitStruct.Pin       = SPI1_SCK_PIN;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_PULLDOWN;  //GPIO_PULLDOWN
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = SPI1_SCK_AF;
    HAL_GPIO_Init(SPI1_SCK_GPIO_PORT, &GPIO_InitStruct);
    /* SPI MISO GPIO pin configuration  */
    GPIO_InitStruct.Pin = SPI1_MISO_PIN;
    GPIO_InitStruct.Alternate = SPI1_MISO_AF;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    HAL_GPIO_Init(SPI1_MISO_GPIO_PORT, &GPIO_InitStruct);
    /* SPI MOSI GPIO pin configuration  */
    GPIO_InitStruct.Pin = SPI1_MOSI_PIN;
    GPIO_InitStruct.Alternate = SPI1_MOSI_AF;
    HAL_GPIO_Init(SPI1_MOSI_GPIO_PORT, &GPIO_InitStruct);
  }
}

有两点需要注意的是:
1. 在spi1_init()中,正确配置SPI模式,比如SPI_PHASE_1EDGE,SPI_POLARITY_LOW,这都是adxl362所要求的(时钟低电平,第一个沿采样数据)。
2. 在HAL_SPI_MspInit()中,配置IO相关寄存器,SCK IO 要选择GPIO_PULLDOWN 模式,其他IO选择GPIO_PULLUP模式,否则会出现初次配置adxl寄存器的时候失败,接着读取寄存器正常的情况。

SPI读写函数

static void Sensor_IO_Write(uint8_t WriteAddr, uint8_t *pBuffer, uint16_t nBytesToWrite )
{
    //HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
     //                                     uint32_t Timeout)
    uint8_t reg_cmd = 0;
    reg_cmd = ADXL362_WRITE_REG;
    adxl362_enable();
    HAL_SPI_Transmit(&SpiHandle_1, ®_cmd, 1, 1000);
    HAL_SPI_Transmit(&SpiHandle_1, &WriteAddr, 1, 1000);
    HAL_SPI_Transmit(&SpiHandle_1, pBuffer, nBytesToWrite, 1000);
    adxl362_disable();
}

static void Sensor_IO_Read(uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead, uint8_t r_flag)
{

    //HAL_SPI_Receive
    uint8_t rd_addr = 0;
    uint8_t reg_cmd = 0;
    rd_addr = ReadAddr;
    adxl362_enable();
    if(r_flag == ADXL362_READ_REG){
        reg_cmd = ADXL362_READ_REG;
        HAL_SPI_Transmit(&SpiHandle_1, ®_cmd, 1, 1000);
        HAL_SPI_Transmit(&SpiHandle_1, &rd_addr, 1, 1000);
    }
    if(r_flag == ADXL362_READ_FIFO){
        reg_cmd = ADXL362_READ_FIFO;
        HAL_SPI_Transmit(&SpiHandle_1, ®_cmd, 1, 1000);
    }
    HAL_SPI_Receive(&SpiHandle_1, pBuffer, nBytesToRead, 1000);
    adxl362_disable();

}

跟使用手册中的操作顺序要一致。
adxl362别的操作就不多写了,按照数据手册配置寄存器,基本没什么问题了。

你可能感兴趣的:(物联网,stm32)