DSP的三角函数(\Embedded Workbench 9.0\arm\CMSIS\DSP)

南北湖创客5个月前代码基础6

1、主要代码在

BasicMathFunctions文件夹


2、主要例子在

arm_sin_cos_example文件夹


3、arm_sin_cos_example_f32文件


4、先总结网上的DSP说法


FPU 即浮点运算单元(Float Point Unit)。浮点运算,对于定点 CPU(没有 FPU 的 CPU)来说必须要按照IEEE-754 标准的算法来完成运算,是相当耗费时间的。

而对于有 FPU 的 CPU来说,浮点运算则只是几条指令的事情,速度相当快。


STM32F4 属于 Cortex M4F 架构,带有 32 位单精度硬件 FPU,支持浮点指令集,相对于 Cortex M0 和Cortex M3 等,高出数十倍甚至上百倍的运算性能。

STM32F4 硬件上要开启 FPU是很简单的,通过一个叫:协处理器控制寄存器(CPACR)的寄存器设置即可开启 STM32F4 的硬件 FPU。


运行一次sin函数大约需要30~50us,运行一次arm_sin_f32函数,

只需要3us。 运行时间是1个数量级差距。


再来看函数:

sin和cos的值不在-1到1范围,判定是arm_sin_cos_f32这个函数造成的,并不是角度异常造成的。

在ARM CMSIS官网上下载了源代码,找到arm_sin_cos_f32这个函数的源代码

上面的函数采用的方法是线性插值的方法,所以fract应该只在0到1,所以产生了上面的BUG

Arm_sin_cos_f32这个函数的输入范围是-180到180,但官网上也写了,如果超出这个范围,函数将自动调整回来,所以我的代码中没有对输入范围有限制,比较在-720度时出现了这个问题

附代码:

void arm_sin_cos_f32(

  float32_t theta,

  float32_t * pSinVal,

  float32_t * pCosVal)

{

  float32_t fract, in;                             /* Temporary variables for input, output */

  uint16_t indexS, indexC;                         /* Index variable */

  float32_t f1, f2, d1, d2;                        /* Two nearest output values */

  int32_t n;

  float32_t findex, Dn, Df, temp;

 

  /* input x is in degrees */

  /* Scale the input, divide input by 360, for cosine add 0.25 (pi/2) to read sine table */

  in = theta * 0.00277777777778f;

 

  /* Calculation of floor value of input */

  n = (int32_t) in;

 

  /* Make negative values towards -infinity */

  if(in < 0.0f)

  {

    n--;

  }

  /* Map input value to [0 1] */

  in = in - (float32_t) n;

 

  /* Calculation of index of the table */

  findex = (float32_t) FAST_MATH_TABLE_SIZE * in;

  indexS = ((uint16_t)findex) & 0x1ff;

  indexC = (indexS + (FAST_MATH_TABLE_SIZE / 4)) & 0x1ff;

 

  /* fractional value calculation */

  fract = findex - (float32_t) indexS;

 

  /* Read two nearest values of input value from the cos & sin tables */

  f1 = sinTable_f32[indexC+0];

  f2 = sinTable_f32[indexC+1];

  d1 = -sinTable_f32[indexS+0];

  d2 = -sinTable_f32[indexS+1];

 

  Dn = 0.0122718463030f; // delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE

  Df = f2 - f1; // delta between the values of the functions

  temp = Dn*(d1 + d2) - 2*Df;

  temp = fract*temp + (3*Df - (d2 + 2*d1)*Dn);

  temp = fract*temp + d1*Dn;

 

  /* Calculation of cosine value */

  *pCosVal = fract*temp + f1;

 

  /* Read two nearest values of input value from the cos & sin tables */

  f1 = sinTable_f32[indexS+0];

  f2 = sinTable_f32[indexS+1];

  d1 = sinTable_f32[indexC+0];

  d2 = sinTable_f32[indexC+1];

 

  Df = f2 - f1; // delta between the values of the functions

  temp = Dn*(d1 + d2) - 2*Df;

  temp = fract*temp + (3*Df - (d2 + 2*d1)*Dn);

  temp = fract*temp + d1*Dn;

 

  /* Calculation of sine value */

  *pSinVal = fract*temp + f1;

}


相关文章

二人接力队列

二人接力队列

一般循环队列的属性如下:    elements\textit{elements}elements:一个固定大小的数组,用于保存循环队列的元素。  &...

动态规划

是一种算法设计技巧,用于解决具有重叠子问题和最优子结构的问题。#include <stdio.h>// 动态规划解决斐波那契数列int fibonacci(int n) {&nb...

HAL_TIM_Base_Start_IT

HAL_TIM_Base_Start_IT这两个中断开启函数使用时会立即进入一次中断回调HAL_TIM_Base_Start_IT(&htim2);//即使下一行加上HAL_TIM_Base_...

make及makefile,编译原理

1、出现*** No rule to make target ` ‘, needed by xxx. Stop.时,基本都是属于找不到所依赖的文件所导致的,查看.pro文件是否有问题。使用Eclips...

延时函数(阻塞式,非阻塞式)

常规阻塞式延时:void delay_1ms(uint32_t count){    delay = count;    delay--;&...

stm32的代码和内存管理(SRAM空间)

stm32的代码和内存管理(SRAM空间)

SRAM空间1、文件中声明和定义(全局变量、静态数据和常量)从0x20000000开始,到堆的起始地址(堆是向上的)。2、HEAP区;(堆是向上的)3、STACK区。(栈是向下的)堆区(heap):一...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。