使用STM32 CubeMX配置adxl345加速度传感器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、硬件连线
  • 二、CubeMX配置I2C
  • 三、adxl345的读取操作
  • 3.1 读取adxl345的设备id
  • 3.2 初始化adxl345
  • 初始化DATA_FORMAT寄存器
  • 数据输出速率
  • POWER_CRL寄存器设置
  • 禁止中断
  • 3.3 读取x、y、z轴的加速度
  • 3.4 读取示例
  • 3.5 得到角度
  • 3.6 滤波处理
  • 总结

  • 前言

    本篇文章使用I2C进行通信
    在嵌入式系统中,加速度传感器是一种常见的传感器,用于检测物体的加速度或者倾斜角度。ADXL345是一款常用的数字三轴加速度传感器,由ADI(Analog Devices)公司制造。它具有高精度、低功耗和可编程的特点,因此在很多嵌入式应用中被广泛使用。本文将介绍如何在STM32 CubeMX中配置和使用ADXL345加速度传感器。


    一、硬件连线

    对于I2C adxl345,由于adxl345不仅可以进行I2C通信,也可以进行SPI通信,所以对于I2C通信,我们不仅需要连接VCC、GND、SCL、SDA等常规的引脚,我们还需要对CS片选引脚连到电源3.3V.
    我们不仅需要连接CS到电源,我们还需要连接SDO引脚连接到电源。
    通过这两步的连线,得到adxl345的读写地址为:写:0x3A 读:0x3B

    二、CubeMX配置I2C

    首先,我们选择一个可用的I2C

    接下来,开启该I2C即可。

    三、adxl345的读取操作

    3.1 读取adxl345的设备id

    阅读芯片手册可得读取0x00地址,我们可以得到他的设备id,并且这个地址只能读,如果得到的数据为0xE5
    代表设备读取成功

    3.2 初始化adxl345

    初始化DATA_FORMAT寄存器

    DATA_FORMAT寄存器的各个位的意义如下,我们可以通过组合,然后发送给adxl345的0x31地址
    位7 – Self-Test Bit(自检位):
    可取值:0或1
    0:禁用自检功能
    1:启用自检功能。在自检模式下,传感器会在每个轴上施加一个已知的加速度,用于自我测试和校准。

    位6 – SPI Bit(SPI接口位):
    可取值:0或1
    0:选择4线SPI模式(默认模式)
    1:选择3线SPI模式

    位5 – Interrupt Invert Bit(中断输出反转位):
    可取值:0或1
    0:中断输出极性不反转(默认)
    1:中断输出极性反转。可用于将中断信号与外部器件的期望极性匹配。

    位4 – 不使用(保留位)

    位3 – Full-Resolution Bit(完整分辨率位):
    可取值:0或1
    0:禁用完整分辨率模式(默认)
    1:启用完整分辨率模式。在完整分辨率模式下,传感器提供最高分辨率的数据输出。

    位2 – Justify Bit(数据对齐位):
    可取值:0或1
    0:左对齐模式
    1:右对齐模式(默认)。决定了数据在输出寄存器中的对齐方式。

    位1-0 – Range Bits(范围位):
    可取值:00、01、10、11
    00:±2g
    01:±4g
    10:±8g
    11:±16g。这两位用于选择加速度的测量范围,影响传感器的灵敏度和测量范围。

    数据输出速率

    我们可以通过设置BW_RATE寄存器来设置数据输出速率。数据输出速率就是输出数据的快慢。
    该寄存器是8位的,其中高4位用于设置数据输出速率,低4位用于设置电源模式。
    他的地址为0x2C

    以下是BW_RATE寄存器中高4位的数据输出速率选项及其对应的取值:

    取值 0000:数据输出速率为 0.10 Hz
    取值 0001:数据输出速率为 0.20 Hz
    取值 0010:数据输出速率为 0.39 Hz
    取值 0011:数据输出速率为 0.78 Hz
    取值 0100:数据输出速率为 1.56 Hz
    取值 0101:数据输出速率为 3.13 Hz
    取值 0110:数据输出速率为 6.25 Hz
    取值 0111:数据输出速率为 12.5 Hz
    取值 1000:数据输出速率为 25 Hz
    取值 1001:数据输出速率为 50 Hz
    取值 1010:数据输出速率为 100 Hz
    取值 1011:数据输出速率为 200 Hz
    取值 1100:数据输出速率为 400 Hz
    取值 1101:数据输出速率为 800 Hz
    取值 1110:数据输出速率为 1600 Hz
    取值 1111:数据输出速率为 3200 Hz
    

    低4位用于设置电源模式,但在大多数情况下,这些位应该设置为默认值(0),以选择正常功耗模式。
    比如我们要使用100Hz,正常电源模式就要写入0x0A

    POWER_CRL寄存器设置

    ADXL345的POWER_CTL寄存器用于控制传感器的电源和操作模式。它是一个8位寄存器,每一位都有特定的功能。以下是各位的作用及取值:

    位 7(0x80):HSE(High-Speed Enable)
    当此位设置为 1 时,传感器工作在高速模式下(3.2 kHz)。否则,传感器在正常模式下工作。
    取值:1(高速模式),0(正常模式)。

    位 6(0x40):休眠模式
    当此位设置为 1 时,传感器进入休眠模式,功耗降低到最低水平。
    取值:1(进入休眠模式),0(退出休眠模式)。

    位 5(0x20):测量
    设置此位为 1 时,传感器开始进行测量。
    取值:1(开始测量),0(停止测量)。

    位 4(0x10):AUTO_SLEEP
    如果启用自动睡眠模式,传感器将在没有活动时自动进入睡眠模式。
    取值:1(启用自动睡眠模式),0(禁用自动睡眠模式)。

    位 3(0x08):测量
    如果测量位设置为 1,传感器处于测量模式。在这种模式下,传感器将执行测量,并在测量完成后将该位清零。
    取值:1(正在测量),0(测量结束)。

    位 2(0x04):休眠模式
    设置此位为 1,将传感器置于休眠模式。
    取值:1(休眠模式),0(正常模式)。

    位 1(0x02):休眠
    如果设置为 1,传感器进入休眠模式。
    取值:1(进入休眠模式),0(退出休眠模式)。

    位 0(0x01):休眠
    与位 1 具有相同的功能,但是当此位和位 1 同时设置时,优先级更高。
    取值:1(进入休眠模式),0(退出休眠模式)。

    如果你想写入数据,你应该写0x2D地址
    如果你想测量的话,你需要设置该寄存器为0x28

    禁止中断

    在adxl345上面可以看到INT1,INT2,这些是中断引脚,但是我们并不需要使用中断,我们可以使用下面的代码进行禁用:

    HAL_I2C_Mem_Write(&hi2c1,WRITE,0x2E,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    HAL_I2C_Mem_Write(&hi2c1,WRITE,0x1E,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    HAL_I2C_Mem_Write(&hi2c1,WRITE,0X1F,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    HAL_I2C_Mem_Write(&hi2c1,WRITE,0X20,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    

    3.3 读取x、y、z轴的加速度

    通过芯片手册可以知道,我们读下面的寄存器即可得到x、y、z轴的加速度

    DATAX0为低位,DATAX1为高位。
    我们可以通过下面的公式进行转换:

    (short)(((uint16_t)readData[1]<<8)+readData[0])
    

    3.4 读取示例

    #define WRITE 0x3A
    #define READ 0x3B
    
    int BeginADXL345(void)
    {
    	uint8_t id,val;
      HAL_I2C_Mem_Read(&hi2c1,READ,0x00,I2C_MEMADD_SIZE_8BIT,&id,1,0xff);   
    	if(id ==0XE5){      //读器件ID,ADXL345的器件ID为0XE5
    			val = 0x2B;     //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0x31,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			val = 0x0A;     //数据输出速度为100Hz
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0x2C,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			val = 0x28;     //链接使能,测量模式
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0x2D,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			val = 0x00;     //不使用中断
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0x2E,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0x1E,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0X1F,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			HAL_I2C_Mem_Write(&hi2c1,WRITE,0X20,I2C_MEMADD_SIZE_8BIT,&val,1,0xFF);
    			return 0;
    	}           
    	return 1;
    }
    
    typedef struct ADXLData
    {
    	short x;
    	short y;
    	short z;
    }ADXLData;
    
    ADXLData readADXL345()
    {
    	uint8_t readData[6] = {0};
    	ADXLData ret;
    	
    	int r = HAL_I2C_Mem_Read(&hi2c1,READ,0x32,I2C_MEMADD_SIZE_8BIT,readData,6,1000);
    	if(r == HAL_OK)
    		printf("read OK\n");
    	else
    		printf("Error %d\n",r);
    	
    	int16_t x_accel, y_accel, z_accel;
    	int16_t x_accel_raw, y_accel_raw, z_accel_raw;
    
    	ret.x=(short)(((uint16_t)readData[1]<<8)+readData[0]);   //DATA_X1为高位有效字节    
    	ret.y=(short)(((uint16_t)readData[3]<<8)+readData[2]);   //DATA_Y1为高位有效字节        
    	ret.z=(short)(((uint16_t)readData[5]<<8)+readData[4]);   //DATA_Z1为高位有效字节   
    	
    	return ret;
    }
    
    /* USER CODE BEGIN 2 */
    	
    BeginADXL345();
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    	data = readADXL345();
    	printf("X: %hd   Y:%hd  Z:%hd\n",data.x,data.y,data.z);
    	printf("angle_X:%hd\n",ADXL345_Get_Angle((double)data.x,(double)data.y,(double)data.z,0));
    	HAL_Delay(1000);
       /* USER CODE END WHILE */
    
       /* USER CODE BEGIN 3 */
     }
    

    3.5 得到角度

    adxl345不仅可以测量各个轴的加速度,还可以根据他们测量出各个轴的角度:
    我们可以使用下面这个函数进行角度的计算:

    short ADXL345_Get_Angle(float x,float y,float z,uint8_t dir){
        float temp;
        float res=0;    //弧度值
        switch(dir){
            case 0:     //0表示与Z轴的角度
                temp=sqrt((x*x+y*y))/z;
                res=atan(temp);
                break;
            case 1:     //1表示与X轴的角度
                temp=x/sqrt((y*y+z*z));
                res=atan(temp);
                break;
            case 2:     //2表示与Y轴的角度
                temp=y/sqrt((x*x+z*z));
                res=atan(temp);
                break;
        }
        return res*180/3.14;    //返回角度值
    }
    

    3.6 滤波处理

    对于adxl345可能读取的有一定的偏差,这时我们可以使用多次测量取平均值,得到最后一个较为准确的值:

    /*读取ADXL345的数据并做滤波处理,读times次再取平均值*/
    void ADXL345_Read_Average(short *x,short *y,short *z,uint8_t times){
        uint8_t i;
        ADXLData data;
        *x=0; *y=0; *z=0;
        if(times){
            for(i=0;i<times;i++){
                data = readADXL345();
                *x+=data.x; *y+=data.y; *z+=data.z;
                HAL_Delay(5);
            }
            *x/=times; *y/=times; *z/=times;
        }
    }   
    

    总结

    本文简要介绍了如何在STM32 CubeMX中配置和使用ADXL345加速度传感器。首先,我们介绍了ADXL345传感器的基本原理和特点,然后详细说明了在CubeMX中如何配置I2C接口以及相关的GPIO引脚。接着,我们演示了如何通过I2C总线与ADXL345通信,并读取其加速度数据。最后,我们提供了一些示例代码和调试技巧,以帮助开发者更好地理解和使用ADXL345传感器。

    通过本文的学习,读者可以掌握在STM32嵌入式系统中使用ADXL345加速度传感器的基本方法,为实际项目的开发和应用提供了参考和指导。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用STM32 CubeMX配置adxl345加速度传感器

    发表评论