《ADXL345角度传感器测二维角度Keil-C程序(共13页).doc》由会员分享,可在线阅读,更多相关《ADXL345角度传感器测二维角度Keil-C程序(共13页).doc(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上程序说明:该程序中有两个C文件,均为同一Keil或TKstudio工程下的C源文件,分别为ADXL345_main和ADXL345_LCD,此程序在Keil uVision2或TKstudio version4.5编译环境下均可正常运行,ADXL345 - 0 Error(s), 0 Warning(s).项目说明:采用全集成的三轴加速度传感器ADXL345进行二维倾角的测量,用1602液晶(LCD省去了测忙函数)显示角度值,其值精确到小数点后两位。ADXL345_main.c文件:/*头文件*/#include #include #include /*宏定义*/#d
2、efine uchar unsigned char#define uint unsigned int/*位定义*/sbit CS = P21; / 片选信号端sbit SCLK = P31; / 时钟sbit SDI = P30; / 数据读/写/*函数声明*/void write_comd(uchar);/void write_data_LCD(uchar);void LCD_init(); / LCD 初始化void display_LCD();/ LCD显示void calculate(); / ASCII码计算/*全局变量*/uint Data_X_22; / 读出的数据储存 X Y
3、Zuint Data_Y_22;uint Data_Z_22;int Data_X,Data_Y,Data_Z; / 数值转换后的值float XX,YY,ZZ;/ 3轴的重力加速度分量uchar ID;/ 机器ID值 用于看读的是否对(调试时用)float roll,pitch;/* 函数名:Delayms()* 功能描述:产生延迟* 形参:ms 延迟的时间,单位ms* 返回值:无* 局部变量:i* 全局变量:无* 函数调用: 无*/void delay_ms(uchar ms)uchar i;while(ms-)for(i = 0; i 250; i+)_nop_();_nop_(); /
4、空执行消耗CPU时间达到等待的效果_nop_();_nop_();/* 函数名:Write_Data(uchar Data_write)* 功能描述:写指令到寄存器 * 形参:Data_write 要写的数据 8位* 返回值:无* 局部变量:i* 全局变量:无* 函数调用: _nop_(); */*写数据函数*/void Write_Data(uchar Adress_Reg,uchar Data_write)uchar i=0;Adress_Reg=(Adress_Reg & 0x7f);/ 置最高位位0 写状态Adress_Reg=(Adress_Reg & 0xbf); / 置第二高位0
5、 单字节读写CS=0;_nop_();SCLK=1;_nop_();for(i=0;i8;i+) / 8位串行输出 寄存器地址值SCLK=0;_nop_();SDI=(bit)(Adress_Reg & 0x80);_nop_();_nop_();_nop_();SCLK=1;_nop_();_nop_();Adress_Reg=1;for(i=0;i8;i+)/ 8位串行输出 指令值SCLK=0;_nop_();SDI=(bit)(Data_write & 0x80);_nop_();_nop_();_nop_();SCLK=1;_nop_();_nop_();Data_write=1;_n
6、op_();_nop_();SCLK=1;_nop_();_nop_();SDI=1;CS=1;/* 函数名: Read_Data_Reg(uchar Adress_Reg) * 功能描述:往寄存器读数据 * 形参:Adress_Reg 寄存器地址* 返回值:Data_Read 读取的数据* 局部变量:i Data_Read 读取的数据 * 全局变量:无* 函数调用: _nop_(); */uchar Read_Data_Reg(uchar Adress_Reg)uchar i=0;uchar Data_Read;Adress_Reg=(Adress_Reg|0x80); / 置最高位为1,
7、读状态Adress_Reg=(Adress_Reg&0xbf); / 置第二高位位0, 单字节读写CS=0;_nop_();_nop_();SCLK=1;_nop_();_nop_();for(i=0;i8;i+) / 8位串行输出 寄存器地址值SCLK=0;_nop_();SDI=(bit)(Adress_Reg & 0x80);_nop_();_nop_();_nop_();SCLK=1;_nop_();_nop_();Adress_Reg=1;for(i=0;i8;i+) / 8位串行读入 数据(8位) SCLK=0;Data_Read=1;_nop_();Data_Read|=(uch
8、ar)SDI;_nop_();_nop_();SCLK=1;_nop_();_nop_();for(i=0;i8;i+) / 产生8个脉冲 (手册要求,目的不知道)SCLK=0;_nop_();_nop_();SCLK=1;_nop_();_nop_();_nop_();_nop_();SCLK=1;_nop_();CS=1;return Data_Read;/* 函数名:Read_Data()* 功能描述:读出6字节X Y Z 轴各两字节的数据 * 形参:无* 返回值:无* 局部变量:无* 全局变量:Data_X_22 Data_Y_22 Data_Z_22 存放读出值 * 函数调用:Rea
9、d_Data_Reg(_);delay_ms(_); */void Read_Data()/*DATAX0是X轴加速度的低字节寄存器,DATAX1是高字节寄存器*/Data_X_20=Read_Data_Reg(0x32); / 读出X轴低位Data_X_21=Read_Data_Reg(0x33); / 读出X轴高位delay_ms(10);Data_Y_20=Read_Data_Reg(0x34); / 读出Y轴低位Data_Y_21=Read_Data_Reg(0x35); / 读出Y轴高位delay_ms(10);Data_Z_20=Read_Data_Reg(0x36); / 读出Z
10、轴低位Data_Z_21=Read_Data_Reg(0x37); / 读出Z轴高位/* 函数名: ADXL345_init()* 功能描述:ADXL345 初始化 对寄存器写指令 * 形参:无* 返回值:无* 局部变量:无* 全局变量:无* 函数调用:Write_Data_Reg(_,_);*/void ADXL345_init()Write_Data(0x31,0x4f); /测量范围为正负16g 13位模式 3线SPI 中断低有效 禁用自测力 左对齐(MSB)模式delay_ms(10);Write_Data(0x2C,0x08); /速率设定为25HZ,带宽12.5HZ delay_m
11、s(10);Write_Data(0x2D,0x08); /选择电源模式delay_ms(10);Write_Data(0x2E,0x80); /使能 DATA_READY 中断delay_ms(10);Write_Data(0x2f,0x00); /中断功能设定,不使用中断delay_ms(10);/*Write_Data(0x1E,0x00); /X 偏移量 根据测试传感器的delay_ms(10); Write_Data(0x1F,0x00); /Y 偏移量 根据测试传感器的delay_ms(10); Write_Data(0x20,0x00); /Z 偏移量 根据测试传感器的delay
12、_ms(10);Write_Data(0x21,0x00); /敲击延时0:禁用; (1.25ms/LSB)delay_ms(10);Write_Data(0x22,0x00); /检测第一次敲击后的延时0:禁用; (1.25ms/LSB) delay_ms(10);Write_Data(0x23,0x00); /敲击窗口0:禁用; (1.25ms/LSB)delay_ms(10);Write_Data(0x24,0x00); /保存检测活动阀值; (62.5mg/LSB)delay_ms(10);Write_Data(0x25,0x00); /保存检测静止阀值; (62.5mg/LSB) d
13、elay_ms(10);Write_Data(0x26,0x2b); /检测活动时间阀值; (1s/LSB)delay_ms(10);Write_Data(0x27,0x00); / 活动 静止检测禁止delay_ms(10);Write_Data(0x28,0x09); /保存检测活动阀值; (62.5mg/LSB)delay_ms(10);Write_Data(0x29,0xff); /保存检测静止阀值; (62.5mg/LSB)delay_ms(10);Write_Data(0x2a,0x80); delay_ms(10);*/* 函数名: transform(void)* 功能描述:数
14、值整合和转换,并转换为加速度 放大1000倍* 形参:无* 返回值:无* 局部变量:无* 全局变量:Data_X=0,Data_Y=0,Data_Z 整合后的X Y Z 轴值* 函数调用:无*/*从数据寄存器中获取加速度数据后,用户必须对数据进行重建*/*数值转换*/void transform(void)(int)Data_X=(Data_X_20)+(Data_X_218);(int)Data_Y=(Data_Y_20)+(Data_Y_218); (int)Data_Z=(Data_Z_20)+(Data_Z_218);if(Data_X&0x2000) / 若位负数 转换为补码Data
15、_X=(Data_X)+1;Data_X=Data_X*3.90625; / 乘比例因素Data_X=-Data_X;elseData_X=Data_X*3.90625;if(Data_Y&0x2000)/ 若位负数 转换为补码Data_Y=(Data_Y)+1;Data_Y=Data_Y*3.90625;/ 乘比例因素Data_Y=-Data_Y;elseData_Y=Data_Y*3.90625;if(Data_Z&0x2000) / 若位负数 转换为补码Data_Z=(Data_Z)+1;Data_Z=Data_Z*3.90625; / 乘比例因素Data_Z=-Data_Z;elseD
16、ata_Z=Data_Z*3.90625;/*if(Data_X0) Data_X=-Data_X;Data_X=(float)Data_X*3.9;/Data_X单位为1000倍的g,即mgelseData_X=(float)Data_X*3.9;if(Data_Y0)Data_Y=-Data_Y;Data_Y=(float)Data_Y*3.9;elseData_Y=(float)Data_Y*3.9;if(Data_Z0) Data_Z=-Data_Z;Data_Z=(float)Data_Z*3.9;elseData_Z=(float)Data_Z*3.9;*/*扩大1000倍后结果*
17、/*检测轴始终检测到的是正加速度*/XX=Data_X; / X轴重力加速度分量YY=Data_Y; / Y轴重力加速度分量ZZ=Data_Z; / Z轴重力加速度分量/* 函数名:calculate_angle(float V_x,float V_y,float V_z)* 功能描述:计算横滚角和俯仰角 * 形参:G_x G_x G_zX Y Z轴的加速度值* 返回值:无* 局部变量:无 * 全局变量:roll pitch 横滚角和俯仰角* 函数调用:atan2(_,_); */ /*计算角度函数*/void calculate_angle(float G_x,float G_y,float
18、 G_z)roll=-(float)(atan2(G_z,G_x)*180)/3.)-90);/弧度转成角度 pitch=-(float)(atan2(G_z,G_y)*180)/3.)-90);roll=roll*100;pitch=pitch*100;/*主函数*/void main(void)delay_ms(5); /上电延时ADXL345_init(); / ADXL345的初始化LCD_init(); / LCD的初始化ID=Read_Data_Reg(0x00);/ 读出机器ID值,DEVID寄存器保存0xE5的固定器件ID代码while(1) Read_Data();/读出X
19、Y Z 轴加速度值 transform(); /数据重建过程calculate_angle(XX,YY,ZZ);/计算x和y轴相对于水平面的倾角calculate(); / ASCII码计算display_LCD();/ 显示ADXL345_LCD.c文件:#include /51寄存器文件#include /*宏定义*/#define uchar unsigned char#define uint unsigned int/*位定义及变量声明*/sbit LCDEN=P34;sbit RS=P35;sbit DULA=P26;sbit WEILA=P27;extern uchar ID;ex
20、tern float roll,pitch;uchar dis116 = X+00.00 Y+00.00;uchar dis216 = ID:000;/*计算函数*/void calculate()/uchar flag_X,flag_Y;if(roll0)roll=-roll;dis11=-;/flag_X=45;elsedis11=+;if(pitch0;j-)for(i=100;i0;i-);/*液晶显示相关函数*/void write_comd(uchar com)RS=0;/数据/命令选择端P0=com;delay(1);/数据建立时间LCDEN=1;delay(5);LCDEN=0
21、;void write_data_LCD(uchar datas)RS=1;/数据/命令选择端P0=datas;delay(1);/数据建立时间LCDEN=1;delay(5);LCDEN=0;void LCD_init()DULA=0;WEILA=0;LCDEN=0;write_comd(0x38);/显示模式设置write_comd(0x0c);/开显示,不显示光标write_comd(0x06);/写一个字符后,地址指针加1且光标加1;整屏显示不移动write_comd(0x01);/显示清屏void display_LCD()uint i,j;write_comd(0x80);/初始化数据指针,写在第一行for(i=0;i16;i+)write_data_LCD(dis1i);delay(1);write_comd(0x80+0x40);/将数据指针移动到第二行第4字符处开始显示for(j=0;j6;j+)write_data_LCD(dis2j);delay(1);专心-专注-专业