0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于infineonPSOC62开发板的-信号处理前端 虚拟示波器-工具集

RTThread物联网操作系统 来源:未知 2023-10-11 18:35 次阅读

一、前言


本项目基于英飞凌PSoC 6 RTT开发板实现了信号处理前端-一个信号处理的工具集。

包括虚拟示波器音频采集分析,谐波分析,周期幅值相位分析,数字滤波,极值检测,可上位机可视化和命令行人机交互,可以方便继续扩展相关功能,继续丰富工具集。

wKgZomUt2qqANAVDAAEqzFtWVfM414.png

视频:https://www.bilibili.com/video/BV1PM4y147v1/

代码仓库:https://gitee.com/qinyunti/infineon-psoc62.git

二、移植DSP算法


2.1添加代码

git clone https://github.com/ARM-software/CMSIS_5.git

CMSIS_5CMSISDSP下是相关文件,Source下是源码

wKgZomUt2qqAI9LLAADrIrG0gII433.png

将DSP文件夹复制到自己的工程目录中,只保留

Include,PrivateInclude,Source三个文件夹

wKgZomUt2qqAQY5VAABscxwByu8359.pngwKgZomUt2qqAbte-AABsDha8WV4274.png

Source下的每个子文件夹都是一类算法,里面的每个c都对应一个计算函数,并且有一个总文件包括其中所有的单个.c,比如BasicMathFunctions.c中

wKgZomUt2quAbHcKAAF5499h9Fw883.png

删除这些总的.c,避免编译重复

删除以下文件和所有的非.c和.h文件


		

1BasicMathFunctions:BasicMathFunctions.c,BasicMathFunctionsF16.c 2BayesFunctions:BayesFunctions.c,BayesFunctionsF16.c 3CommonTables:CommonTables.c,CommonTablesF16.c 4ComplexMathFunctions:ComplexMathFunctions.c,ComplexMathFunctionsF16.c 5ControllerFunctions:ControllerFunctions.c 6DistanceFunctions:DistanceFunctions.c,DistanceFunctionsF16.c 7FastMathFunctions:FastMathFunctions.c,FastMathFunctionsF16.c 8FilteringFunctions:FilteringFunctions.c,FilteringFunctionsF16.c 9InterpolationFunctions:InterpolationFunctions.c,InterpolationFunctionsF16.c 10MatrixFunctions:MatrixFunctions.c,MatrixFunctionsF16.c 11QuaternionMathFunctions:QuaternionMathFunctions.c 12StatisticsFunctions:StatisticsFunctions.c,StatisticsFunctionsF16.c 13SupportFunctions:SupportFunctions.c,SupportFunctionsF16.c 14SVMFunctions:SVMFunctions.c,SVMFunctionsF16.c 15TransformFunctions:TransformFunctions.c,TransformFunctionsF16.c,arm_bitreversal2.S


		

wKgZomUt2quAO_M6AAIl-PTKjVM320.png

工程设置添加相关头文件包含路径

2.2测试

复制CMSIS_5CMSISDSPExamplesARMarm_fft_bin_example下的arm_fft_bin_data.c和arm_fft_bin_example_f32.c到自己的工程目录

arm_fft_bin_example_f32.c下的

int32_t main(void)改为int32_t ffttest_main(void)

并添加#define SEMIHOSTING以使能printf打印,我们已经重定向实现了printf打印到串口。

由于 arm_cfft_f32(&varInstCfftF32, testInput_f32_10khz, ifftFlag, doBitReverse);会修改testInput_f32_10khz的内容,所以添加一个缓存,以便能重复测试


			

1float32_ttesttmp_f32_10khz[2048]; 2/*ProcessthedatathroughtheCFFT/CIFFTmodule*/ 3memcpy(testtmp_f32_10khz,testInput_f32_10khz,sizeof(testInput_f32_10khz)); 4arm_cfft_f32(&varInstCfftF32,testtmp_f32_10khz,ifftFlag,doBitReverse); 5/*ProcessthedatathroughtheComplexMagnitudeModulefor 6calculatingthemagnitudeateachbin*/ 7arm_cmplx_mag_f32(testtmp_f32_10khz,testOutput,fftSize);

在自己的main函数中申明并调用

int32_t ffttest_main(void)

ffttest_main()

编译运行可以看到串口打印SUCCESS说明测试OK。

将输入输出数据打印


			

1printf("SUCCESS "); 2for(inti=0;i 3{ 4if(i2) 5{ 6printf("/*%f,%f*/ ",testInput_f32_10khz[i],testOutput[i]); 7} 8else 9{ 10printf("/*%f,%f*/ ",testInput_f32_10khz[i],0.0); 11} 12}

使用serialstudio可视化显示,可以看到计算结果FFT频率明显的峰值

wKgZomUt2quAYaGdAAJwW6fancA932.png

三、音频采集


3.1原理图

从原理图看到有6路模拟输入,分别对应

P10.0~P10.5, VREF为模拟参考电压。

wKgZomUt2quANX5HAAFJr7GsAmM777.png

wKgZomUt2quABh9MAANJysolPLo323.png

使用的是MAX4466的MIC,接到ADC0,如下图所示

wKgZomUt2qyANhDlAAXNXx882vI665.png

wKgZomUt2qyALrBBAANE_SBjPwE946.png


		

3.2配置模拟采集引脚

wKgZomUt2qyAPUbOAAIv02LauXg829.png

3.3代码

Adc.c


			

1#include"cy_pdl.h" 2#include"cyhal.h" 3#include"cybsp.h" 4#include"cy_retarget_io.h" 5#defineVPLUS_CHANNEL_0(P10_0) 6/*Conversionfactor*/ 7#defineMICRO_TO_MILLI_CONV_RATIO(1000u) 8/*Acquistiontimeinnanosecond*/ 9#defineACQUISITION_TIME_NS(116680u) 10/*ADCScandelayinmillisecond*/ 11#defineADC_SCAN_DELAY_MS(200u) 12/******************************************************************************* 13*EnumeratedTypes 14*******************************************************************************/ 15/*ADCChannelconstants*/ 16enumADC_CHANNELS 17{ 18CHANNEL_0=0, 19NUM_CHANNELS 20}adc_channel; 21/******************************************************************************* 22*GlobalVariables 23*******************************************************************************/ 24/*ADCObject*/ 25cyhal_adc_tadc_obj; 26/*ADCChannel0Object*/ 27cyhal_adc_channel_tadc_chan_0_obj; 28/*DefaultADCconfiguration*/ 29constcyhal_adc_config_tadc_config={ 30.continuous_scanning=false,//ContinuousScanningisdisabled 31.average_count=1,//Averagecountdisabled 32.vref=CYHAL_ADC_REF_VDDA,//VREFforSingleendedchannelsettoVDDA 33.vneg=CYHAL_ADC_VNEG_VSSA,//VNEGforSingleendedchannelsettoVSSA 34.resolution=12u,//12-bitresolution 35.ext_vref=NC,//Noconnection 36.bypass_pin=NC};//Noconnection 37/*Asynchronousreadcompleteflag,usedinEventHandler*/ 38staticboolasync_read_complete=true; 39#defineNUM_SCAN(1000) 40#defineNUM_CHANNELS(1) 41/*Variabletostoreresultsfrommultiplechannelsduringasynchronousread*/ 42int32_tresult_arr[NUM_CHANNELS*NUM_SCAN]={0}; 43staticvoidadc_event_handler(void*arg,cyhal_adc_event_tevent) 44{ 45if(0u!=(event&CYHAL_ADC_ASYNC_READ_COMPLETE)) 46{ 47/*Setasyncreadcompleteflagtotrue*/ 48async_read_complete=true; 49} 50} 51intadc_init(void) 52{ 53/*Variabletocapturereturnvalueoffunctions*/ 54cy_rslt_tresult; 55/*InitializeADC.TheADCblockwhichcanconnecttothechannel0inputpinisselected*/ 56result=cyhal_adc_init(&adc_obj,VPLUS_CHANNEL_0,NULL); 57if(result!=CY_RSLT_SUCCESS) 58{ 59printf("ADCinitializationfailed.Error:%ld ",(longunsignedint)result); 60CY_ASSERT(0); 61} 62/*ADCchannelconfiguration*/ 63constcyhal_adc_channel_config_tchannel_config={ 64.enable_averaging=false,//Disableaveragingforchannel 65.min_acquisition_ns=ACQUISITION_TIME_NS,//Minimumacquisitiontimesetto1us 66.enabled=true};//SamplethischannelwhenADCperformsascan 67/*Initializeachannel0andconfigureittoscanthechannel0inputpininsingleendedmode.*/ 68result=cyhal_adc_channel_init_diff(&adc_chan_0_obj,&adc_obj,VPLUS_CHANNEL_0, 69CYHAL_ADC_VNEG,&channel_config); 70if(result!=CY_RSLT_SUCCESS) 71{ 72printf("ADCfirstchannelinitializationfailed.Error:%ld ",(longunsignedint)result); 73CY_ASSERT(0); 74} 75/*Registeracallbacktohandleasynchronousreadcompletion*/ 76cyhal_adc_register_callback(&adc_obj,&adc_event_handler,result_arr); 77/*Subscribetotheasyncreadcompleteeventtoprocesstheresults*/ 78cyhal_adc_enable_event(&adc_obj,CYHAL_ADC_ASYNC_READ_COMPLETE,CYHAL_ISR_PRIORITY_DEFAULT,true); 79printf("ADCisconfiguredinmultichannelconfiguration. "); 80printf("Channel0isconfiguredinsingleendedmode,connectedtothe "); 81printf("channel0inputpin.Provideinputvoltageatthechannel0inputpin "); 82return0; 83} 84intadc_samp(void) 85{ 86/*Variabletocapturereturnvalueoffunctions*/ 87cy_rslt_tresult; 88/*VariabletostoreADCconversionresultfromchannel0*/ 89int32_tadc_result_0=0; 90/*Clearasyncreadcompleteflag*/ 91async_read_complete=false; 92/*Initiateanasynchronousreadoperation.Theeventhandlerwillbecalled 93*whenitiscomplete.*/ 94memset(result_arr,0,sizeof(result_arr)); 95cyhal_gpio_write_internal(CYBSP_USER_LED,true); 96result=cyhal_adc_read_async_uv(&adc_obj,NUM_SCAN,result_arr); 97if(result!=CY_RSLT_SUCCESS) 98{ 99printf("ADCasyncreadfailed.Error:%ld ",(longunsignedint)result); 100CY_ASSERT(0); 101} 102while(async_read_complete==false); 103cyhal_gpio_write_internal(CYBSP_USER_LED,false); 104/* 105*Readdatafromresultlist,inputvoltageintheresultlistisin 106*microvolts.Convertitmillivoltsandprintinputvoltage 107* 108*/ 109for(inti=0;i110{ 111adc_result_0=result_arr[i]/MICRO_TO_MILLI_CONV_RATIO; 112printf("/*%4ld*/ ",(longint)adc_result_0); 113} 114return0; 115}

Adc.h


			

1#ifndefADC_H 2#defineADC_H 3intadc_init(void); 4intadc_samp(void); 5#endif

Main.c调用

adc_init();

adc_samp();

3.4时钟

时钟源是100Mhz,12分频=8.33M,满足1.8MHz~18MHz之间的要求

默认是按照8M配置

wKgZomUt2qyAam4EAAIgBrBQPbk231.png

wKgZomUt2qyAXsRjAAH-QToczyI645.png

3.5采样时间

采样前后翻转LED用示波器测量时间


			

1intadc_samp(void) 2{ 3/*Variabletocapturereturnvalueoffunctions*/ 4cy_rslt_tresult; 5/*VariabletostoreADCconversionresultfromchannel0*/ 6int32_tadc_result_0=0; 7/*Clearasyncreadcompleteflag*/ 8async_read_complete=false; 9/*Initiateanasynchronousreadoperation.Theeventhandlerwillbecalled 10*whenitiscomplete.*/ 11memset(result_arr,0,sizeof(result_arr)); 12cyhal_gpio_write_internal(CYBSP_USER_LED,true); 13result=cyhal_adc_read_async_uv(&adc_obj,NUM_SCAN,result_arr); 14if(result!=CY_RSLT_SUCCESS) 15{ 16printf("ADCasyncreadfailed.Error:%ld ",(longunsignedint)result); 17CY_ASSERT(0); 18} 19while(async_read_complete==false); 20cyhal_gpio_write_internal(CYBSP_USER_LED,false); 21/* 22*Readdatafromresultlist,inputvoltageintheresultlistisin 23*microvolts.Convertitmillivoltsandprintinputvoltage 24* 25*/ 26for(inti=0;i27{ 28adc_result_0=result_arr[i]/MICRO_TO_MILLI_CONV_RATIO; 29printf("/*%4ld*/ ",(longint)adc_result_0); 30} 31return0; 32}

采样1000次,分别设置采样时间为2uS和1uS对比。

#define ACQUISITION_TIME_NS (2000u)

10.28mS

wKgZomUt2q2AXCqeAAOo21kjK3M789.png

#define ACQUISITION_TIME_NS (1000u)

9.32mS

wKgZomUt2q2AGWKPAAOfvkv-IWo683.png

10.28-9.32=0.96mS 1000次约1mS,1次刚好是1uS。

而1000次除去采样时间其他时间为8.32mS,即一次8.32uS。

因为前面设置了时钟为8.33MHz, 从前面时序一节可以看到,除去采样时间,其他转换时间等需要14个CLK,所以需要14/8.33uS=1.7uS. 剩余的8.32-1.7为数据搬运,软件处理等时间。

3.6 采样值正确性

1.545V和示波器采集为1.54V差不多是正确的,这里没有高精度万用表就不对测试精度了,只测试了正确性。

wKgZomUt2q2Aem6MAAHPY_Qtpsk969.png

wKgZomUt2q2AAVn6AANOUdltiws298.png

3.7音频采集

一次采集1000次然后串口打印,使用SerialStudio可视化显示


			

1intadc_samp(void) 2{ 3/*Variabletocapturereturnvalueoffunctions*/ 4cy_rslt_tresult; 5/*VariabletostoreADCconversionresultfromchannel0*/ 6int32_tadc_result_0=0; 7/*Clearasyncreadcompleteflag*/ 8async_read_complete=false; 9/*Initiateanasynchronousreadoperation.Theeventhandlerwillbecalled 10*whenitiscomplete.*/ 11memset(result_arr,0,sizeof(result_arr)); 12cyhal_gpio_write_internal(CYBSP_USER_LED,true); 13result=cyhal_adc_read_async_uv(&adc_obj,NUM_SCAN,result_arr); 14if(result!=CY_RSLT_SUCCESS) 15{ 16printf("ADCasyncreadfailed.Error:%ld ",(longunsignedint)result); 17CY_ASSERT(0); 18} 19while(async_read_complete==false); 20cyhal_gpio_write_internal(CYBSP_USER_LED,false); 21/* 22*Readdatafromresultlist,inputvoltageintheresultlistisin 23*microvolts.Convertitmillivoltsandprintinputvoltage 24* 25*/ 26for(inti=0;i27{ 28adc_result_0=result_arr[i]/MICRO_TO_MILLI_CONV_RATIO; 29printf("/*%4ld*/ ",(longint)adc_result_0); 30} 31return0; 32}

四、信号处理前端


4.1 电能质量,谐波分析

4.1.1添加命令行

在电能检测应用中,电能质量一项分析即谐波分析,谐波分量大,说明电能质量不好,

基于本板信号处理前端也实现了该功能。

shell_fun.h


			

1voidFftFun(void*param);

shell_fun.c


			

1include"fft.h"

shell_cmd_list中添加一行


			

1{(constuint8_t*)"fft",FftFun,"fft"},/*打印帮助信息*/

添加命令执行函数


			

1voidFftFun(void*param) 2{ 3fft_main(); 4}

4.1.2添加实现

Fft.c


			

1#include"arm_math.h" 2#include"arm_const_structs.h" 3#include 4#defineTEST_LENGTH_SAMPLES2048 5externfloat32_ttestInput_f32_10khz[TEST_LENGTH_SAMPLES]; 6staticfloat32_ttestOutput[TEST_LENGTH_SAMPLES/2]; 7staticuint32_tfftSize=1024; 8staticuint32_tifftFlag=0; 9staticuint32_tdoBitReverse=1; 10staticarm_cfft_instance_f32varInstCfftF32; 11staticinttestIndex=0; 12staticfloattesttmp_f32_10khz[2048]; 13staticint32_tadcbuffer[2048]; 14int32_tfft_main(void) 15{ 16arm_statusstatus; 17float32_tmaxValue; 18status=ARM_MATH_SUCCESS; 19status=arm_cfft_init_f32(&varInstCfftF32,fftSize); 20//memcpy(testtmp_f32_10khz,testInput_f32_10khz,sizeof(testInput_f32_10khz)); 21adc_samp(adcbuffer,2048); 22for(inti=0;i<2048;i++) 23{ 24testtmp_f32_10khz[i]=(float)adcbuffer[i]; 25} 26arm_cfft_f32(&varInstCfftF32,testtmp_f32_10khz,ifftFlag,doBitReverse); 27arm_cmplx_mag_f32(testtmp_f32_10khz,testOutput,fftSize); 28/*CalculatesmaxValueandreturnscorrespondingBINvalue*/ 29arm_max_f32(testOutput,fftSize,&maxValue,&testIndex); 30int32_tout=0; 31for(inti=0;i32{ 33if(i>TEST_LENGTH_SAMPLES/2) 34{ 35out=testOutput[i-TEST_LENGTH_SAMPLES/2]/1024; 36} 37else 38{ 39out=testOutput[i]/1024; 40} 41printf("/*%ld,%ld*/ ",adcbuffer[i],out); 42} 43} 44/**endlink*/

Fft.h


			

1#ifndefFFT_H 2#defineFFT_H 3intfft_main(void); 4#endif

测试

wKgZomUt2q2AN5sgAADTvVziW8A653.png

4.2 周期(频率),幅值,相位分析

4.2.1 原理

FFT变换结果,幅值最大的横坐标对应信号频率,纵坐标对应幅度。幅值最大的为out[m]=val;则信号频率f0=(Fs/N)m ,信号幅值Vpp=val/(N/2)。N为FFT的点数,Fs为采样频率。相位Pha=atan2(a, b)弧度制,其中ab是输出虚数结果的实部和虚部。

4.2.2添加命令行

shell_fun.h


			

1voidFrqFun(void*param);

shell_fun.c

include "frq.h"

shell_cmd_list中添加一行


			

1{(constuint8_t*)"frt",FrqFun,"frq"},

添加命令执行函数


			

1voidFrqFun(void*param) 2{ 3Frq_main(); 4}

4.2.3实现代码

Frq.c


			

1#include"arm_math.h" 2#include"arm_const_structs.h" 3#include 4#defineTEST_LENGTH_SAMPLES2048 5#defineFS10000 6externfloat32_ttestInput_f32_10khz[TEST_LENGTH_SAMPLES]; 7staticfloat32_ttestOutput[TEST_LENGTH_SAMPLES/2]; 8staticuint32_tfftSize=1024; 9staticuint32_tifftFlag=0; 10staticuint32_tdoBitReverse=1; 11staticarm_cfft_instance_f32varInstCfftF32; 12staticinttestIndex=0; 13staticfloattesttmp_f32_10khz[2048]; 14staticint32_tadcbuffer[2048]; 15int32_tfrq_main(void) 16{ 17arm_statusstatus; 18float32_tmaxValue; 19status=ARM_MATH_SUCCESS; 20status=arm_cfft_init_f32(&varInstCfftF32,fftSize); 21//memcpy(testtmp_f32_10khz,testInput_f32_10khz,sizeof(testInput_f32_10khz)); 22adc_samp(adcbuffer,2048); 23for(inti=0;i<2048;i++) 24{ 25testtmp_f32_10khz[i]=(float)adcbuffer[i]; 26} 27arm_cfft_f32(&varInstCfftF32,testtmp_f32_10khz,ifftFlag,doBitReverse); 28arm_cmplx_mag_f32(testtmp_f32_10khz,testOutput,fftSize); 29/*CalculatesmaxValueandreturnscorrespondingBINvalue*/ 30arm_max_f32(testOutput,fftSize,&maxValue,&testIndex); 31floatfreq=(FS/TEST_LENGTH_SAMPLES)*testIndex; 32floatvpp=maxValue/(TEST_LENGTH_SAMPLES/2); 33floatpha=atan2(testOutput[2*testIndex],testOutput[2*testIndex+1]); 34printf("freq=%f,vpp=%f,pha=%f ",freq,vpp,pha); 35} 36/**endlink*/

Frq.h


			

1#ifndefFRQ_H 2#defineFRQ_H 3intfrq_main(void); 4#endif

4.2.4测试

输入frq开始测试印如下

wKgZomUt2q6AH1wDAAGub2QI3Y4534.png

实时采集测试

此时采集的是音频背景声,噪声很小,所以频率为0

wKgZomUt2q6AFsBLAAK8FKV37vk422.png

4.3数字滤波信号前端

4.3.1原理

CMSIS-DSP提供直接I型IIR库支持Q7,Q15,Q31和浮点四种数据类型。其中Q15和Q31提供了快速版本。

直接I型IIR滤波器是基于二阶Biquad级联的方式来实现的。每个Biquad由一个二阶的滤波器组成:

y[n] = b0 x[n] + b1 x[n-1] + b2 x[n-2] + a1 y[n-1] + a2 * y[n-2]

直接I型算法每个阶段需要5个系数和4个状态变量。

wKgZomUt2q6AM3PCAAD-eOvWUQ0445.png

matlab使用上面的公式实现,在使用fdatool工具箱生成的a系数需要取反才能用于直接I型IIR滤波器的函数中。

高阶IIR滤波器的实现是采用二阶Biquad级联的方式来实现的。其中参数numStages就是用来做指定二阶Biquad的个数。比如8阶IIR滤波器就可以采用numStages=4个二阶Biquad来实现。

wKgZomUt2q6ATa4qAABT1mUq6iM062.png

如果要实现9阶IIR滤波器就需要将numStages=5,这时就需要其中一个Biquad配置成一阶滤波器(也就是b2=0,a2=0)。

4.3.2添加命令行

shell_fun.h

void IirFun(void* param);

shell_fun.c


			

1include"iir.h"

shell_cmd_list中添加一行


			

1{(constuint8_t*)"iir",IirFun,“iir"},

添加命令执行函数


			

1voidIirFun(void*param) 2{ 3Iir_main(); 4}

4.3.3实现代码

Iir.c


			

1#include"arm_math.h" 2#include"arm_const_structs.h" 3#include 4#defineTEST_LENGTH_SAMPLES2048 5#defineFS10000 6externfloat32_ttestInput_f32_10khz[TEST_LENGTH_SAMPLES]; 7staticfloat32_ttestOutput[TEST_LENGTH_SAMPLES]; 8staticuint32_tfftSize=1024; 9staticuint32_tifftFlag=0; 10staticuint32_tdoBitReverse=1; 11staticarm_cfft_instance_f32varInstCfftF32; 12staticinttestIndex=0; 13staticfloattesttmp_f32_10khz[2048]; 14staticint32_tadcbuffer[2048]; 15#definenumStages2/*2阶IIR滤波的个数*/ 16#defineBLOCK_SIZE128/*调用一次arm_biquad_cascade_df1_f32处理的采样点个数*/ 17uint32_tblockSize=BLOCK_SIZE; 18uint32_tnumBlocks=TEST_LENGTH_SAMPLES/BLOCK_SIZE;/*需要调用arm_biquad_cascade_df1_f32的次数*/ 19staticfloat32_tIIRStateF32[4*numStages];/*状态缓存*/ 20/*巴特沃斯低通滤波器系数80Hz*/ 21constfloat32_tIIRCoeffs32LP[5*numStages]={ 221.0f,2.0f,1.0f,1.479798894397216679763573665695730596781f, 23-0.688676953053861784503908438637154176831f, 241.0f,2.0f,1.0f,1.212812092620218384908525877108331769705f, 25-0.384004162286553540894828984164632856846f 26}; 27int32_tiir_main(void) 28{ 29uint32_ti; 30arm_biquad_casd_df1_inst_f32S; 31float32_tScaleValue; 32float32_t*inputF32,*outputF32; 33/*初始化输入输出缓存指针*/ 34//memcpy(testtmp_f32_10khz,testInput_f32_10khz,sizeof(testInput_f32_10khz)); 35#if1 36adc_samp(adcbuffer,2048); 37for(inti=0;i<2048;i++) 38{ 39testtmp_f32_10khz[i]=(float)adcbuffer[i]; 40} 41#endif 42inputF32=testtmp_f32_10khz; 43outputF32=testOutput; 44/*初始化*/ 45arm_biquad_cascade_df1_init_f32(&S,numStages,(float32_t*)&IIRCoeffs32LP[0], 46(float32_t*)&IIRStateF32[0]); 47/*实现IIR滤波,这里每次处理1个点*/ 48for(i=0;i< numBlocks; i++) 49{ 50arm_biquad_cascade_df1_f32(&S,inputF32+(i*blockSize),outputF32+(i*blockSize), 51blockSize); 52} 53/*放缩系数*/ 54ScaleValue=0.012f*0.42f; 55/*打印滤波后结果*/ 56for(i=0;i57{ 58printf("/*%f,%f*/ ",testtmp_f32_10khz[i],testOutput[i]*ScaleValue); 59} 60} 61/**endlink*/

Iir.h


			

1#ifndefIIR_H 2#defineIIR_H 3intiir_main(void); 4#endif

4.3.4测试

输入iir回车,查看波形

见视频

以下可以看到滤波导致了滞后,黄色线有滞后

wKgZomUt2q6AZUffAABU0wp83P0878.jpg

wKgZomUt2q6ADlU-AAA7J-2D5i0757.jpg

以下是实时采集滤波

wKgZomUt2q6AX-oVAABCxtthyV8535.jpg

4.4 极大值检测

在电力等行业,分析电压极值,是一项重要的参数分析,可以分析电压的波动;示波器中也有自动测量极值的功能更。本板作为信号处理前端也实现了该功能。

4.4.1 算法

算法来源于论文https://www.mdpi.com/1999-4893/5/4/588/htm

核心代码如下


			

1voidampd(int32_t*data,int32_tlen) 2{ 3introw_sum; 4for(intk=1;k<len/2+1;k++) 5{ 6row_sum=0; 7for(inti=k;i<len-k;i++) 8{ 9if((data[i]>data[i-k])&&(data[i]>data[i+k])) 10{ 11row_sum-=1; 12} 13} 14arr_rowsum[k-1]=row_sum; 15} 16intmin_index=argmin(arr_rowsum,len/2+1); 17max_window_length=min_index; 18for(intk=1;k1;k++) 19{ 20for(inti=k;i<len-k;i++) 21{ 22if((data[i]>data[i-k])&&(data[i]>data[i+k])) 23{ 24p_data[i]+=1; 25} 26} 27} 28for(intk=0;k<len;k++) 29{ 30if(p_data[k]==max_window_length) 31{ 32/*极大值*/ 33} 34} 35}

4.4.2 添加命令行


			

1{(constuint8_t*)"max",MaxFun,"max"},/*打印帮助信息*/ 2voidMaxFun(void*param) 3{ 4max_test(); 5} 6voidMaxFun(void*param);

测试代码如下,串口命令行输入命令max,开始采集ADC值,并计算极值,打印到PC串口通过seraistudio可视化显示


			

1intmax_test(void) 2{ 3for(inti=0;i<10;i++) 4{ 5memset(p_data,0,sizeof(p_data)); 6//adc_samp(sim_data_buffer,1000); 7sim_data(); 8ampd(sim_data_buffer,sizeof(sim_data_buffer)/sizeof(sim_data_buffer[0])); 9for(intk=0;k<sizeof(sim_data_buffer)/sizeof(sim_data_buffer[0]);k++) 10{ 11if(p_data[k]==max_window_length) 12{ 13/*极大值*/ 14printf("/*%ld,%ld*/ ",sim_data_buffer[k],sim_data_buffer[k]); 15} 16else 17{ 18printf("/*%ld,%d*/ ",sim_data_buffer[k],0); 19} 20cyhal_system_delay_ms(10); 21} 22} 23return0; 24}

4.4.3 测试

效果如下IN是原始数据,MAX是检测到的极大值,如果检测极小值将原始数据取反即可。

wKgZomUt2q-AEzK0AABkghq9CX4766.jpg

wKgZomUt2q-AKWrGAABCqborvGI705.jpg

检测语音,效果如下

wKgZomUt2q-AH-RRAABPblN0HsA284.jpg

wKgZomUt2q-AC5nPAAA_Ym_aWb8479.jpg

五、总结


得益于开发板出色的处理性能,和外设性能,以及官方可视化的代码配置工具,可以方便的搭建开发环境,实现外设采集信号比如ADC,移植DSP库,实现各种算法。本Demo实现了谐波分析,周期幅值相位分析,数字滤波,极大值检测等功能,是一个小的工具集,还可以继续扩展,设计了人机交互命令行,方便实用和测试,具备一定实用价值。

———————End——————

wKgZomUt2rCAKQZiAHiX-BnG6Ho319.gif

点击阅读原文进入官网


原文标题:基于infineonPSOC62开发板的-信号处理前端 虚拟示波器-工具集

文章出处:【微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RT-Thread
    +关注

    关注

    31

    文章

    1151

    浏览量

    38916

原文标题:基于infineonPSOC62开发板的-信号处理前端 虚拟示波器-工具集

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    英飞凌PSoC™ 62开发板 -LCD ILI9341 8080 DEMO

    英飞凌开发板
    rx_ted
    发布于 :2024年03月07日 21:08:39

    虚拟示波器如何使用 虚拟示波器和数字示波器的区别

    虚拟示波器是一种基于计算机软件的虚拟仪器,用于显示和分析电子信号的形状、频率、幅度等特征。它的工作原理是将模拟信号通过采样和数模转换等
    的头像 发表于 01-23 14:14 311次阅读

    【米尔-TIAM62开发板-接替335x-试用评测】1、TIAM62的SoC架构

    处理器模组厂商,与TI再联手,推出基于TI-AM62x处理器的MYC-YM62X核心开发板
    发表于 01-05 20:25

    【核桃派1B 开发板试用体验】0基础小白该如何玩转LINUX开发板

    开发板,LINUX开发板的入门起点更高,基础知识更加丰富,当然可玩性也更多!但正是因为这样的特点,导致很多0基础小白用户刚拿到LINUX开发板时,感觉根本不知道从何学起,结果就是让
    发表于 01-02 16:32

    示波器如何处理有噪声的信号

    示波器如何处理有噪声的信号  示波器是一种用于测量和显示电信号的设备,可以帮助工程师和科学家分析和诊断电路故障。然而,在实际的测量中,
    的头像 发表于 12-21 15:37 570次阅读

    在使用AD9625的开发板时需要在前端加驱动电路或者驱动放大器吗?

    在使用AD9625的开发板时,还需不需要在前端加驱动电路或者驱动放大器?还有有没有合适的抗混叠滤波器适合AD9625开发板的,可以推荐一下吗?
    发表于 12-11 08:29

    【米尔-TIAM62开发板-接替335x-试用评测】+(三)手把手创建Uboot设备树与内核设备树实战

    接上两篇: 【米尔-TIAM62开发板-接替335x-试用评测】+(一)手把手配置Yocto - 米尔电子 【米尔-TIAM62开发板-接替335x-试用评测】+(二)配置U-Boot
    发表于 11-28 09:54

    【ELF 1开发板试用】+ 一款高效的学习开发工具

    ELF 1开发套件是一款面向学习者的开发板,它有丰富的学习资源,为使用者提供了一套便捷之路,从中可获得一个系统的学习机会,这是通常开发板所不具备的。 此外,ELF 1开发套件还是一个外
    发表于 11-20 19:26

    【米尔-TIAM62开发板-接替335x-试用评测】+(一)手把手配置Yocto

    -TIAM62开发板-接替335x时对Yocto Project进行硬件配置、镜像编译与测试的心得体会: Yocto Project,这是一个开源的嵌入式系统开发工具,用于构建定制的
    发表于 11-13 00:48

    开发板开发工具指南

    与使用开发环境相比,许多工程师更倾向于将调试点嵌入其代码并使用测试设备来验证其硬件。欧时电子指南将详述开发板开发工具的优势,并提供关于使用和选择恰当开发工具的实用建议。
    的头像 发表于 10-26 14:35 281次阅读

    #fpga开发板 Lattic-mipi开发板

    FPGA开发板
    明德扬科技
    发布于 :2023年10月25日 18:01:23

    虚拟示波器和数字示波器的区别是什么?

    虚拟示波器和数字示波器的区别。 一、虚拟示波器的工作原理 虚拟
    的头像 发表于 09-04 16:47 1434次阅读

    基于 Infineon PSoC™62开发板信号处理前端虚拟示波器-工具

    一、前言 本项目基于英飞凌PSoC6 RT-Thread开发板实现了信号处理前端-一个信号处理
    的头像 发表于 08-16 20:15 405次阅读
    基于 Infineon PSoC™<b class='flag-5'>62</b><b class='flag-5'>开发板</b>的<b class='flag-5'>信号</b><b class='flag-5'>处理</b><b class='flag-5'>前端</b><b class='flag-5'>虚拟</b><b class='flag-5'>示波器</b>-<b class='flag-5'>工具</b>集

    怎么设计一个基于PSoC™ 62开发板的龟龟智能水缸?

    主要设计一个系统,用于监测龟龟水缸的水质检测,PSoC™ 62开发板用于采集TDS传感器数据,通过外接鹅rw007网络模块发送至云端。
    的头像 发表于 07-18 17:02 914次阅读
    怎么设计一个基于PSoC™ <b class='flag-5'>62</b><b class='flag-5'>开发板</b>的龟龟智能水缸?

    虚拟示波器软件

    虚拟示波器软件是一种可以通过计算机、平板电脑或手机等移动设备上安装的软件来实现电信号检测和分析的工具。它主要用于获得各种电信号的波形图像,并
    发表于 06-19 18:20 18次下载