|
发表于 2011-11-5 00:14:35
|
显示全部楼层
下面是我的想法,请大家指教:
可以用一定频率扫描加速度值,然后积分出速度和运动距离。假设get_MMA7660_data()这个函数可以取得X\Y的加速度值Xa和Ya。在get_MMA7660_data()中要加入滤波程序,确保读取值尽量精确。
int XA;//初始化时的X加速度,即静止时的加速度,理想状态应该是0
int YA;//初始化时的Y加速度,即静止时的加速度,理想状态应该是0
int Xa;//get_MMA7660_data()实时测得的X加速度
int Ya;//get_MMA7660_data()实时测得的Y加速度
int VX=0;//当前的X方向速度
int VY=0;//当前的Y方向速度
int X=0;//当前所在的X坐标轴位置
int Y=0;//当前所在的Y坐标轴位置
unsigned char FLAG_X=0;//X方向移动标志
unsigned char FLAG_Y=0;//Y方向移动标志
int X_lasttime=0;//;//运动前的X坐标
int Y_lasttime=0;//运动前的Y坐标
int Xposition=0;//此次X方向移动的距离
int Yposition=0;//此次Y方向移动的距离
get_MMA7660_data();//此次是在未移动的情况下初始化系统
XA=Xa;
YA=Ya;
//使用定时器每隔固定时间(周期越小越精确)运行以下程序:
{
get_MMA7660_data();
VX=VX+Xa-XA;//计算X轴运动速度
X=X+VX;//计算X轴当前位置
VY=VY+Ya-YA;//计算Y轴运动速度
Y=Y+VY;//计算Y轴当前位置
}
主循环:
while(1)
{
//计算X轴方向移动
if(VX==0&&FLAG_X==1)//在X方向运动的状态下计算出速度降为0,视为一次运动停止
{
Xposition=X-X_lasttime;//Xposition在此次运动中行动的距离,数值为正即为正方向移动,为负即为负方向移动
FLAG_X=0;//表示X轴方向停止移动
X_lasttime=X;//将停止后的坐标做为下一次运动前的坐标
}
if(VX!=0&&FLAG_X==0)
{
FLAG_X=1;//表示X轴方向开始移动
}
//计算Y轴方向移动
if(VY==0&&FLAG_Y==1)//在Y方向运动的状态下计算出速度降为0,视为一次运动停止
{
Yposition=Y-Y_lasttime;//Yposition在此次运动中行动的距离,数值为正即为正方向移动,为负即为负方向移动
FLAG_Y=0;//表示Y轴方向停止移动
Y_lasttime=Y;//将停止后的坐标做为下一次运动前的坐标
}
if(VY!=0&&FLAG_Y==0)
{
FLAG_Y=1;//表示Y轴方向开始移动
}
}
//建议根据实际工况设置一定时器,当速度低于某个值一段时间后,视为运动已停止。这是为了避免积分误差导致速度无法归0。楼主要求只要取得方向,对运动距离精度没要求,我觉得上面的计算应该可以实现。初学单片机,写的程序乱,请大家见谅
编辑原因:整理和修正代码 |
|