#ifndef __BSP_RR_H
#define __BSP_RR_H
#define RMS_WINDOW_SIZE 30
typedef struct
{
short window[RMS_WINDOW_SIZE];
unsigned char index;
double sum_of_squares;
double rms_value;
unsigned char count;
unsigned char counter;
unsigned char active;
} updateRMS_T;
extern updateRMS_T g_updateRMS_T;
extern updateRMS_T g_updateRMS_T;
#endif
updateRMS_T g_updateRMS_T = { {0}, 0, 0.0, 0.0, 0 };
void stop_updateRMS(updateRMS_T *sw)
{
for (int i = 0; i < RMS_WINDOW_SIZE; ++i)
{
sw->window[i] = 0;
}
sw->index = 0;
sw->sum_of_squares = 0.0;
sw->rms_value = 0.0;
sw->count = 0;
sw->counter = 50;
sw->active = 1;
}
void updateRMS(updateRMS_T *sw, short new_sample)
{
short s_new_sample;
if (sw->counter)
{
sw->counter--;
return;
}
if (sw->active == 0)
{
return;
}
if (sw->count >= RMS_WINDOW_SIZE)
{
sw->sum_of_squares -= sw->window[sw->index] * sw->window[sw->index];
}
else
{
sw->count++;
}
s_new_sample = new_sample / 10;
sw->window[sw->index] = s_new_sample;
sw->sum_of_squares += s_new_sample * s_new_sample;
sw->index = (sw->index + 1) % RMS_WINDOW_SIZE;
if (sw->count == RMS_WINDOW_SIZE)
{
sw->rms_value = (sqrt(sw->sum_of_squares / RMS_WINDOW_SIZE)) * 10;
sw->active = 0;
sw->sum_of_squares = 0;
}
}
在您提供的updateRMS函数代码中,我注意到了一些细节和可能的改进点。首先,s_new_sample变量被用来存储缩放后的新样本值,但原代码中并没有对s_new_sample进行任何检查或错误处理,这可能是一个潜在的错误源。此外,尽管您在计算RMS值时乘以了10(sw->rms_value = (sqrt(sw->sum_of_squares / RMS_WINDOW_SIZE)) * 10;),但在将新样本添加到平方和时进行了除以10的操作(s_new_sample = new_sample / 10;),这意味着您的RMS值可能被错误地缩小了100倍(10除以10再乘以10)。
下面是一个稍微修改过的updateRMS函数版本,其中包括了一些错误检查和可能的改进:
c
#include <math.h>
void updateRMS(updateRMS_T *sw, short new_sample)
{
short s_new_sample;
if (sw->counter)
{
sw->counter--;
return;
}
if (sw->active == 0)
{
return;
}
if (sw->count > 0)
{
if (sw->count >= RMS_WINDOW_SIZE)
{
sw->sum_of_squares -= sw->window[sw->index] * sw->window[sw->index];
}
}
s_new_sample = new_sample;
if (s_new_sample < SHRT_MIN || s_new_sample > SHRT_MAX)
{
return;
}
sw->window[sw->index] = s_new_sample;
sw->sum_of_squares += s_new_sample * s_new_sample;
sw->index = (sw->index + 1) % RMS_WINDOW_SIZE;
if (sw->count < RMS_WINDOW_SIZE)
{
sw->count++;
}
if (sw->count == RMS_WINDOW_SIZE)
{
sw->rms_value = sqrt((double)sw->sum_of_squares / RMS_WINDOW_SIZE);
sw->active = 0;
sw->sum_of_squares = 0;
}
}
在这个版本中,我移除了对新样本值的缩放,并添加了对new_sample值的范围检查,以确保它不会溢出short类型的范围。同时,我也修复了当sw->count为0时可能导致除以零的错误,并在计算RMS值时不再乘以10,因为我们在添加样本到平方和时没有进行缩放。最后,我将sw->count的递增移到了计算RMS值之前,以确保在计算RMS值时窗口是满的。
请注意,这些更改可能需要根据您的具体应用场景和需求进行调整。如果您确实需要对样本值进行缩放,那么您应该在计算RMS值时相应地调整它。