|
adxl345传感器计步器程序
- #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;
- }
-
- }
复制代码
|
评分
-
查看全部评分
|