当前位置:   article > 正文

MCU微小系统下的纯整形快速正余弦三角函数实现_算力较低的单片机上实现三角函数的算法,正弦表

算力较低的单片机上实现三角函数的算法,正弦表

当MCU平台资源非常紧张且只有整数运算指令时,可以通过查表近似运算来快速得到正余弦等各种三角操作。为规避浮点操作,可通过0~90度角度放大得到一个整数输入区间,相应结果也适当放大便于工程计算和精度取舍。具体实现如下。

实现框架:

1)整数对齐:
     计算角度0.00~90.00度区间放大100倍取整到0~9000整数,以便于整数处理。
     三角相应结果放大1000倍。
     比如sin(30),实际输入时30对应3000(放大100),结果0.5对应500(放大1000)2)定义并实现一个通用正整数区间查表函数:
     输入变量mvalue: 要计算的数值,比如30度输入3000
     输入变量num: 表数组大小
     输入变量value: 表参数数组,取值范围0~9000对应0~90度
     输入变量data: 表结果数组,取值范围0~10000对应0~1.000
     函数返回:根据value/data数组查找后,找到于md最接近的data对应的value数值,差值部分按照临近节点线性计算得到近似值,数组越多微分区间越小精度越高。
3)定义正弦函数的data/value表数组
     常量数组angle:若干角度(放大100)
     常量数组sin_data:各角度对应结果(放大1000)
4)定义正弦函数:
     输入变量angle: 要计算的数角度值,比如30度输入3000
     函数返回:根据相应常量数组利用以上查表函数返回对应的结果
5)定义余弦函数:
     输入变量angle: 要计算的数角度值,比如30度输入3000
     函数返回:利用cos(a)=sin(90-a)得到
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

代码实现:

uint16_t calc(uint16_t mvalue, uint16_t num, const uint16_t *value, const uint16_t *data) {
   
  uint16_t i;
  uint32_t data_calc;
  if( mvalue <= value[0] )
    data_calc = data[0];
  else if( mvalue>= value[num-1] )
    data_calc = data[num-1];
  else {
   
    for( i = 1; i < num-1; i++ ) {
   
      if( mvalue<= value[i] )
        break;
    }
    if( value[i] == value[i-1] )
      data_calc = value[i];
    else {
   
      data_calc = data[i] - data[i-1];
      data_calc *= mvalue - value[i-1];
      data_calc /= value[i] - value[i-1];
      data_calc += data[i-1];
    }
  }
  return data_calc;
}

const uint16_t sin_data[] = {
   
    0,  87, 174, 259,
  342, 423, 500, 574,
  643, 707, 766, 819,
  866, 906, 940, 966,
  985, 996, 1000
};

const uint16_t angle[] = {
    
     0,  500, 1000, 1500,
  2000, 2500, 3000, 3500,
  4000, 4500, 5000, 5500,
  6000, 6500, 7000, 7500,
  8000, 8500, 9000,
};

uint16_t my_sin( uint16_t angle ) {
   
  return calc(angle, sizeof(angle)/sizeof(angle[0]), angle, sin_data);
}

uint16_t my_cos( uint16_t angle ) {
   
  return my_sin(9000-angle);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

测试结果以及误差(括号里是实际SIN/COS数值,以及当前查表近似方法与实际数值的计算误差):

sin( 0)=0.000 (0.000000,  0.000000)   cos( 0)=1.000 (1.000000,  0.000000)
sin( 1)=0.017 (0.017452, -0.000452)   cos( 1)=0.999 (0.999848, -0.000848)
sin( 2)=0.034 (0.034899, -0.000899)   cos( 2)=0.998 (0.999391, -0.001391)
sin( 3)=0.052 (0.052336, -0.000336)   cos( 3)=0.997 (0.998630, -0.001630)
sin( 4)=0.069 (0.069756, -0.000756)   cos( 4)=0.996 (0.997564, -0.001564)
sin( 5)=0.087 (0.087156, -0.000156)   cos( 5)=0.996 (0.996195, -0.000195)
sin( 6)=0.104 (0.104528, -0.000528
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/400512
推荐阅读
相关标签
  

闽ICP备14008679号