找回密码
 立即注册
查看: 38|回复: 1

TFPU中没有asin和acos,使用atan来间接实现

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:498
  • 最近打卡:2025-06-15 10:18:37
已绑定手机
已实名认证

112

主题

2384

回帖

5998

积分

版主

积分
5998
发表于 前天 12:17 | 显示全部楼层 |阅读模式

截图202506131349335723.jpg

截图202506131350173533.jpg



由于有硬件TFPU的单片机AI8051U中,

没有 asin acos 的加速支持,
所以在添加了支持硬件TFPU的数学库后,
会出现asin和acos运行不正常的问题。
===使用 atan 来间接实现
截图202506131207377280.jpg

但是使用模拟计算又会使得计算时间延长许多,
那有没有什么两全其美的方式呢?
这里给出一种利用atan来间接计算asin和acos的方式,
同时提供验证过的工程,保证方案的正确性

首先是代码部分:
  1. float asin2(float x) { float t = x / (1.0 + sqrt(1.0 - x * x));return 2.0 * atan(t); }
  2. float acos2(float x) { float t = sqrt((1.0 - x) / (1.0 + x));return 2.0 * atan(t); }
复制代码

仅需要添加以上两行代码,然后使用asin2(在math库中没有这个名字,这里加个2是避免冲突)
然后就像正常的调用asin和acos就可以了


测试程序如下:
  1. void main(void)
  2. {
  3.         P2M0 |= 0x01; P2M1 &= ~0x01;//设置P20为推挽输出,用于测量计算消耗时间
  4.         f1 = 0.5f;
  5.         while(1)
  6.         {
  7.                 P20 = 0;
  8.                 f2 = sin(f1);
  9.                 f3 = asin2(f2);
  10.                 f2 = cos(f1);
  11.                 f3 = acos2(f2);
  12.                 P20 = 1;
  13.                 Delay10ms();
  14.         }
  15. }
复制代码

使用USB硬件仿真进行正确性验证,可以看到,当运行完成f2 = sin(f1);后,f2的值为0.47942555
截图202506131215561952.jpg
然后再继续运行一条f3 = asin2(f2);,可以看到f3的值为0.5,与f1的值相同,证明经过sin后,asin2后可以正常还原数值
截图202506131216441352.jpg



同时,经过使用示波器测量,可以得到在添加TFPU库和不添加TFPU库下(这个测量屏蔽掉了sin和cos运算,单纯测量asin2和acos2),速度提升大约为90.3us/15.9us≈5.67倍

虽然是间接实现,但是仍然比模拟计算提高了不少的速度。
添加TFPU进行加速的情况下         |          不添加TFPU进行加速的情况下
截图202506131212542681.jpg 截图202506131213034117.jpg
以下是测试的工程:
asin和acos测试程序.zip (44.69 KB, 下载次数: 0)


回复

使用道具 举报 送花

3

主题

729

回帖

169

积分

等待验证会员

积分
169
发表于 前天 12:18 | 显示全部楼层
在TFPU中没有asin和acos函数,因此在添加数学库后,asin和acos的运行会出现异常。然而,可以通过使用atan来间接实现这两个函数。以下是解决方案:

1. 代码部分:
  1. c
  2. float asin2(float x) {
  3.     float t = x / (10 + sqrt(10 - x  x));
  4.     return 20.0  atan(t);
  5. }
  6. float acos2(float x) {
  7.     float t = sqrt((10 - x) / (10 + x));
  8.     return 20.0  atan(t);
  9. }
复制代码

2. 验证过程:
正确性验证:需要验证当输入在[-1, 1]范围内时,asin2和acos2的输出结果是否正确。可以编写测试用例,例如:
   
  1. c
  2.      float x = 0.5;
  3.      float asinval = asin2(x);
  4.      float acosval = acos2(x);
复制代码
精度验证:使用微调方法验证输出结果的准确性。例如,可以计算abs(asinval - 0.5)是否小于1e-5。

3. 性能验证:
计算时间:在添加代码后,测试运行时间是否增加显著。由于代码中仅增加了两行,计算时间应该不会显著增加。

4. 资源验证:
内存消耗:测试代码是否在内存上带来额外负担。由于代码简单且没有复杂的数据结构,内存消耗应该不会显著增加。

5. 兼容性验证:
处理器兼容性:确保代码在不同的处理器上都能正确运行。例如,需要验证在P2M0和P2M1中设置的掩码是否正确。

通过以上步骤,可以验证代码的正确性和性能,确保在添加代码后,asin和acos函数的运行仍然正常,计算时间不会显著延长。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-15 18:32 , Processed in 0.121898 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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