OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6507|回复: 11

三轴加速度传感器实验

[复制链接]

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
发表于 2014-4-6 10:53:51 | 显示全部楼层 |阅读模式
void ADXL345_RD_XYZ(short *x,short *y,short *z)          //这里参数为什么要用指针?函数体里面好像没有体现指针的用法啊
{
u8 buf[6];
u8 i;
IIC_Start();    
IIC_Send_Byte(ADXL_WRITE); //发送写器件指令  
IIC_Wait_Ack();   
    IIC_Send_Byte(0x32);   //发送寄存器地址(数据缓存的起始地址为0X32)
IIC_Wait_Ack();     
 
  IIC_Start();     //重新启动
IIC_Send_Byte(ADXL_READ); //发送读器件指令
IIC_Wait_Ack();
for(i=0;i<6;i++)
{
if(i==5)buf=IIC_Read_Byte(0);//读取一个字节,不继续再读,发送NACK  
else buf=IIC_Read_Byte(1); //读取一个字节,继续读,发送ACK 
  }           
    IIC_Stop(); //产生一个停止条件
*x=(short)(((u16)buf[1]<<8)+buf[0]);    
*y=(short)(((u16)buf[3]<<8)+buf[2]);    
*z=(short)(((u16)buf[5]<<8)+buf[4]);   
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

50

主题

243

帖子

1

精华

高级会员

Rank: 4

积分
616
金钱
616
注册时间
2014-2-26
在线时间
1 小时
发表于 2014-4-6 11:10:42 | 显示全部楼层
void ADXL345_RD_Avval(short *x,short *y,short *z)
{
short tx=0,ty=0,tz=0;    
u8 i;  
for(i=0;i<10;i++)
{
ADXL345_RD_XYZ(x,y,z);
delay_ms(10);
tx+=(short)*x;
ty+=(short)*y;
tz+=(short)*z;    
}
*x=tx/10;
*y=ty/10;
*z=tz/10;
}
从程序中可以看出 不止一个程序要对坐标 x,y,z 进行修改  这样设计一个指针同时指向 变量X,Y,Z的地址处 就可以实现多个函数对变量的修改
而不需要在每个函数入口处设置重复的参数 
由于没有学习三轴加速度传感器这个章节 只是刚才看了看 
自己的理解 求大神拍砖
现在去吃饭 回来再讨论~
我是一只摔不死的蚂蚁!
回复 支持 反对

使用道具 举报

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
 楼主| 发表于 2014-4-6 12:14:06 | 显示全部楼层
回复【2楼】_tank_:
---------------------------------
指针变量作为函数参数有什么好处?
回复 支持 反对

使用道具 举报

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
 楼主| 发表于 2014-4-6 12:23:25 | 显示全部楼层
回复【2楼】_tank_:
---------------------------------
void ADXL345_Read_Average(short *x,short *y,short *z,u8 times)
{
u8 i;
short tx,ty,tz;
*x=0;
*y=0;
*z=0;
if(times)//读取次数不为0
{
for(i=0;i<times;i++)//连续读取times次
{
ADXL345_RD_XYZ(&tx,&ty,&tz);
*x+=tx;
*y+=ty;
*z+=tz;
delay_ms(5);
}
*x/=times;
*y/=times;
*z/=times;
}
}

这个函数,先定义了tx,ty,tz,编译是就会为他们分配相应地址单元,那么ADXL345_RD_XYZ(&tx,&ty,&tz);这个函数就相当于有确定参数了,然后把这个函数调用的得到的数值保存在这几个地址单元。是这样吗?
我开始一直纠结,tx,ty,tz都没赋值怎么能调用ADXL345_RD_XYZ(&tx,&ty,&tz);>
回复 支持 反对

使用道具 举报

50

主题

243

帖子

1

精华

高级会员

Rank: 4

积分
616
金钱
616
注册时间
2014-2-26
在线时间
1 小时
发表于 2014-4-7 00:02:23 | 显示全部楼层
我也是个菜鸟 大家一起讨论一下哈 
我今天想了想这个问题 
先说一下函数调用过程中 形参和实参 的关系 以及函数返回值的问题

比如:
int x=2,y=3;
int Max(int a, int b)//函数实现平方后比较大小 并返回较大的平方值
{
    int z;
    a*=a;
    b*=b;
    z=a>b?a:b;
   return z;
}
然后main函数中调用Max(x,y); 函数会返回9;而x依然是2, y依然是3,不会被改变。
从这个例子中 我们讨论两个问题
1、一个函数只能有一个返回值 那如果我们需要返回多个返回值怎么办 比如三轴加速度传感器的三个坐标x y z 值
2、函数的形参为简单的变量 函数运行过程中 形参只在中间运算过程中占用内存 即将实参x,y的值传送给形参a,b 函数执行完a,b释放内存 而且x,y的值不会改变
    这样又有一个问题 如果我们需要修改x,y的值怎么办

现在想如果函数的形参是指针 结果会是什么情况
比如
int x=2,y=3;
int max (int *a, int *b) 
{
    int z;
    *a*=*a;   //第二个* 是乘号 实现平方的操作
    *b*=*b;
    z=*a>*b?*a:*b;
    return z;
}
这时调用max(&x,&y); 函数会返回9,并且x,y的值分别修改为x=4,y=9; x,y的值会被改变 
函数的具体实现过程是:函数调用时,系统给指针分配内存,并使*a,*b分别指向x,y;运算过程中函数会对x,y的值进行修改,函数运行完,指针*a,*b释放内存;x,y被修改;

从上面两个例子应该可以看出,使用指针作为函数的形参(入口参数) 刚好可以弥补前面提出的两个问题
我想这也是为什么原子哥的例程中会使用指针做入口参数的原因 

这是我的一点看法 你认为呢




我是一只摔不死的蚂蚁!
回复 支持 反对

使用道具 举报

50

主题

243

帖子

1

精华

高级会员

Rank: 4

积分
616
金钱
616
注册时间
2014-2-26
在线时间
1 小时
发表于 2014-4-7 00:51:47 | 显示全部楼层
回复【4楼】Along:
---------------------------------
你说的后半句是对的 但前半句 应该是在执行这条语句的时候才会为其分配内存 但是不是编译器为其分配的内存我就不知道了 查到的资料都说是函数执行时系统为其分配内存 至于系统是怎么为其分配内存的我就不知道了 对于内存分配这部分我也不是太懂 这几天我找一下资料 等我弄明白了 再讨论  你有什么看法也可以讨论一下
我是一只摔不死的蚂蚁!
回复 支持 反对

使用道具 举报

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
 楼主| 发表于 2014-4-7 11:21:27 | 显示全部楼层
回复【5楼】_tank_:
---------------------------------
好像是这样的,5L的我们可以继续讨论
回复 支持 反对

使用道具 举报

50

主题

243

帖子

1

精华

高级会员

Rank: 4

积分
616
金钱
616
注册时间
2014-2-26
在线时间
1 小时
发表于 2014-4-7 13:22:04 | 显示全部楼层
回复【7楼】Along:
---------------------------------
OK! 这两天一定要把它搞懂
我是一只摔不死的蚂蚁!
回复 支持 反对

使用道具 举报

33

主题

209

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
361
金钱
361
注册时间
2014-1-20
在线时间
0 小时
发表于 2014-4-7 15:10:37 | 显示全部楼层
回复【3楼】Along:
---------------------------------
返回多个值
回复 支持 反对

使用道具 举报

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
 楼主| 发表于 2014-4-7 18:44:34 | 显示全部楼层
回复【9楼】Chaplin:
---------------------------------
确切的是返回多个要改变的值吧
回复 支持 反对

使用道具 举报

50

主题

243

帖子

1

精华

高级会员

Rank: 4

积分
616
金钱
616
注册时间
2014-2-26
在线时间
1 小时
发表于 2014-4-11 00:18:29 | 显示全部楼层
关于局部变量的内存分配 
书上是说由系统自动分配 而这里的系统就是编译器 即由编译器自动分配 那么分配到哪里呢? 怎么分配的呢?
昨天去问老师 老师说一般是放在堆栅里 另外说可以去看反汇编 (栅的地址空间应该是由我们开发者确定的 一般在bootloader中定义)

今天我找了一个流水灯的工程 反汇编看了一下 


这是其中的一个延时函数的反汇编 可以看出函数的入口参数被压入栅中 (不明白的是 为什么在出栅的时候 要弹给r3)

另外我还自己写了一个函数 测试结果是



这个也相当于一个延时函数 能看出 并没有把参数入栅 而是利用通用寄存器来运算 这种方式也是我们自己用汇编写程序的时候经常用的方式 利用通用寄存器操作 

这个小实验一点也不严谨 但是对于我们的问题 基本可以回答了 

局部变量是由编译器自动分配 一般(暂且说一般吧)放在栅中

这是我的一些看法  












我是一只摔不死的蚂蚁!
回复 支持 反对

使用道具 举报

32

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
252
金钱
252
注册时间
2013-12-30
在线时间
0 小时
 楼主| 发表于 2014-4-11 14:42:14 | 显示全部楼层
回复【11楼】_tank_:
---------------------------------
谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-12 14:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表