分享

adxl345传感器计步器 单片机程序

 曲静幽然 2017-11-07
#include<reg52.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int

#include  <INTRINS.H>

#define        SlaveAddress   0xA6          //1010 0110    定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;                              //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A 0011 1010
sbit sclk=P1^2;
sbit sda=P1^3;
sbit stop=P3^2;

uchar BUF[8];                              //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A 0011 1010

float  dis_datax,dis_datay,dis_dataz,acc,acc1=1000;

uchar wan,qian,bai,shi ,ge,flag,miao,miao1,n,g,s,b;
uint count,count_hou,cishu,v,a;


void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void write_com(uchar com)
{
        rs=0;
        P0=com;
        delay(5);
        en=1;
        delay(5);
        en=0;
}
void write_dat(uchar dat)
{
        rs=1;
        P0=dat;
        delay(1);
        en=1;
        delay(5);
        en=0;
}
void init()
{
        rw=0;
        en=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
//        write_com(0x80+0x10);
}

void conversion(uint temp_data)  
{  
    wan=temp_data/10000+0x30 ;
    temp_data=temp_data%10000;   //取余运算
        qian=temp_data/1000+0x30 ;
    temp_data=temp_data%1000;    //取余运算
        bai=temp_data/100+0x30   ;
    temp_data=temp_data%100;     //取余运算                                 -e----------------eee-e
        shi=temp_data/10+0x30    ;
    temp_data=temp_data%10;      //取余运算
        ge=temp_data+0x30;         
}
void delay6us()                 //6us延时函数
 { 

        _nop_();        _nop_();          



 }

void delay_ms(uint n)       //N ms延时函数
{
        uint x,y;
        for(x=n;x>0;x--)
                for(y=110;y>0;y--);        
}

                                                                                                                                                                /////

void ADXL345_Start()
{
    sda = 1;                    //拉高数据线
    sclk = 1;                    //拉高时钟线
    delay6us();                 //延时
    sda = 0;                    //产生下降沿
    delay6us();                 //延时
    sclk = 0;                    //拉低时钟线
}

void ADXL345_Stop()
{
    sda = 0;                    //拉低数据线
    sclk = 1;                    //拉高时钟线
    delay6us();                 //延时
    sda = 1;                    //产生上升沿
    delay6us();                 //延时
}

void ADXL345_SendACK(bit ack)
{
    sda = ack;                  //写应答信号
    sclk = 1;                    //拉高时钟线
    delay6us();                 //延时
    sclk = 0;                    //拉低时钟线
    delay6us();                 //延时
}


bit ADXL345_RecvACK()
{
    sclk = 1;                    //拉高时钟线
    delay6us();                 //延时
    CY = sda;                   //读应答信号
    sclk = 0;                    //拉低时钟线
    delay6us();                 //延时

    return CY;
}


void ADXL345_SendByte(uchar dat)
{
    uchar i;
//        sclk = 0;                //拉低时钟线

    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        sda = CY;               //送数据口
        sclk = 1;                //拉高时钟线
        delay6us();             //延时
        sclk = 0;                //拉低时钟线
        delay6us();             //延时
    }
    ADXL345_RecvACK();
}


uchar ADXL345_RecvByte()
{
    uchar i;
    uchar dat = 0;

    sda = 1; 
        //        write_com(0x80);
                   //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        sclk = 1;                //拉高时钟线
        delay6us();             //延时
        dat |= sda;             //读数据               
        sclk = 0;                //拉低时钟线
        delay6us();             //延时

    }


    return dat;
}

void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
{
    ADXL345_Start();                  //起始信号
    ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
    ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页 
    ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页 
    ADXL345_Stop();                   //发送停止信号
}

uchar Single_Read_ADXL345(uchar REG_Address)
{
        uchar REG_data;
    ADXL345_Start();            //起始信号
    ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
    ADXL345_SendByte(REG_Address);                   //发送存储单元地址,从0开始        
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
    REG_data=ADXL345_RecvByte();              //读出寄存器数据
        ADXL345_SendACK(1);   
        ADXL345_Stop();                           //停止信号
    return REG_data; 
}

void Multiple_read_ADXL345()
{   
        uchar i;
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号           1010 0110
    ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始 0011 0010
    ADXL345_Start();                          //起始信号
    ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号           1010 0111
        for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
    {
        BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
        if(i == 5)        ADXL345_SendACK(1);       //最后一个数据需要回NOACK
        else        ADXL345_SendACK(0);           //回应ACK
    }
    ADXL345_Stop();                          //停止信号
    delay_ms(10);
}

void Init_ADXL345()           //初始化ADXL345,根据需要请参考pdf进行修改***********************
{
//        delay(500);                                          //上电延时
   Single_Write_ADXL345(0x31,0x2B);   //测量范围,正负16g,13位模式
   Single_Write_ADXL345(0x2C,0x06);   //0000 0110速率设定为6.25 参考pdf13页
   Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
   Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
   Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
   Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
   Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
}


float operation(uchar starti)
{
        float  dis_data        ;
        int temp;
        temp=(BUF[starti+1]<<8)+BUF[starti];  //合成数据 
//        write_com(0x80);  
        if(temp<0)
        {
                temp=-temp;
                flag=1;

        }
        else flag=0; //显示空格

    dis_data=(float)temp*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  return dis_data;
}
void display_x()         //显示x轴
{   
   conversion(dis_datax);          //转换出显示需要的数据
        write_com(0x80);
        if(flag==0)        write_dat(' ');
        else write_dat('-');
        write_dat('X');
        write_dat(':');
        write_dat(qian);

        write_dat('.'); 
        write_dat(bai); 
         write_dat(shi); 
        write_dat('g');        
                                  write_dat(' ');
                                                                                                                write_dat('v');
                                                                                                                write_dat(':');
                                                                                                                write_dat(v/100+0x30);
                                  write_dat((v%100)/10+0x30);
                                  write_dat(v%10+0x30);
}

void display_y()        //显示y轴
{    
  // dis_datay=operation(2);
    conversion(dis_datay);          //转换出显示需要的数据
        write_com(0x80+8);
        if(flag==0)         write_dat(' ');
        else write_dat('-');
        write_dat('Y');
        write_dat(':');
        write_dat(qian);

        write_dat('.'); 
        write_dat(bai); 
         write_dat(shi); 
        write_dat('g');

                                  write_dat(' ');
                                                                                                                write_dat('v');
                                                                                                                write_dat(':');
                                                                                                                write_dat(v/100+0x30);
                                  write_dat((v%100)/10+0x30);
                                  write_dat(v%10+0x30);
}

void display_z()           //显示z轴
{  

 //  dis_dataz=operation(4);
    conversion(dis_dataz);           //转换出显示需要的数据
        write_com(0x80+0x40);
        if(flag==0)                  write_dat(' ');
        else write_dat('-');
        write_dat('Z');
        write_dat(':');
        write_dat(qian);

        write_dat('.'); 
        write_dat(bai); 
         write_dat(shi); 
        write_dat('g');
        ///gai  guo
                                  write_dat(' ');
                                                                                                                write_dat('v');
                                                                                                                write_dat(':');
                                                                                                                write_dat(v/100+0x30);
                                  write_dat((v%100)/10+0x30);
                                  write_dat(v%10+0x30);
}

void countstep()
{
        dis_datax=operation(0);
        dis_datay=operation(2);
   dis_dataz=operation(4);

        acc1=acc;
        acc=sqrt(dis_dataz*dis_dataz+dis_datax*dis_datax+dis_datay*dis_datay)  ;
        if(acc1<990&&acc>1010)
//        if(fabs(acc-acc1)>140&&miao1!=miao)

        {//if(stop=0)
        //        miao1=miao;
                count++;
        }
        write_com(0x80);
        conversion(acc);
        write_dat('A');
        write_dat(':');
        write_dat(qian);

        write_dat('.'); 
        write_dat(bai); 
         write_dat(shi); 
        write_dat('g');
                          write_dat(' ');
        write_dat('v');
        write_dat(':');
        write_dat(v/100+0x30);
        write_dat((v%100)/10+0x30);
    write_dat(v%10+0x30);
        write_com(0x80+0x40);
        write_dat('C');
        write_dat('o');
        write_dat('u');
        write_dat('n');
        write_dat('t');
        write_dat(':');
        write_dat(count_hou/100+0x30);
        write_dat((count_hou%100)/10+0x30);
        write_dat(count_hou%10+0x30);


}
void ADXL345_Measure()                         //测量角度值并显示
{
        Multiple_read_ADXL345();     //连续读出数据,存储在BUF中
        countstep();

}



void main()
{
        unsigned int j,k=1;
        stop=1;
        init();

        TMOD=0X01;                        //设置定时器0为模式一,即16位计算模式
  TH0 =(65536-50000)/256;
  TL0 =(65536-50000)%256;
        EA=1;                //开启总中断
        ET0=1;                //开启定时器0中断
        TR0=1;                //启动定时器0
        write_com(0x80);
        write_dat('O');
        write_dat('N');
        delay(1500);
        Init_ADXL345();
        while(1)
        {
                                                if(stop==0)                //检测按键K1是否按下
                                                {
                                                                delay(10);//消除抖动
                                                                if(stop==0)
                                                                {
                                                                                                                while(k==1)
                                                                                                        {
                                                                                                                        j=count;
                                                                                                                        count_hou=j;
                                                                                                                        write_com(0x80);
                                                                                                                        conversion(acc);
                                                                                                                        write_dat('s');
                              write_dat('t'); 
                                                                                                                        write_dat('o'); 
                                                                                                                        write_dat('p');
                                                                                                                        write_dat('!');
                                                                                                                 write_dat(' ');
                                                                                                                write_dat(' ');
                                                                                                                write_dat(' ');
                                                                                                                write_dat('v');
                                                                                                                write_dat(':');
                                                                                                                write_dat(v/100+0x30);
                                  write_dat((v%100)/10+0x30);
                                  write_dat(v%10+0x30);
                                                                                                                EA=0;
                                                                                                                        delay(1000);
                                                                                                                        delay(100);
                                                                                                                                if(stop==0)
                                                                                                                                {
                                                                                                                                        Init_ADXL345();
                                                                                                                                 count=0;
                                                                                                                                        k=0;
                                                                                                                                        EA=1;
                                                                                                                                }                                                                                                                
                                                                                                        }                                                                
                                                                }
                                                }                
        count_hou=count;        
        ADXL345_Measure();

  }        
}


void timeinit()
{
        TMOD=0X01;                        //设置定时器0为模式一,即16位计算模式
  TH0 =(65536-50000)/256;
  TL0 =(65536-50000)%256;
        EA=1;                //开启总中断
        ET0=1;                //开启定时器0中断
        TR0=1;                //启动定时器0
}

void time0(void) interrupt 1
{
  TH0 =(65536-50000)/256;
  TL0 =(65536-50000)%256;
        cishu++;
        if(cishu>=100)
        {
          cishu=0;
                v=(count-a)*12;
                a=count;
        }
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多