ADXL345加速度传感器驱动

ADXL345 是 ADI 公司的一款 3 轴、数字输出的加速度传感器。ADXL345 是 ADI 公司推
出的基于 iMEMS 技术的 3 轴、数字输出加速度传感器。该加速度传感器的特点有:
  分辨率高。最高 13 位分辨率。
  量程可变。具有+/-2g,+/-4g,+/-8g,+/-16g 可变的测量范围。
  灵敏度高。最高达 3.9mg/LSB,能测量不到 1.0°的倾斜角度变化。
  功耗低。40~145uA 的超低功耗,待机模式只有 0.1uA。
  尺寸小。整个 IC 尺寸只有 3mm*5mm*1mm,LGA 封装。
ADXL 支持标准的 I2C 或 SPI 数字接口,自带 32 级 FIFO 存储,并且内部有多种运动状态

检测和灵活的中断方式等特性

  加速度传感器一般都有三个轴,垂直于芯片为Z轴,检测重力,平行于芯片分别为XY轴,三个轴得到三种加速度,经过合成,可以得到物体在匀速运动时候的姿态,这是一个相对静止的姿态,

因为静止状态,物体仅受到重力加速度的影响,通过姿态重力加速度产生分量作用在三个轴上,通过这个分量可以计算加速度传感器和地面参考系之间的夹角从而得到姿态

 因为是IIC总线,所以还是居于IIC标准通讯的,修改功能使能IIC总线修改寄存器即可,寄存器框图如下


对于加速度传感器的功能配置各有不同,以下是基础配置的代码

#include "adxl345.h"
#include "delay.h"
#include "math.h"   

//初始化ADXL345.
//返回值:0,初始化成功;1,初始化失败.
u8 Adxl345Init(void)
{				  
    IIcInit();							//初始化IIC总线	
    if(Adxl345ReadReg(DEVICE_ID)==0XE5)	//读取器件ID
    {  
        Adxl345WRReg(DATA_FORMAT,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 
        Adxl345WRReg(BW_RATE,0x0A);		//数据输出速度为100Hz
        Adxl345WRReg(POWER_CTL,0x28);	   	//链接使能,测量模式
        Adxl345WRReg(INT_ENABLE,0x00);	//不使用中断		 
        Adxl345WRReg(OFSX,0x00);
        Adxl345WRReg(OFSY,0x00);
        Adxl345WRReg(OFSZ,0x00);	
        return 0;
    }			
    return 1;	   								  
}   



//写ADXL345寄存器
//addr:寄存器地址
//val:要写入的值
//返回值:无
void Adxl345WRReg(u8 addr,u8 val) 
{
    IIcStart();  				 
    IIcSendByte(ADXL_WRITE);     	//发送写器件指令	 
    IIcWaitAck();	   
    IIcSendByte(addr);   			//发送寄存器地址
    IIcWaitAck(); 	 										  		   
    IIcSendByte(val);     		//发送值					   
    IIcWaitAck();  		    	   
    IIcStop();						//产生一个停止条件 	   
}


//读ADXL345寄存器
//addr:寄存器地址
//返回值:读到的值
u8 Adxl345ReadReg(u8 addr) 		
{
    u8 temp=0;		 
    IIcStart();  				 
    IIcSendByte(ADXL_WRITE);	//发送写器件指令	 
    temp=IIcWaitAck();	   
    IIcSendByte(addr);   		//发送寄存器地址
    temp=IIcWaitAck(); 	 										  		   
    IIcStart();  	 	   		//重新启动
    IIcSendByte(ADXL_READ);	//发送读器件指令	 
    temp=IIcWaitAck();	   
    temp=IIcReadByte(0);		//读取一个字节,不继续再读,发送NAK 	    	   
    IIcStop();					//产生一个停止条件 	    
    return temp;				//返回读到的值
} 



//读取ADXL的平均值
//x,y,z:读取10次后取平均值
void Adxl345ReadAvval(short *x,short *y,short *z)
{
    short tx=0,ty=0,tz=0;	   
    u8 i;  
    for(i=0;i<10;i++)
    {
        Adxl345ReadXyz(x,y,z);
        DelayMs(10);
        tx+=(short)*x;
        ty+=(short)*y;
        tz+=(short)*z;	   
    }
    *x=tx/10;
    *y=ty/10;
    *z=tz/10;
} 



//自动校准
//xval,yval,zval:x,y,z轴的校准值
void Adxl345AutoAdjust(char *xval,char *yval,char *zval)
{
    short tx,ty,tz;
    u8 i;
    short offx=0,offy=0,offz=0;
    Adxl345WRReg(POWER_CTL,0x00);	   	//先进入休眠模式.
    DelayMs(100);
    Adxl345WRReg(DATA_FORMAT,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 
    Adxl345WRReg(BW_RATE,0x0A);		//数据输出速度为100Hz
    Adxl345WRReg(POWER_CTL,0x28);	   	//链接使能,测量模式
    Adxl345WRReg(INT_ENABLE,0x00);	//不使用中断		 
    
    Adxl345WRReg(OFSX,0x00);
    Adxl345WRReg(OFSY,0x00);
    Adxl345WRReg(OFSZ,0x00);
    DelayMs(12);
    for(i=0;i<10;i++)
    {
        Adxl345ReadAvval(&tx,&ty,&tz);
        offx+=tx;
        offy+=ty;
        offz+=tz;
    }	 		
    offx/=10;
    offy/=10;
    offz/=10;
    *xval=-offx/4;
    *yval=-offy/4;
    *zval=-(offz-256)/4;	  
    Adxl345WRReg(OFSX,*xval);
    Adxl345WRReg(OFSY,*yval);
    Adxl345WRReg(OFSZ,*zval);	
} 



//读取3个轴的数据
//x,y,z:读取到的数据
void Adxl345ReadXyz(short *x,short *y,short *z)
{
    u8 buf[6];
    u8 i;
    IIcStart();  				 
    IIcSendByte(ADXL_WRITE);	//发送写器件指令	 
    IIcWaitAck();	   
    IIcSendByte(0x32);   		//发送寄存器地址(数据缓存的起始地址为0X32)
    IIcWaitAck(); 	 										  		   
    
    IIcStart();  	 	   		//重新启动
    IIcSendByte(ADXL_READ);	//发送读器件指令
    IIcWaitAck();
    for(i=0;i<6;i++)
    {
        if(i==5)buf[i]=IIcReadByte(0);//读取一个字节,不继续再读,发送NACK  
        else buf[i]=IIcReadByte(1);	//读取一个字节,继续读,发送ACK 
    }	        	   
    IIcStop();					//产生一个停止条件
    *x=(short)(((u16)buf[1]<<8)+buf[0]); 	    
    *y=(short)(((u16)buf[3]<<8)+buf[2]); 	    
    *z=(short)(((u16)buf[5]<<8)+buf[4]); 	   
}



//读取ADXL345的数据times次,再取平均
//x,y,z:读到的数据
//times:读取多少次
void Adxl345ReadAverage(short *x,short *y,short *z,u8 times)
{
    u8 i;
    short tx,ty,tz;
    *x=0;
    *y=0;
    *z=0;
    if(times)//读取次数不为0
    {
        for(i=0;i<times;i++)//连续读取times次
        {
            Adxl345ReadXyz(&tx,&ty,&tz);
            *x+=tx;
            *y+=ty;
            *z+=tz;
            DelayMs(5);
        }
        *x/=times;
        *y/=times;
        *z/=times;
    }
	printf("x = %d, y = %d ,z = %d \r\n",*x,*y,*z);
}



//得到角度
//x,y,z:x,y,z方向的重力加速度分量(不需要单位,直接数值即可)
//dir:要获得的角度.0,与Z轴的角度;1,与X轴的角度;2,与Y轴的角度.
//返回值:角度值.单位0.1°.
short Adxl345GetAngle(float x,float y,float z,u8 dir)
{
    float temp;
    float res=0;
    switch(dir)
    {
    case 0://与自然Z轴的角度
        temp=sqrt((x*x+y*y))/z;
        res=atan(temp);
        break;
    case 1://与自然X轴的角度
        temp=x/sqrt((y*y+z*z));
        res=atan(temp);
        break;
    case 2://与自然Y轴的角度
        temp=y/sqrt((x*x+z*z));
        res=atan(temp);
        break;
    }
    return (short)(res*1800/3.14);
}


#ifndef __ADXL345_H
#define __ADXL345_H
#include "iic.h"   
#include "uart.h"    




#define DEVICE_ID 0X00 //器件ID,0XE5
#define THRESH_TAP 0X1D   //敲击阀值
#define OFSX 0X1E
#define OFSY 0X1F
#define OFSZ 0X20
#define DUR 0X21
#define Latent 0X22
#define Window   0X23 
#define THRESH_ACK 0X24
#define THRESH_INACT        0X25 
#define TIME_INACT 0X26
#define ACT_INACT_CTL        0X27  
#define THRESH_FF 0X28
#define TIME_FF 0X29 
#define TAP_AXES 0X2A  
#define ACT_TAP_STATUS          0X2B 
#define BW_RATE 0X2C 
#define POWER_CTL 0X2D 


#define INT_ENABLE 0X2E
#define INT_MAP 0X2F
#define INT_SOURCE          0X30
#define DATA_FORMAT        0X31
#define DATA_X0 0X32
#define DATA_X1 0X33
#define DATA_Y0 0X34
#define DATA_Y1 0X35
#define DATA_Z0 0X36
#define DATA_Z1 0X37
#define FIFO_CTL 0X38
#define FIFO_STATUS 0X39




//0X0B TO OX1F Factory Reserved  
//如果ALT ADDRESS脚(12脚)接地,IIC地址为0X53(不包含最低位).
//如果接V3.3,则IIC地址为0X1D(不包含最低位).
//因为开发板接V3.3,所以转为读写地址后,为0X3B和0X3A(如果接GND,则为0XA7和0XA6)  
#define ADXL_READ    0X3B
#define ADXL_WRITE   0X3A




u8 Adxl345Init(void); //初始化ADXL345




void Adxl345WRReg(u8 addr,u8 val); //写ADXL345寄存器




u8 Adxl345ReadReg(u8 addr); //读ADXL345寄存器




void Adxl345ReadXyz(short *x,short *y,short *z); //读取一次值




void Adxl345ReadAvval(short *x,short *y,short *z); //读取平均值




void Adxl345AutoAdjust(char *xval,char *yval,char *zval);//自动校准




void Adxl345ReadAverage(short *x,short *y,short *z,u8 times);//连续读取times次,取平均




short Adxl345GetAngle(float x,float y,float z,u8 dir);




#endif




























































































  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ADXL345是ADI公司推出的基于iMEMS技术的3轴、数字输出加速度传感器。它具有最高13位的分辨率、可变的测量范围、能测量不到1.0°的倾斜角度变化等特点。ADXL345支持标准的I2C或SPI数字接口,自带32级FIFO存储,并且内部有多种状态检测和灵活的中断方式等特性。在STM32驱动ADXL345的过程中,可以按照以下步骤进行操作: 1. 初始化ADXL345传感器,可以使用ADXL345_Init函数进行初始化。该函数会初始化IIC总线,并设置ADXL345的一些参数,如数据格式、数据输出速度、工作模式等。 2. 读取ADXL345三个方向的加速度值,可以使用ADXL345_RD_Reg函数读取传感器的寄存器值。 3. 通过加速度的值计算角度值,可以根据加速度值的变化来计算传感器的倾斜角度。 4. 在主函数中显示测试结果,可以通过串口打印显示传感器的加速度值和转换后的角度值。 需要注意的是,以上是一个简单的程序框架,具体的实现还需要根据具体的硬件平台和编程语言进行适配。可以参考引用\[2\]中提供的程序框架进行具体的驱动开发。 #### 引用[.reference_title] - *1* [STM32CubeMX系列|ADXL345传感器](https://blog.csdn.net/Chuangke_Andy/article/details/108987310)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [STM32——库函数版——ADXL345驱动程序](https://blog.csdn.net/qq_45844792/article/details/118565633)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值