IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> MCU微小系统下的纯整形快速正余弦三角函数实现 -> 正文阅读

[嵌入式]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)   cos( 6)=0.993 (0.994522, -0.001522)
sin( 7)=0.121 (0.121869, -0.000869)   cos( 7)=0.991 (0.992546, -0.001546)
sin( 8)=0.139 (0.139173, -0.000173)   cos( 8)=0.989 (0.990268, -0.001268)
sin( 9)=0.156 (0.156434, -0.000434)   cos( 9)=0.987 (0.987688, -0.000688)
sin(10)=0.174 (0.173648,  0.000352)   cos(10)=0.985 (0.984808,  0.000192)
sin(11)=0.191 (0.190809,  0.000191)   cos(11)=0.981 (0.981627, -0.000627)
sin(12)=0.208 (0.207912,  0.000088)   cos(12)=0.977 (0.978148, -0.001148)
sin(13)=0.225 (0.224951,  0.000049)   cos(13)=0.973 (0.974370, -0.001370)
sin(14)=0.242 (0.241922,  0.000078)   cos(14)=0.969 (0.970296, -0.001296)
sin(15)=0.259 (0.258819,  0.000181)   cos(15)=0.966 (0.965926,  0.000074)
sin(16)=0.275 (0.275637, -0.000637)   cos(16)=0.960 (0.961262, -0.001262)
sin(17)=0.292 (0.292372, -0.000372)   cos(17)=0.955 (0.956305, -0.001305)
sin(18)=0.308 (0.309017, -0.001017)   cos(18)=0.950 (0.951057, -0.001057)
sin(19)=0.325 (0.325568, -0.000568)   cos(19)=0.945 (0.945519, -0.000519)
sin(20)=0.342 (0.342020, -0.000020)   cos(20)=0.940 (0.939693,  0.000307)
sin(21)=0.358 (0.358368, -0.000368)   cos(21)=0.933 (0.933580, -0.000580)
sin(22)=0.374 (0.374607, -0.000607)   cos(22)=0.926 (0.927184, -0.001184)
sin(23)=0.390 (0.390731, -0.000731)   cos(23)=0.919 (0.920505, -0.001505)
sin(24)=0.406 (0.406737, -0.000737)   cos(24)=0.912 (0.913545, -0.001545)
sin(25)=0.423 (0.422618,  0.000382)   cos(25)=0.906 (0.906308, -0.000308)
sin(26)=0.438 (0.438371, -0.000371)   cos(26)=0.898 (0.898794, -0.000794)
sin(27)=0.453 (0.453990, -0.000990)   cos(27)=0.890 (0.891007, -0.001007)
sin(28)=0.469 (0.469472, -0.000472)   cos(28)=0.882 (0.882948, -0.000948)
sin(29)=0.484 (0.484810, -0.000810)   cos(29)=0.874 (0.874620, -0.000620)
sin(30)=0.500 (0.500000,  0.000000)   cos(30)=0.866 (0.866025, -0.000025)
sin(31)=0.514 (0.515038, -0.001038)   cos(31)=0.856 (0.857167, -0.001167)
sin(32)=0.529 (0.529919, -0.000919)   cos(32)=0.847 (0.848048, -0.001048)
sin(33)=0.544 (0.544639, -0.000639)   cos(33)=0.837 (0.838671, -0.001671)
sin(34)=0.559 (0.559193, -0.000193)   cos(34)=0.828 (0.829038, -0.001038)
sin(35)=0.574 (0.573576,  0.000424)   cos(35)=0.819 (0.819152, -0.000152)
sin(36)=0.587 (0.587785, -0.000785)   cos(36)=0.808 (0.809017, -0.001017)
sin(37)=0.601 (0.601815, -0.000815)   cos(37)=0.797 (0.798636, -0.001636)
sin(38)=0.615 (0.615661, -0.000661)   cos(38)=0.787 (0.788011, -0.001011)
sin(39)=0.629 (0.629320, -0.000320)   cos(39)=0.776 (0.777146, -0.001146)
sin(40)=0.643 (0.642788,  0.000212)   cos(40)=0.766 (0.766044, -0.000044)
sin(41)=0.655 (0.656059, -0.001059)   cos(41)=0.754 (0.754710, -0.000710)
sin(42)=0.668 (0.669131, -0.001131)   cos(42)=0.742 (0.743145, -0.001145)
sin(43)=0.681 (0.681998, -0.000998)   cos(43)=0.730 (0.731354, -0.001354)
sin(44)=0.694 (0.694658, -0.000658)   cos(44)=0.718 (0.719340, -0.001340)
sin(45)=0.707 (0.707107, -0.000107)   cos(45)=0.707 (0.707107, -0.000107)
sin(46)=0.718 (0.719340, -0.001340)   cos(46)=0.694 (0.694658, -0.000658)
sin(47)=0.730 (0.731354, -0.001354)   cos(47)=0.681 (0.681998, -0.000998)
sin(48)=0.742 (0.743145, -0.001145)   cos(48)=0.668 (0.669131, -0.001131)
sin(49)=0.754 (0.754710, -0.000710)   cos(49)=0.655 (0.656059, -0.001059)
sin(50)=0.766 (0.766044, -0.000044)   cos(50)=0.643 (0.642788,  0.000212)
sin(51)=0.776 (0.777146, -0.001146)   cos(51)=0.629 (0.629320, -0.000320)
sin(52)=0.787 (0.788011, -0.001011)   cos(52)=0.615 (0.615662, -0.000661)
sin(53)=0.797 (0.798635, -0.001635)   cos(53)=0.601 (0.601815, -0.000815)
sin(54)=0.808 (0.809017, -0.001017)   cos(54)=0.587 (0.587785, -0.000785)
sin(55)=0.819 (0.819152, -0.000152)   cos(55)=0.574 (0.573576,  0.000424)
sin(56)=0.828 (0.829038, -0.001038)   cos(56)=0.559 (0.559193, -0.000193)
sin(57)=0.837 (0.838671, -0.001671)   cos(57)=0.544 (0.544639, -0.000639)
sin(58)=0.847 (0.848048, -0.001048)   cos(58)=0.529 (0.529919, -0.000919)
sin(59)=0.856 (0.857167, -0.001167)   cos(59)=0.514 (0.515038, -0.001038)
sin(60)=0.866 (0.866025, -0.000025)   cos(60)=0.500 (0.500000,  0.000000)
sin(61)=0.874 (0.874620, -0.000620)   cos(61)=0.484 (0.484810, -0.000810)
sin(62)=0.882 (0.882948, -0.000948)   cos(62)=0.469 (0.469472, -0.000472)
sin(63)=0.890 (0.891007, -0.001007)   cos(63)=0.453 (0.453991, -0.000991)
sin(64)=0.898 (0.898794, -0.000794)   cos(64)=0.438 (0.438371, -0.000371)
sin(65)=0.906 (0.906308, -0.000308)   cos(65)=0.423 (0.422618,  0.000382)
sin(66)=0.912 (0.913545, -0.001545)   cos(66)=0.406 (0.406737, -0.000737)
sin(67)=0.919 (0.920505, -0.001505)   cos(67)=0.390 (0.390731, -0.000731)
sin(68)=0.926 (0.927184, -0.001184)   cos(68)=0.374 (0.374607, -0.000607)
sin(69)=0.933 (0.933580, -0.000580)   cos(69)=0.358 (0.358368, -0.000368)
sin(70)=0.940 (0.939693,  0.000307)   cos(70)=0.342 (0.342020, -0.000020)
sin(71)=0.945 (0.945519, -0.000519)   cos(71)=0.325 (0.325568, -0.000568)
sin(72)=0.950 (0.951056, -0.001056)   cos(72)=0.308 (0.309017, -0.001017)
sin(73)=0.955 (0.956305, -0.001305)   cos(73)=0.292 (0.292372, -0.000372)
sin(74)=0.960 (0.961262, -0.001262)   cos(74)=0.275 (0.275637, -0.000637)
sin(75)=0.966 (0.965926,  0.000074)   cos(75)=0.259 (0.258819,  0.000181)
sin(76)=0.969 (0.970296, -0.001296)   cos(76)=0.242 (0.241922,  0.000078)
sin(77)=0.973 (0.974370, -0.001370)   cos(77)=0.225 (0.224951,  0.000049)
sin(78)=0.977 (0.978148, -0.001148)   cos(78)=0.208 (0.207912,  0.000088)
sin(79)=0.981 (0.981627, -0.000627)   cos(79)=0.191 (0.190809,  0.000191)
sin(80)=0.985 (0.984808,  0.000192)   cos(80)=0.174 (0.173648,  0.000352)
sin(81)=0.987 (0.987688, -0.000688)   cos(81)=0.156 (0.156434, -0.000434)
sin(82)=0.989 (0.990268, -0.001268)   cos(82)=0.139 (0.139173, -0.000173)
sin(83)=0.991 (0.992546, -0.001546)   cos(83)=0.121 (0.121869, -0.000869)
sin(84)=0.993 (0.994522, -0.001522)   cos(84)=0.104 (0.104528, -0.000528)
sin(85)=0.996 (0.996195, -0.000195)   cos(85)=0.087 (0.087156, -0.000156)
sin(86)=0.996 (0.997564, -0.001564)   cos(86)=0.069 (0.069757, -0.000757)
sin(87)=0.997 (0.998630, -0.001630)   cos(87)=0.052 (0.052336, -0.000336)
sin(88)=0.998 (0.999391, -0.001391)   cos(88)=0.034 (0.034900, -0.000900)
sin(89)=0.999 (0.999848, -0.000848)   cos(89)=0.017 (0.017452, -0.000452)
sin(90)=1.000 (1.000000,  0.000000)   cos(90)=0.000 (0.000000,  0.000000)

注:

- 以上只实现0~+/-90度操作,如果需要0~360度区间可以利用0~90的结果进行适当变换就行了
- 正切操作也可以利用该方法实现,不过角度计算可以定义最大值8800也即88.0度,从而规避超过88度的特殊情况
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:37:47  更:2021-07-13 17:39:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:41:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码