ADXL345加速度传感器实验学习目标1.复习I2C协议的操作2.学习ADXL345加速度传感器的使用28.1ADXL345加速度传感器简介ADXL345是一款完整的3轴加速度测量系统,可选择的测量范围有±2g,±4g,±8g或±16g。既能测量运动或冲击导致的动态加速度,也能测量静止加速度,例如重力加速度,使得器件可作为倾斜传感器使用。它的分辨率为13位,测量范围达±16g。数字输出数据为16位二进制补码格式,可通过SPI(3线或4线)或I2C数字接口访问。这节课我们讲述的是使用I2C操作的方式。。ADXL345传感器的检测轴如下:当ADXL345沿检测轴正向加速时,它对正加速度进行检测。在检测重力时用户需要注意,当检测轴的方向与重力的方向相反时检测到的是正加速度。下图所示为输出对重力的响应:1.ADXL345原理图2.ADXL345写寄存器操作上节课我们已经讲述过I2C的操作方式了,这里就不详细讲了。在这里,我们主要讲述的是使用IO口模拟I2C的操作方式,因为STM32的硬件I2C太复杂,操作起来有时候有出现GUG。写寄存器的操作步骤为:1)发送起始信号2)发送I2C写器件地址3)等待应答4)发送要写入的寄存器地址5)等待应答6)发送要写入的数据7)等待应答8)发送结束信号例程函数的程序实现为:/**************************************************************FunctionName:ADX345_WriteReg*Description:设置ADX345寄存器*Input:addr:寄存器地址**dat:吸入数据*Output:None*Return:None************************************************************/staticint8_tADX345_WriteReg(uint8_taddr,uint8_tdat){IIC_Start();IIC_SendData(ADX345_ADDR);//24C02写地址if(IIC_WaitAck())//如果无应答,表示发送失败{return0xFF;}IIC_SendData(addr);if(IIC_WaitAck())//如果无应答,表示发送失败{return0xFF;}IIC_SendData(dat);if(IIC_WaitAck()){return0xFF;}IIC_Stop();return0;}3.ADXL345的读寄存器操作ADXL345的读寄存器操作步骤如下:1)发送起始信号2)发送I2C写器件地址3)等待应答4)发送I2C要读的寄存器地址5)等待应答6)发送起始信号7)发送I2C读器件地址8)等待应答9)接收返回数据10)发送结束信号例程函数的程序实现为:/**************************************************************FunctionName:ADX345_ReadReg*Description:读取ADX345寄存器*Input:addr:读取地址*Output:None*Return:读取到的8位数据*************************************************************/staticuint8_tADX345_ReadReg(uint8_taddr){uint8_treadValue=0xFF;IIC_Start();IIC_SendData(ADX345_ADDR);//24C02写地址if(IIC_WaitAck()){returnreadValue;}IIC_SendData(addr);if(IIC_WaitAck()){returnreadValue;}IIC_Start();IIC_SendData(ADX345_ADDR+1);//24C02读地址if(IIC_WaitAck()){returnreadValue;}readValue=IIC_ReceiveData(0);IIC_Stop();returnreadValue;}4.ADXL345初始化在使用ADXL345之前,我们要对其寄存器进行一定的设置。首先我们来看一下它的寄存器命令。这里的初始化操作主要是:1)查看器件ID。ADXL345的ID寄存器为0x00,它的ID为:2)设置ADXL345存储数据的方式和通信方式。这里我们设置寄存器地址为:0x31。这里我们主要看一下我们要设置的位的意义,详细的数据大家可以查看数据手册。D6:是设置是否使用SPI。D7:设置数据的存储方式,我们知道,ADXL345的分辨率为13位,那么当它用16位寄存器保存的时候,就会空3位。这里是设置数据存储的时候是选择数据保存左对齐还是右对齐。3)设置数据的输出速率这里我们设置的是BW_RATE寄存器,地址为:0x2C。我们这里设置为正常模式,传输速率100HZ。4)设置测量模式和链接模式设置POWER_CTL寄存器。这里设置使用测量模式,不使用中断模式。而且链接模式也是设置为1。5)设置不启用中断设置INT_ENABLE寄存器,设置它不使用中断模式。6)初始化偏移量。也就是设置OFSX寄存器、OFSY寄存器、OFSZ寄存器。下面我们来看一下初始化的例程函数:/******************************************************************FunctionName:ADX345_Init*Description:初始化ADX345,并核对ADX的ID*Input:None*Output:None*Return:0:成功。0xFF:失败****************************************************************/intADX345_Init(void){IIC_Config();if(ADX345_ReadReg(ADX_DEVID)==0xE5){ADX345_WriteReg(ADX_DATA_FORMAT,0x2B);//13位全分辨率,输出数据右对齐,16g量程ADX345_WriteReg(ADX_BW_RATE,0x0A);//数据输出速度为100HzADX345_WriteReg(ADX_POWER_CTL,0x28);//链接使能,测量模式ADX345_WriteReg(ADX_INT_ENABLE,0x00);//不使用中断ADX345_WriteReg(ADX_OFSX,0x00);//敲击阀值ADX345_WriteReg(ADX_OFSY,0x00);//X轴偏移ADX345_WriteReg(ADX_OFSZ,0x00);//Y轴偏移return0;}return0xFF;//返回初始化失败}5.读取ADXL345的XYL值。ADX345的XYL值,每个值有2个字节,一共6个字节,这6个字节(寄存器0x32至寄存器0x37)都为8位字节,保存各轴的输出数据。寄存器0x32和0x33保存x轴输出数据,寄存器0x34和0x35保存y轴输出数据,寄存器0x36和0x37保存z轴输出数据。输出数据为二进制补码,DATAx0为最低有效字节,DATAx1为最高有效字节,其中x代表X、Y或Z。DATA_FORMAT寄存器(地址0x31)控制数据格式。建议所有寄存器执行多字节读取,以防止相继寄存器读取之间的数据变化。我们例程的读取函数为:/**************************************************************FunctionName:ADX345_ReadXYZ*Description:读取X,Y,Z的AD值*Input:xValue:X轴的保存地址**yValue:Y轴的保存地址**zValue:Z轴的保存地址*Output:None*Return:0:读取成功。0xFF:读取失败************************************************************/staticint8_tADX345_ReadXYZ(int16_t*xValue,int16_t*yValue,int16_t*zValue){uint8_treadValue[6],i;IIC_Start();IIC_SendData(ADX345_ADDR);//24C02写地址if(IIC_WaitAck()){return0xFF;}IIC_SendData(0x32);//发送读地址(X轴首地址)if(IIC_WaitAck()){return0xFF;}IIC_Start();IIC_SendData(ADX345_ADDR+1);//24C02读地址if(IIC_WaitAck()){return0xFF;}/*读取六个字节数据*/for(i=0;i6;i++){if(i==5)//接收最后一个字节时,发送NACK{readValue[i]=IIC_ReceiveData(0);}else//发送接收后应答{readValue[i]=IIC_ReceiveData(1);}}IIC_Stop();/*处理读取到的数据*/*xValue=(uint16_t)(readValue[1]8)+readValue[0];*yValue=(uint16_t)(readValue[3]8)+readValue[2];*zValue=(uint16_t)(readValue[5]8)+readValue[4];return0;}6.ADXL345校正。在数据手册上面有详细讲解,在《ADXL345》数据手册的第29页这里就不详细将了。7.求角度值。求角度值的公式如下:所以例程代码为:/**************************************************************FunctionName:ADX_GetAngle*Description:将AD值转换成角度值*Input:xValue:x的值**yValue:y的值**zValue:z的值**dir:0:与Z轴的角度;1:与X轴的角度;2:与Y轴的角度.*Output:None*Return:None*************************************************************/int16_tADX_GetAngle(floatxValue,floatyValue,floatzValue,uint8_tdir){floattemp;floatres=0;switch(dir){/*与自然Z轴的角度*/case0:temp=sqrt((xValue*xValue+yValue*yValue))/zValue;res=atan(temp);break;/*与自然X轴的角度*/case1:temp=xValue/sqrt((yValue*yValue+zValue*zValue));res=atan(temp);break;/*与自然Y轴的角度*/case2:temp=yValue/sqrt((xValue*xValue+zValue*zValue));res=atan(temp);break;default:break;}res=res*1800/3.14;returnres;}28.2例程主函数intmain(void){uint8_tledState;uint32_ti;/*初始化*/TFT_Init();FLASH_Init();SYSTICK_Config();USART1_Config(9600);LED_Config();while(ADX345_Init()){GUI_Show12Char(60,42,ADX345ERROR!,