#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; } }
|
|