滑动平均滤波参考代码

发布时间 2023-09-27 20:23:58作者: JayWell

目录

在CH592上可以运行,用来给RSSI滤波。由于RSSI一般是-100~-20之间的数值,故数组类型是有符号数。

/*******************
 * 缓存迭代
 *
 * 参数:uint8_t num       待加入的数值
 *      uint8_t *data     待处理的数组
 *      uint8_t len        数组长度
 */
__HIGH_CODE
void buff_iteration(int8_t num, int8_t *data, uint8_t len)    //XXX
{
    static uint8_t iteration_offset = 0;    //存放缓存的偏移量
    if(iteration_offset >= len)
        iteration_offset = 0;
    data[iteration_offset] = num;
    iteration_offset++;
}


/****************************
 * 冒泡排序
 *
 * 参数:uint8_t *data     待处理的数组
 *      uint8_t len        数组长度
*/
__HIGH_CODE
void bubble_sort(int8_t *data, uint8_t len)                //XXX
{
    int8_t i, j, temp;
    for(i=0; i<len-1; i++)
        for(j=0; j<len-1-i; j++)
        {
            if(data[j] > data[j+1])
            {
                temp = data[j];
                data[j] = data[j+1];
                data[j+1] = temp;
            }
        }
}


/*************************************
 * 平均滤波
 *
 * 参数:uint8_t *data      待处理的数组
 *      uint8_t *filt_buf   冒泡排序后的数组
 *      uint8_t len         数组长度
 *      uint8_t opti        如果数据长度>=10,该变量用于选择是否需要去掉约10%的最高和约10%的最低数据,只计算中间约80%数据的平均值
*/
__HIGH_CODE
int8_t moving_avr_filt(int8_t *data, int8_t *filt_buf, uint8_t len, uint8_t opti)       //XXX
{
    uint8_t temp_cut = 0;   //存放首尾各省略多少个数据
    uint8_t num_count;      //实际计算多少个数据的平均值
    int16_t temp_sam = 0;

    if(opti && (len >= 10))
    {
        if(len >= 250){
            temp_cut = 25;      //最多首尾各略去25个数
        }
        else{
            temp_cut = (len+5)/10;      //判断需要收尾各略去多少个数据,四舍五入
        }
        memcpy(filt_buf, data, len);
        bubble_sort(filt_buf, len);     //冒泡排序
        //如果仅仅是要排除掉n个最大和n个最小值,可以直接用2个长度为n的数组,依次比较并存放需要略去的数值,总和加好后再减去这两个数组中的数值求平均值
        //冒泡排序有个好处是可以返回中位数,坏处是计算时间较长
    }

    num_count = len-2*temp_cut;     //多少个数据取平均值
    for(uint8_t i=temp_cut; i<len-temp_cut; i++)
    {
        temp_sam += filt_buf[i];
    }

    return (temp_sam + (num_count+1)/2) /num_count;     //四舍五入
}

/*****************下方为测试代码***************/
        buff_iteration((int8_t)rxBuf[0], rssi_buf, sizeof(rssi_buf));       //XXX    将rxBuf[0]迭代缓存到rssi_buf数组中
        PRINT("moving_avr_filt0 = %d\n", moving_avr_filt(rssi_buf, rssi_filt_buf, sizeof(rssi_filt_buf), 0));
        PRINT("moving_avr_filt1 = %d\n", moving_avr_filt(rssi_buf, rssi_filt_buf, sizeof(rssi_filt_buf), 1));

        PRINT("rssi_buf = ");
        for(uint8_t i=0; i<sizeof(rssi_buf); i++){
            PRINT(" %d", rssi_buf[i]);
        }
        PRINT("\n");

        PRINT("rssi_filt_buf =");
        for(uint8_t i=0; i<sizeof(rssi_filt_buf); i++)
            PRINT( " %d", rssi_filt_buf[i]);
        PRINT("\n");