如题。
想实时监测一个频率的幅值做告警,但芯片的能力不够,现在用戈策尔算法获取到两个目标频率周期的采样数据后再计算实测128点的数据算完要5ms。
想要用滑动戈策尔采一次算一次但自己没折腾出来
[C] 纯文本查看 复制代码 static void CalcGoertzel(GOERTZEL_T *_p, int32_t *_pData, uint16_t _usLen)
{
uint8_t useWinFlag = 0;
int64_t q0 = 0, q1 = 0, q2 = 0;
if(_p->index > 18)
{
usedWinFlag = 1;
}
for(uint16_t i = 0; i < _usLen; i++)
{
//int64_t data = (int64_t)FLOAT_TO_Q16(_pData[i]); //Q47.16
int64_t data = 0;
int64_t coeff_term = ((int64_t)_p->coeff_Q15_16 * q1) >> 16;
if(useWinFlag)
{
data = ((int64_t)_pData[i] * FaltTopWindow[i]) >> 16;
}
else
{
data = _pData[i];
}
q0 = (data) + coeff_term - q2;
q2 = q1;
q1 = q0;
}
const int64_t SCALE = 1LL << 16;
float q1_f = (float)q1 / (float)SCALE;
float q2_f = (float)q2 / (float)SCALE;
float real = q1_f - q2_f * _p->cosVal;
float imag = q2_f * _p->sinVal;
if(useWinFlag)
{
_p->map *= 4.18f;
}
#if USED_HANNING_WIN == 1
_p->map = sqrtf(real * real + imag * imag) * 4 / N;
#else
//#if USED_FALT_TOP_WIN == 1
// _p->map *= 4.18f;
//#endif /* USED_FALT_TOP_WIN == 1 */
_p->map = sqrtf(real * real + imag * imag) * 2 / N;
#endif /* USED_HANNING_WIN == 1 */
_p->map = _p->map * K_ADC;
if(_p->map >= 5 && _p->map < 290)
{
if(_p->index > 10)
{
_p->map_2 = _p->map * K2 + B2;
}
else
{
_p->map_2 = _p->map * K + B;
}
}
else
{
_p->map_2 = _p->map;
}
_p->rms = _p->map_2 / sqrtf(2.0f);
}
这个是做的定点数戈策尔
|