ADXL345是一款三轴加速度传感器,广泛用于手机、游戏手柄等设计。
ADXL 支持标准的 I2C 或 SPI 数字接口,自带 32 级 FIFO 存储,并且内 部有多种运动状态检测和灵活的中断方式等特性,常用I2C接口


检测轴

初始化步骤
1) 上电
2) 等待 1.1ms
3) 初始化命令序列
4) 结束
其中上电这个动作发生在开发板第一次上电的时候,在上电之后,等待 1.1ms 左右,就可以开始发送初始化序列了,初始化序列一结束, ADXL345 就 开始正常工作了


stm里的硬件电路

adxl345.c

#include "adxl345.h"
#include "iic.h"
#include "math.h"
#include "SysTick.h"//初始化ADXL345.
//返回值:0,初始化成功;1,初始化失败.
u8 ADXL345_Init(void)
{                 IIC_Init();                         //初始化IIC总线  if(ADXL345_RD_Reg(DEVICE_ID)==0XE5) //读取器件ID{  ADXL345_WR_Reg(DATA_FORMAT,0X2B);   //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A);       //数据输出速度为100HzADXL345_WR_Reg(POWER_CTL,0x28);     //链接使能,测量模式ADXL345_WR_Reg(INT_ENABLE,0x00);    //不使用中断      ADXL345_WR_Reg(OFSX,0x00);ADXL345_WR_Reg(OFSY,0x00);ADXL345_WR_Reg(OFSZ,0x00);  return 0;}           return 1;
} //写ADXL345寄存器
//addr:寄存器地址
//val:要写入的值
//返回值:无
void ADXL345_WR_Reg(u8 addr,u8 val)
{IIC_Start();                 IIC_Send_Byte(ADXL_WRITE);      //发送写器件指令    IIC_Wait_Ack();    IIC_Send_Byte(addr);            //发送寄存器地址IIC_Wait_Ack();                                                        IIC_Send_Byte(val);             //发送值                      IIC_Wait_Ack();                    IIC_Stop();                     //产生一个停止条件
} //读ADXL345寄存器
//addr:寄存器地址
//返回值:读到的值
u8 ADXL345_RD_Reg(u8 addr)
{u8 temp=0;       IIC_Start();                 IIC_Send_Byte(ADXL_WRITE);  //发送写器件指令    temp=IIC_Wait_Ack();       IIC_Send_Byte(addr);        //发送寄存器地址temp=IIC_Wait_Ack();                                                       IIC_Start();                //重新启动IIC_Send_Byte(ADXL_READ);   //发送读器件指令    temp=IIC_Wait_Ack();       temp=IIC_Read_Byte(0);      //读取一个字节,不继续再读,发送NAK               IIC_Stop();                 //产生一个停止条件      return temp;                //返回读到的值
} //读取3个轴的数据
//x,y,z:读取到的数据
void ADXL345_RD_XYZ(short *x,short *y,short *z)
{u8 buf[6];u8 i;IIC_Start();                 IIC_Send_Byte(ADXL_WRITE);  //发送写器件指令    IIC_Wait_Ack();    IIC_Send_Byte(0x32);        //发送寄存器地址(数据缓存的起始地址为0X32)IIC_Wait_Ack();                                                        IIC_Start();                //重新启动IIC_Send_Byte(ADXL_READ);   //发送读器件指令IIC_Wait_Ack();for(i=0;i<6;i++){if(i==5)buf[i]=IIC_Read_Byte(0);//读取一个字节,不继续再读,发送NACK  else buf[i]=IIC_Read_Byte(1);   //读取一个字节,继续读,发送ACK }                  IIC_Stop();                 //产生一个停止条件*x=(short)(((u16)buf[1]<<8)+buf[0]); //低字节先读,两个字节表示一个方向位的值    *y=(short)(((u16)buf[3]<<8)+buf[2]);        *z=(short)(((u16)buf[5]<<8)+buf[4]);
}//读取ADXL的平均值
//x,y,z:读取10次后取平均值
void ADXL345_RD_Avval(short *x,short *y,short *z)
{short tx=0,ty=0,tz=0;      u8 i;  for(i=0;i<10;i++){ADXL345_RD_XYZ(x,y,z);delay_ms(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 ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval)
{short tx,ty,tz;u8 i;short offx=0,offy=0,offz=0;ADXL345_WR_Reg(POWER_CTL,0x00);     //先进入休眠模式.delay_ms(100);ADXL345_WR_Reg(DATA_FORMAT,0X2B);   //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A);       //数据输出速度为100HzADXL345_WR_Reg(POWER_CTL,0x28);     //链接使能,测量模式ADXL345_WR_Reg(INT_ENABLE,0x00);    //不使用中断      ADXL345_WR_Reg(OFSX,0x00);ADXL345_WR_Reg(OFSY,0x00);ADXL345_WR_Reg(OFSZ,0x00);delay_ms(12);for(i=0;i<10;i++){ADXL345_RD_Avval(&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;      ADXL345_WR_Reg(OFSX,*xval);ADXL345_WR_Reg(OFSY,*yval);ADXL345_WR_Reg(OFSZ,*zval);
}//读取ADXL345的数据times次,再取平均
//x,y,z:读到的数据
//times:读取多少次
void ADXL345_Read_Average(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次{ADXL345_RD_XYZ(&tx,&ty,&tz);*x+=tx;*y+=ty;*z+=tz;delay_ms(5);}*x/=times;*y/=times;*z/=times;}
} //得到角度
//x,y,z:x,y,z方向的重力加速度分量(不需要单位,直接数值即可)
//dir:要获得的角度.0,与Z轴的角度;1,与X轴的角度;2,与Y轴的角度.
//返回值:角度值.单位0.1°.
//res得到的是弧度值,需要将其转换为角度值也就是*180/3.14
short ADXL345_Get_Angle(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 res*180/3.14;
}

adxl345.h

#ifndef _adxl345_H
#define _adxl345_H#include "system.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脚)接地,ADXL地址为0X53(不包含最低位).
//如果接V3.3,则ADXL地址为0X1D(不包含最低位).
//因为开发板接V3.3,所以转为读写地址后,为0X3B和0X3A(如果接GND,则为0XA7和0XA6)
#define ADXL_READ    0X3B
#define ADXL_WRITE   0X3Au8 ADXL345_Init(void);                              //初始化ADXL345
void ADXL345_WR_Reg(u8 addr,u8 val);                //写ADXL345寄存器
u8 ADXL345_RD_Reg(u8 addr);                         //读ADXL345寄存器
void ADXL345_RD_XYZ(short *x,short *y,short *z);    //读取一次值
void ADXL345_RD_Avval(short *x,short *y,short *z);  //读取平均值
void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval);//自动校准
void ADXL345_Read_Average(short *x,short *y,short *z,u8 times);//连续读取times次,取平均
short ADXL345_Get_Angle(float x,float y,float z,u8 dir);#endif

main.c

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "tftlcd.h"
#include "key.h"
#include "adxl345.h"//x,y:开始显示的坐标位置
//num:要显示的数据
//mode:0,显示加速度值;1,显示角度值;
void ADXL_Show_num(u16 x,u16 y,short num,u8 mode)   //ADXL345显示
{u8 valbuf[3];if(mode==0)   //显示加速度值{if(num<0){num=-num;LCD_ShowString(x,y,tftlcd_data.width,tftlcd_data.height,16,"-");}else{LCD_ShowString(x,y,tftlcd_data.width,tftlcd_data.height,16," ");}valbuf[0]=num/100+0x30;valbuf[1]=num%100/10+0x30;valbuf[2]=num%100%10+0x30;  LCD_ShowString(x+10,y,tftlcd_data.width,tftlcd_data.height,16,valbuf);  }else         //显示角度值{if(num<0){num=-num;LCD_ShowString(x,y,tftlcd_data.width,tftlcd_data.height,16,"-");}else{LCD_ShowString(x,y,tftlcd_data.width,tftlcd_data.height,16," ");}valbuf[0]=num/10+0x30;valbuf[1]='.';valbuf[2]=num%10+0x30;  LCD_ShowString(x+10,y,tftlcd_data.width,tftlcd_data.height,16,valbuf);      }
}void data_pros()    //数据处理函数
{short x,y,z;short xang,yang,zang;   u8 key;ADXL345_Read_Average(&x,&y,&z,10);  //读取x,y,z 3个方向的加速度值 总共10次ADXL_Show_num(60,120,x,0);ADXL_Show_num(60,140,y,0);ADXL_Show_num(60,160,z,0);xang=ADXL345_Get_Angle(x,y,z,1);yang=ADXL345_Get_Angle(x,y,z,2);zang=ADXL345_Get_Angle(x,y,z,0);ADXL_Show_num(60,180,xang,1);ADXL_Show_num(60,200,yang,1);ADXL_Show_num(60,220,zang,1);key=KEY_Scan(0);if(key==KEY_UP)       //按下K_UP校准{led2=0;     //LED2亮表示正在校准ADXL345_AUTO_Adjust((char*)&x,(char*)&y,(char*)&z);led2=1;    //LED2灭表示校准完成}
}int main()
{u8 i=0;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组LED_Init();USART1_Init(9600);TFTLCD_Init();          //LCD初始化KEY_Init();FRONT_COLOR=BLACK;LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"PRECHIN STM32F1");LCD_ShowString(10,30,tftlcd_data.width,tftlcd_data.height,16,"www.prechin.net");LCD_ShowString(10,50,tftlcd_data.width,tftlcd_data.height,16,"ADXL345 Test");LCD_ShowString(10,90,tftlcd_data.width,tftlcd_data.height,16,"K_UP:ADXL345 Adjust");LCD_ShowString(10,120,tftlcd_data.width,tftlcd_data.height,16,"X Val:");LCD_ShowString(10,140,tftlcd_data.width,tftlcd_data.height,16,"Y Val:");LCD_ShowString(10,160,tftlcd_data.width,tftlcd_data.height,16,"Z Val:");LCD_ShowString(10,180,tftlcd_data.width,tftlcd_data.height,16,"X Ang:");LCD_ShowString(10,200,tftlcd_data.width,tftlcd_data.height,16,"Y Ang:");LCD_ShowString(10,220,tftlcd_data.width,tftlcd_data.height,16,"Z Ang:");FRONT_COLOR=RED;while(ADXL345_Init()){printf("ADXL345 Error!\r\n");LCD_ShowString(130,50,tftlcd_data.width,tftlcd_data.height,16,"Error  ");delay_ms(200);}printf("ADXL345 OK!\r\n");LCD_ShowString(130,50,tftlcd_data.width,tftlcd_data.height,16,"Success");while(1){i++;if(i%20==0){led1=!led1;data_pros();}delay_ms(10);}}
4.PNG

stm32---ADXL345相关推荐

  1. stm32 ADXL345传感器

    加速度灵敏度轴 沿敏感轴加速时相应输出电压增加 寄存器映射 寄存器定义 0x31-DATA_FORMAT SELF_TEST位:设置为1,自测力应用至传感器,造成输出数据转换.值为0时,禁用自测力 S ...

  2. STM32驱动ADXL345三轴传感器

    简介:STM32F103C8T6驱动ADXL345三轴倾斜度传感器源码介绍. 开发平台:KEIL ARM MCU型号:STM32F103C8T6 传感器型号:ADXL345 特别提示:驱动内可能使用了 ...

  3. stm32软件模拟I2C读取ADXL345三轴加速度值

    最近做一个实验室里的小项目,需要用stm32来读取ADXL345三轴加速度的值,本来硬件I2C都调好了,可是后来和实验室合作的一个公司给的板子却没把硬件I2C的端口给引出来,太伤心了,我又得重新调一下 ...

  4. 【STM32+cubemx】0011 HAL库开发:I2C总线访问加速度传感器ADXL345

    本节我们介绍I2C总线,并使用stm32的I2C总线来访问加速度传感器ADXL345. 1)I2C基础知识 I2C总线通信比较适合设备内部各芯片间的通信,它只需要两根信号线. I2C可以挂载多个主机和 ...

  5. STM32 SPI NSS 作用

    STM32 SPI NSS 作用 原创 2017年06月16日 11:18:14 142 SSM可以控制内部NSS引脚与SSI(一个寄存器,软件模式)相连,还是与NSS外部引脚(真正的STM32引脚, ...

  6. ADXL345知识学习总结

    三轴加速度传感器ADXL345 一.ADXL345是一款三轴.数字化的加速度传感器,它能测X.Y.Z三个方向轴上的加速度,它可以在倾斜检测应用中测量静态重力加速度,还可以测量运动或冲击导致的动态加速度 ...

  7. ADXL345 驱动代码

    #include "adxl345.h" #include "sys.h" #include "delay.h" #include &quo ...

  8. 基于STM32蓝牙无线手环脉搏心率计步器体温监测设计

    一.电路设计 电路构成:STM32F103C8T6单片机电路+时钟晶振电路+复位电路(上电自复位,手动复位)+LCD1602液晶显示屏电路+ADXL345计步检测传感器电路+DS18B20温度传感器电 ...

  9. STM32单片机蓝牙APP智能急救手表跌倒报警心率报警MAX30102

    实践制作DIY- GC0083-智能急救手表 一.功能说明: 基于STM32单片机设计-智能急救手表 功能介绍: STM32F103C系列最小系统板+OLED显示器+MAX30102心率传感器+蜂鸣器 ...

  10. STM32 SPI 软件NSS和硬件NSS解读

    [导读] SSM可以控制内部NSS引脚与SSI(一个寄存器,软件模式)相连,还是与NSS外部引脚(真正的STM32引脚,硬件模式)相连.真正作用的是内部NSS引脚(内部NSS引脚才真正连接到SPI通信 ...

最新文章

  1. 1行代码消除PyTorch的CUDA内存溢出报错,这个GitHub项目刚发布就揽星600+
  2. 为ubuntu添加多媒体以及flash等等常用包
  3. KDE和GNOME的区别※切换
  4. Log4J入门教程(二) 参数讲解
  5. 二叉树的前序、中序、后序遍历与创建
  6. linux下vtune使用
  7. mysql undo表空间增长_undo表空间太大解决办法
  8. 一阶低通滤波器方程_一阶RC低通滤波器和RC高通滤波器简介-模拟/电源-与非网...
  9. js面向对象写法及栈的实现
  10. 编写REG注册表文件
  11. lua 遍历删除_lua中table如何安全移除元素
  12. Go-Redis使用手册
  13. hardhat 教程及 hardhat-deploy 插件使用
  14. 微信标题特殊符号大全 ✔
  15. i2c 驱动五:gpio模拟i2c
  16. 处理人际冲突(冲突的本质是什么?发生冲突最要不要采取哪四种行动?建设性处理冲突的技巧是什么?)...
  17. CSDN写文章——不要使用默认标题
  18. 计算机专业大学生应该在大学四年踏实学哪些东西?
  19. sql 数据库创建及建表,
  20. Idea生成英文JavaDoc以及中文编码问题

热门文章

  1. 3d场景渲染插件MultiScatter 1.623
  2. 牛客IOI周赛20-普及组
  3. 【博闻强记】java来发送邮件
  4. No discret job created in Oracle
  5. 微信连wifi 电脑怎么连接到服务器,微信连wifi怎么用 微信连Wi-Fi开通使用教程-电脑教程...
  6. python 机器视觉测量_用Opencv python实现精密测量
  7. 计算机网络知识自问自答,2020计算机网络学习心得体会.doc
  8. 【开源】技术宅硬核跨年,DIY墨水屏日历:自动刷新位置、天气,随机播放2000多条「毒鸡汤」...
  9. Unity 简易读取配置文件内容(txt,懒人用)
  10. SparkStreaming动态读取配置文件