找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1518|回复: 0
收起左侧

ADXL345是怎么来计算步数和判断运动状态的?

[复制链接]
ID:890746 发表于 2021-6-7 21:38 | 显示全部楼层 |阅读模式
ADXL345模块做计步器,找到了一段程序但是看不太懂,有大佬教教我,ADXL345是怎么来计算步数和判断运动状态的啊......
#include<reg52.h>
#include<stdio.h>
#include "delay.h"
#include "math.h"
#include "adxl345.h"
#include "1602.h"

sbit led=P1^4;         //引脚定义

unsigned char ReadAdxl345;                 //定时读取adxl345
char dis0[16];                   //串口数据显示
xdata char dis1[16];                   //串口数据显示
xdata char dis2[16];                   //串口数据显示
unsigned long time_20ms=0;           //定时器计数
unsigned char ReportFlag=0;           //数据上报标志

unsigned int BuShu=0;         //累计步数
float JuLi=0;                        //累计距离
float KaLuLi=0;                        //累计卡路里
unsigned char statFlag = 0;//状态
void Init_Timer0(void);                   //函数声明
void SendStr(unsigned char *s,unsigned char length);
void UART_Init(void);
void SendByte(unsigned char dat);
void BuShuCheck(void);

void main (void)
{     
        Init_Timer0();        //定时器0初始化
        UART_Init();

        LCD_Init();           //初始化液晶
        DelayMs(20);          //延时有助于稳定
        LCD_Clear();

        Init_ADXL345();          //清屏
        if(Single_Read_ADXL345(0X00)==0xe5)        //读出的数据为0XE5,表示正确
        {
                DelayMs(5);
        }
        else
        {
                DelayMs(3);
        }
        led=1;
        while (1)         //主循环
        {
            if(ReadAdxl345==1)   //定时读取adxl345数据
            {
                        BuShuCheck();                        //检测步数

                        sprintf(dis1,"B:%04d J:%4.1fm ",BuShu/2,JuLi);        //打印
                        LCD_Write_String(0,0,dis1);//显示
                        sprintf(dis2,"%7.2fcal ",KaLuLi);                   //打印
                        LCD_Write_String(0,1,dis2);//显示                        

                        if(statFlag == 0)//站着状态
                        {LCD_Write_String(11,1,"Stand");}
                        else if(statFlag == 1)////躺着状态
                        {LCD_Write_String(11,1,"Lie  ");}
                        else if(statFlag == 2)//跑着状态
                        {LCD_Write_String(11,1,"Run  ");}
                        else if(statFlag == 3)//走着状态
                        {LCD_Write_String(11,1,"Walk ");}
                }

                if(ReportFlag==1)        //2s
                {
                        ReportFlag=0;
                        sprintf(dis0,"*B:%04d",BuShu/2);        //上报步数
                        SendStr(dis0,7);
                        sprintf(dis0,"J:%04.1fm",JuLi);                        //上报距离
                        SendStr(dis0,7);
                        sprintf(dis0,"K:%07.2fcal",KaLuLi);                   //上报卡路里
                        SendStr(dis0,12);

                        if(statFlag == 0)//站着状态
                        {SendStr("Stand#",6);}
                        else if(statFlag == 1)////躺着状态
                        {SendStr("Lie  #",6);}
                        else if(statFlag == 2)//跑着状态
                        {SendStr("Run  #",6);}
                        else if(statFlag == 3)//走着状态
                        {SendStr("Walk #",6);}
                        SendStr("\r\n",2);
                }
        }
}

void BuShuCheck(void)
{
        static unsigned char ErrorNum=0;           //变量定义
        static unsigned char NormalNum=0;

        static unsigned char CheckNum=0;           //变量定义
        static unsigned char shuNum=0;
        static unsigned char ceNum=0;
        static unsigned int remBuShu=0;
        ReadAdxl345=0;
        ReadData_x();
        CheckNum++;//检测次数
        if((temp_X<650)||(abs(temp_Y)>400))       //查看正常次数
        {
                led=0;                        //呼吸灯
                ErrorNum++;        //记录次数
                shuNum++;//竖直状态++
        }
        else
        {NormalNum++; ceNum++;led=1;} //呼吸灯//侧着状态++        

        if((NormalNum!=0)&&(ErrorNum!=0))        //                        从角度判断走了一步
        {
                ErrorNum=0;
                NormalNum=0;
                BuShu++;
                JuLi=(float)(BuShu/2)*0.45;          //计算距离
                KaLuLi=JuLi*70*0.832;                 //卡路里计算 走路 距离*体重*系数
        }

        if(CheckNum>=20)
        {

                if((ceNum!=0)&&(shuNum==0))
                {
                        statFlag = 0;//站着状态
                }
                else if((ceNum==0)&&(shuNum!=0))
                {
                        statFlag = 1;//躺着状态
                }
                else if((ceNum!=0)&&(shuNum!=0))
                {
                        if((BuShu - remBuShu)>=6)//跑着 一个周期大于3步
                        {statFlag = 2;}//跑着状态
                        else
                        {statFlag = 3;}//走着状态
                        remBuShu = BuShu;//记录上次步数                        
                }
                CheckNum=0;
                ceNum=0;                //清空计数
                shuNum=0;                        
        }
}
void Init_Timer0(void)
{
        TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
        TH0=(65536-20000)/256;                  //重新赋值 20ms
        TL0=(65536-20000)%256;
        EA=1;            //总中断打开
        ET0=1;           //定时器中断打开
        TR0=1;           //定时器开关打开
}

void Timer0_isr(void) interrupt 1
{
        TH0=(65536-20000)/256;                  //重新赋值 20ms
        TL0=(65536-20000)%256;

        time_20ms++;
        if(time_20ms%5==0)
        {
                ReadAdxl345=1;
        }
        if(time_20ms%50==0)
        {
                ReportFlag=1;
        }
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表