打印
[其他]

使用CMSIS DSP库实现自适应滤波器

[复制链接]
635|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、mindsdk使用
首先登录mindsdk,网址为https://mindsdk.mindmotion.co…,首次登录需要先注册。



接着选择对应的工具链和开发板。



接着下载生成的工程压缩包。



解压后可以看到文件夹内部的结构,大致包括demo例程,hal库,外设应用,启动文件等。



二、cmsis dsp库使用
Common Microcontroller Software Interface Standard (CMSIS) 是一个独立于供应商的抽象层,适用于基于 Arm Cortex 处理器的微控制器。其下包括许多组件,dsp包就是其中一个,包括常规的数字信号处理函数,支持dsp硬件。



由于最新的cmsis进行了改版,新版本中的dsp库没有预编译的lib,使用起来暂时比较麻烦,这次使用v5.7版本进行演示。在keil中首先打开pack install 安装5.7版本的cmsis。



在工程管理中加入以下文件,包括Lib中的arm_ARMv8MMLldfsp_math.lib和Include中包括arm_math.h所有文件,我的路径如下。





三、LMS 最小均方自适应滤波器实现
LMS 最小均方自适应滤波器能够"学习"未知的传输特性。 LMS 滤波器使用梯度下降方法,根据瞬时错误信号更新滤波系数。自适应滤波器常用于通信系统、均衡器和降噪。



自适应滤波器的主要通过下面两个函数实现,支持逐点实时滤波。
函数 arm_lms_norm_init_f32:此函数用于自适应滤波器初始化。

void arm_lms_norm_init_f32(
arm_lms_norm_instance_f32 * S,
uint16_t numTaps,
float32_t * pCoeffs,
float32_t * pState,
float32_t mu,
uint32_t blockSize);



函数 arm_lms_norm_f32:此函数用于自适应滤波器实时滤波。

void arm_lms_norm_f32(
arm_lms_norm_instance_f32 * S,
const float32_t * pSrc,
float32_t * pRef,
float32_t * pOut,
float32_t * pErr,
uint32_t blockSize);



我们直接使用plus-f5270_mdk\demo_apps\basic\hello_world的例程进行开发,main.c更改如下:

#include "board_init.h"
#include "arm_math.h"
#include "arm_const_structs.h"

#define TEST_LENGTH_SAMPLES  2048  
#define BLOCK_SIZE           2048   
#define NUM_TAPS             20   

uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;           

static float32_t testInput_f32_50Hz_200Hz[TEST_LENGTH_SAMPLES]={0};
static float32_t testInput_f32_REF[TEST_LENGTH_SAMPLES]={0};        
static float32_t test_f32_ERR[TEST_LENGTH_SAMPLES]={0};           
static float32_t testOutput[TEST_LENGTH_SAMPLES]={0};              
static float32_t lmsStateF32[BLOCK_SIZE + NUM_TAPS - 1]={0};   
static float32_t lmsCoeffs32[NUM_TAPS] = {0};                     
float32_t testInput50Hz_200Hz;
float32_t testOutput1;

void arm_lms_f32_test1(void)
{
    uint32_t i;
    float32_t  *inputF32, *outputF32, *inputREF, *outputERR;
    arm_lms_norm_instance_f32 lmsS={0};


    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {

        testInput_f32_50Hz_200Hz = arm_sin_f32(2*3.1415926f*50*i/1000) + arm_sin_f32(2*3.1415926f*200*i/1000);
        testInput_f32_REF =  arm_sin_f32(2*3.1415926f*50*i/1000);
    }


    memset(lmsCoeffs32,0,sizeof(lmsCoeffs32));
    memset(lmsStateF32,0,sizeof(lmsStateF32));   


    inputF32 = (float32_t *)&testInput_f32_50Hz_200Hz[0];
    outputF32 = (float32_t *)&testOutput[0];              
    inputREF = (float32_t *)&testInput_f32_REF[0];        
    outputERR = (float32_t *)&test_f32_ERR[0];            



    arm_lms_norm_init_f32 (&lmsS,                        
                           NUM_TAPS,                     
                            (float32_t *)&lmsCoeffs32[0],
                            &lmsStateF32[0],              
                            0.1,                          
                            blockSize);                  



    /* ʵÏÖLMS×ÔÊÊÓ¦Â˲¨£¬ÕâÀïÿ´Î´¦Àí1¸öµã */
    for(i=0; i < numBlocks; i++)
    {

        arm_lms_norm_f32(&lmsS, /* LMS½á¹¹Ìå */
                        inputF32 + (i * blockSize),   
                        inputREF + (i * blockSize),   
                        outputF32 + (i * blockSize),  
                        outputERR + (i * blockSize),  
                        blockSize);                     

    }


    printf("y1=[");
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        printf("%f ", testInput_f32_50Hz_200Hz);
        testInput50Hz_200Hz = testInput_f32_50Hz_200Hz;
    }
    printf("]\r\n");
    printf("=========================================\r\n");   

    printf("y2=[");
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        printf("%f ", outputF32);
    }
    printf("]\r\n");
    printf("=========================================\r\n");   

    printf("y3=[");
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        printf("%f ", test_f32_ERR);
    }
    printf("]\r\n");
    printf("=========================================\r\n");   
}


int main(void)
{
    uint8_t ch;

    BOARD_Init();

    printf("hello, world!!\r\n");

    while (1)
    {
        getchar();
                arm_lms_f32_test1();
    }
}



这里输入的原始波形 200Hz + 50Hz 正弦波,滤除 200Hz 正弦波,通过串口打印数据,使用matlab画出波形。


————————————————
版权声明:本文为CSDN博主「极术社区」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_47569031/article/details/127440827

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

148

主题

4100

帖子

5

粉丝