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)得到

代码实现:

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);
}

测试结果以及误差(括号里是实际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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值