王昱顺 发表于 3 天前

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








由于有硬件TFPU的单片机AI8051U中,
并 没有 asin 和 acos 的加速支持,
所以在添加了支持硬件TFPU的数学库后,
会出现asin和acos运行不正常的问题。
===使用 atan 来间接实现


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

首先是代码部分:
float asin2(float x) { float t = x / (1.0 + sqrt(1.0 - x * x));return 2.0 * atan(t); }
float acos2(float x) { float t = sqrt((1.0 - x) / (1.0 + x));return 2.0 * atan(t); }
仅需要添加以上两行代码,然后使用asin2(在math库中没有这个名字,这里加个2是避免冲突)
然后就像正常的调用asin和acos就可以了


测试程序如下:
void main(void)
{
      P2M0 |= 0x01; P2M1 &= ~0x01;//设置P20为推挽输出,用于测量计算消耗时间
      f1 = 0.5f;
      while(1)
      {
                P20 = 0;
                f2 = sin(f1);
                f3 = asin2(f2);
                f2 = cos(f1);
                f3 = acos2(f2);
                P20 = 1;
                Delay10ms();
      }
}
使用USB硬件仿真进行正确性验证,可以看到,当运行完成f2 = sin(f1);后,f2的值为0.47942555

然后再继续运行一条f3 = asin2(f2);,可以看到f3的值为0.5,与f1的值相同,证明经过sin后,asin2后可以正常还原数值




同时,经过使用示波器测量,可以得到在添加TFPU库和不添加TFPU库下(这个测量屏蔽掉了sin和cos运算,单纯测量asin2和acos2),速度提升大约为90.3us/15.9us≈5.67倍
虽然是间接实现,但是仍然比模拟计算提高了不少的速度。
添加TFPU进行加速的情况下         |          不添加TFPU进行加速的情况下

以下是测试的工程:



国芯人工智能 发表于 3 天前

在TFPU中没有asin和acos函数,因此在添加数学库后,asin和acos的运行会出现异常。然而,可以通过使用atan来间接实现这两个函数。以下是解决方案:

1. 代码部分:

c
float asin2(float x) {
    float t = x / (10 + sqrt(10 - xx));
    return 20.0atan(t);
}

float acos2(float x) {
    float t = sqrt((10 - x) / (10 + x));
    return 20.0atan(t);
}

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

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

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

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

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

[本文内容由国芯人工智能辅助生成,仅供参考]
页: [1]
查看完整版本: TFPU中没有asin和acos,使用atan来间接实现