同步发布到我的博客:http://www.lijingquan.net/iqmath-stm32.html
看到M4的Std库有这个,想想可能M0也有用,所以实践了一下,大概如此,添加方法跟M4差不多,预编译头是ARM_MATH_CM0,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING.实验函数有如下的,工程我也可以打包,但是这儿不好放,打算放到其他电子论坛,我会发个外连.默认方法:
uint8_t sin_cos(float32_t angle)
{
float32_t sinx, cosx;
float32_t result;
uint32_t i = 0;
for(i = 0; i < 0xFFFF; i++)
{
cosx = cosf(angle);
sinx = sinf(angle);
result = sinx * sinx + cosx * cosx;
result = fabsf(result - 1.0f);
if(result > 0.00001)return 0xFF;
angle += 0.001f;
}
return 0;
}[/mw_shl_code]
使用ARM Math方法:
uint8_t sin_cos_arm_math(float32_t angle)
{
float32_t cmpv = 1.0f;
float32_t sinx, cosx;
float32_t resultA, resultB;
float32_t result;
uint32_t i = 0;
for(i = 0; i < 0xFFFF; i++)
{
cosx = arm_cos_f32(angle);
sinx = arm_sin_f32(angle);
arm_mult_f32(&sinx, &sinx, &resultA, 1);
arm_mult_f32(&cosx, &cosx, &resultB, 1);
arm_add_f32(&resultA, &resultB, &result, 1);
arm_sub_f32(&result, &cmpv, &resultA, 1);
arm_abs_f32(&resultA, &result, 1);
if(result > 0.00001)return 0xFF;
angle += 0.001f;
}
return 0;
}[/mw_shl_code]
使用IQMath方法:
uint8_t sin_cos_arm_q31(float32_t angle)
{
float32_t cmpv = 1.0f;
float32_t cresult = 1.0f;
q31_t q31_angle;
q31_t q31_cmpv;
q31_t sinx, cosx;
q31_t resultA;
q31_t resultB;
q31_t result;
uint32_t i = 0;
arm_float_to_q31(&cmpv, &q31_cmpv, 1);
for(i = 0; i < 0xFFFF; i++)
{
arm_float_to_q31(&angle, &q31_angle, 1);
cosx = arm_cos_q31(q31_angle);
sinx = arm_sin_q31(q31_angle);
arm_mult_q31(&sinx, &sinx, &resultA, 1);
arm_mult_q31(&cosx, &cosx, &resultB, 1);
arm_add_q31(&resultA, &resultB, &result, 1);
arm_sub_q31(&result, &q31_cmpv, &resultA, 1);
arm_abs_q31(&resultA, &resultB, 1);
arm_q31_to_float(&resultB, &cresult, 1);
if(cresult > 0.00001)return 0xFF;
angle += 0.001f;
}
return 0;
}[/mw_shl_code]
测试主体:
while(1)
{
while(sin_cos_arm_q31(0.3));
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
while(sin_cos_arm_q31(0.3));
GPIO_SetBits(GPIOB,GPIO_Pin_1);
}[/mw_shl_code]
图是要放的,不过我打算发到外链论坛,其中普通方法需要4.125 sec,ARM Math方法3.063 sec,IQ法是1.508 sec.
其中普通方法需要4.125 sec,ARM Math方法3.063 sec,IQ法是1.508 sec.
|