stm32---ADXL345

2020-03-26来源: eefocus关键字:stm32  ADXL345  传感器

ADXL345是一款三轴加速度传感器,广泛用于手机、游戏手柄等设计。


ADXL 支持标准的 I2C 或 SPI 数字接口,自带 32 级 FIFO 存储,并且内 部有多种运动状态检测和灵活的中断方式等特性,常用I2C接口

13367077-399ad5f7008bf43d.PNG

检测轴

初始化步骤

1)上电

2)等待 1.1ms

3)初始化命令序列

4)结束


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

13367077-d646e76312aae81f.PNG

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);       //数据输出速度为100Hz

        ADXL345_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);       //数据输出速度为100Hz

    ADXL345_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

        {

            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轴的角度

[1] [2]
关键字:stm32  ADXL345  传感器 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic492634.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机引脚模式配置
下一篇:stm32---SPI与内部flash

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm8l低功耗系列
最近干刚做了一个stm8的项目用的是L低功耗系列,其中遇到一个问题。外设寄存器的值怎么都写入不进去。用IAR仿真产看寄存器的值,不论写进去多少,都是初始值。后来把所有寄存器都写了一遍,发现有的能写进去,有的写不进去。比如GPIO的寄存器就能写进去。百思不得姐,偶然查看clock的库函数发现个函数是设置外设时钟的。这个系列,亦或者整个低功耗系列的每个外设是不是都需要在时钟寄存器中单独设置时钟。(以前所使用的芯片都是在外设寄存器中使能或者是禁使能)
发表于 2020-03-09
STM8L+BC26双低功耗,微安
现在在做一个项目需要用到STM8L和BC26。长时间断链后连接下服务器,并且发送一下当前状态,需要用到STM8L和BC26的低功耗。STM8L低功耗,这里用HALT模式,RTC规定时间唤醒。第一步需要关闭所有外设,把所有管脚为设置为输出,并且输出低,管脚根据具体环境设置,需要输出高电平的则输出高电平。在关闭外设的是后是需要先_DeInit,然后在关闭外设始终,有点需要特别主要,要把在进入halt模式的时候需要把所有的中断的标志位清空,否则使用RTC唤醒则会不起作用。第二步就设置低功耗的一些配置。第三步配置完成后进入低功耗。项目中需要用到外部高速始终和BC26通信,所以在进入和退出halt模式的时候需要重新初始化active模式下的
发表于 2020-03-09
stm8l151低功耗程序架构,调试心得
最近帮医院做了一款体温记录仪,整个硬件方案资源是:stm8L151 + NTC*2 + EEPROM + 锂电池充电保护电路 + 18mAh纽扣电池;软件逻辑是,每隔一分钟,采样两路温度并保存在EEP里;通过USB转TTL,上位机能够读取,展示温度曲线,最大最小平均值等简单的运算;整个方案很简单,但也走了不少弯路......单片机程序框架之伪代码:void main(void){    CLK_Config();    GPIO_Config();    ADC_Config();    USART_Config();   
发表于 2020-03-09
STM8s外部时钟晶振失效时钟安全系统CSS启动演示
使用的最小系统晶振是8m的。这里说下配置过程:时钟自动切换,开启切换中断在中断里面清除中断标志,使能CSS并开启CSS中断CSS中断发生,清除CSS中断标志,将HSI二分频,即16M/2=8M,与外部晶振相同,这样不会影响串口波特率窗口输出配置信息:用手触碰PA1、PA2引脚使外部晶振失效串口输出CSS中断
发表于 2020-03-09
STM8s外部时钟晶振失效时钟安全系统CSS启动演示
STM8S103之时钟设置
最大时钟(指的是system clock):外部晶振24MHz,内部高速RC16MHz三个时钟源:外部晶振、内部高速RC(上电默认) +内部低速RC几个时钟:master clock(即sytem clock),fcpu,外设时钟、AWU时钟调用库函数中CLK_ClockSwitchConfig,参考库函数clk_clockselection,但是分频还得进一步设置上电默认:内部高速RC,HSIDIV=/8,CPUDIV=/1,外部时钟全使能,查看相关寄存器的Reset value
发表于 2020-03-09
STM8S103之时钟设置
stm8 16M晶振下精确软件延时
void inerDelay_us(unsigned char n) {for(;n>0;n--) { asm("nop"); //在STM8里面,16M晶振,_nop_() 延时了 333nsasm("nop"); asm("nop"); asm("nop"); }}//---- 毫秒级延时程序----------------------- void Delayms(unsigned int time) { unsigned int i; 
发表于 2020-03-08
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved