搜索
bottom↓
回复: 4

求助, 三轴MQA6100得到XYZ值,获取角度值,,程序运行一段时间死机,

[复制链接]

出0入0汤圆

发表于 2023-8-1 20:49:27 | 显示全部楼层 |阅读模式
这个程序是根据得到的XYZ轴值, 得到角度值. 4秒跑一次.


  1. //读角度
  2. //正取返回True, 失败返回FALSE
  3. u8 QMA6100_Read_Angle(float val[2])
  4. //u8 QMA6100_Read_Angle(void)
  5. {
  6.         int16_t  temp=0;       
  7.         int16_t  x_[3];
  8.         int16_t  tempK[3];
  9.         float accl_in[3];
  10.         //float add_tmp[2];
  11.         float accl_data[3];
  12.     float acc_normal,pitch,roll;
  13.         u8 flg;

  14.        
  15.         //读XYZ的坐标系
  16.         temp=I2C_read(QMA6100P_REG_XOUTL)+((u16)I2C_read(QMA6100P_REG_XOUTH)<<8);
  17.         tempK[0] = temp;       
  18.         x_[0] = temp>>2;
  19.        
  20.         temp=I2C_read(QMA6100P_REG_YOUTL)+((u16)I2C_read(QMA6100P_REG_YOUTH)<<8);
  21.         tempK[1] = temp;       
  22.         x_[1] = temp>>2;
  23.        
  24.         temp=I2C_read(QMA6100P_REG_ZOUTL)+((u16)I2C_read(QMA6100P_REG_ZOUTH)<<8);
  25.         tempK[2] = temp;       
  26.         x_[2] = temp>>2;

  27.         if( test_bit(tempK[0],0) && test_bit(tempK[1],0) && test_bit(tempK[2],0))
  28.         {
  29.                 flg = TRUE ;
  30.         }
  31.         else
  32.         {
  33.                 return FALSE ;
  34.         }
  35.        
  36.         //求度数
  37.         accl_in[0]=  x_[0]*QMA6100P_SENSITITY_8G/1000.0;
  38.         accl_in[1]=  x_[1]*QMA6100P_SENSITITY_8G/1000.0;
  39.         accl_in[2]=  x_[2]*QMA6100P_SENSITITY_8G/1000.0;


  40.         //得到Pich,和POLL坐标
  41.     acc_normal = sqrtf(accl_in[0] * accl_in[0] + accl_in[1] * accl_in[1] + accl_in[2] * accl_in[2]);
  42.           
  43.     accl_data[0] = accl_in[0]/acc_normal;
  44.     accl_data[1] = accl_in[1]/acc_normal;
  45.     accl_data[2] = accl_in[2]/acc_normal;

  46.         pitch = -atan2f(accl_in[0],accl_in[2]);
  47.     val[0] = pitch * RAD_TO_DEG;  //
  48.    
  49.     //grl_decangle[0] = pitch * RAD_TO_DEG;
  50.    
  51.     acc_normal = sqrtf(accl_data[0] * accl_data[0] + accl_data[1] * accl_data[1] + accl_data[2] * accl_data[2]);

  52.     roll = asinf((accl_data[1]/acc_normal));
  53.     val[1] = roll * RAD_TO_DEG;  //
  54.        
  55.     //grl_decangle[1] = roll * RAD_TO_DEG;
  56.         return flg;
  57. }
复制代码



定位到问题.就是 运行了这个函数,,  1天/2天/3天 20%的死机(10台2台会死机重启)   而重启又是直接上电的那种,  非看门狗和LVD..

怀疑是sqrtf asinf 这些函数出了问题.  但是又奇怪是要2天后,或者1天后才出现
求助..
或者大家有这种角度转换函数,,分享一下给我哈..谢谢了..(不过最好定位一下问题)


出0入442汤圆

发表于 2023-8-1 21:52:57 来自手机 | 显示全部楼层
查一下汇编,看看栈溢出的风险大不大。估计用了不少的局部变量,如果在执行atan/asin之类计算时进了系统中断,系统中断再调用一些其它函数,或者函数调用过深,栈可能会爆。默认栈我记得好像是512字节。所以很多单片机程序设计主要以全局变量/全局结构体之类的为主,就是为了避免占用过多栈空间。栈爆了之后万一把ra写成了0,函数返回时回到0地址,现象确实是单片机硬复位了。所以每4秒计算一次出错的概率确实小到可以忽略不计。。需要一大堆巧合才能触发一次。

出0入0汤圆

 楼主| 发表于 2023-8-1 22:32:18 | 显示全部楼层
wye11083 发表于 2023-8-1 21:52
查一下汇编,看看栈溢出的风险大不大。估计用了不少的局部变量,如果在执行atan/asin之类计算时进了系统中 ...
(引用自2楼)

谢谢大神.我再研究研究, 看看汇编

出0入0汤圆

发表于 2023-8-4 11:46:47 | 显示全部楼层
acc_normal做除法的话需要不能等于0.

出0入0汤圆

 楼主| 发表于 2023-8-4 13:32:24 | 显示全部楼层
陆小凤之北京 发表于 2023-8-4 11:46
acc_normal做除法的话需要不能等于0.
(引用自4楼)

好的,有道理..我加一个限制.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 13:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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