完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,首先抱歉,这是一个重复的话题,已经在论坛里搜索过了,我发现所有的解决方法都不起作用。我试着用CE018的FFT例子来确定一个信号的频率(对于DSPIC30F微控制器),但是我不能确定频率。信号是S。In波,具有2.5V偏移和5V振幅(所以它在0~5V之间振荡)。我试图检测频率在0~5KHZ之间。我的代码是休耕:那么,问题是什么呢?我似乎无法确定正确的频率,当我的信号有一个频率为500赫兹时,RD1在(当频率高于1500赫兹时应该只有一个),当我的频率是3000赫兹时,LED(RD0和RD1)在它们之间振荡(相同的情况发生在500赫兹频率),两者都是。LED正在开启,但在它们之间摇摆。任何帮助都将被感激。最好的问候
以上来自于百度翻译 以下为原文 Hi, first of all sorry if this is a repeated topic, already searched in the forum and all solutions that i found didn't work. I'm trying to determine the frequency of a signal, using the fft example of ce018 (for dspic30f microcontrollers), but i can't never determine the frequency. The signal is a sine wave, with 2.5V offset and 5V amplitude (so it oscillates between 0-5V). I'm trying to detect a frequency between 0-5kHz. My code is the fallowing: #include #include #define FFT_BLOCK_LENGTH 256 #define LOG2_BLOCK_LENGTH 8 #define SAMPLING_RATE 10000 unsigned long counter; fractcomplex sigCmpx[FFT_BLOCK_LENGTH] __attribute__ ((space(ymemory))); fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] __attribute__ ((space(xmemory))); fractional SquareMagnitude [FFT_BLOCK_LENGTH/2]; int peakFrequencyBin = 0; /* Declare post-FFT variables to compute the */ unsigned long peakFrequency = 0; /* frequency of the largest spectral component */ void start_timer(unsigned int time_value){ T1CONbits.TON = 0; TMR1 = 0; PR1 = time_value; T1CONbits.TON = 1; return; } fractional getADCValue(){ unsigned int ADCValue; ADCON1bits.SAMP = 1; while(!ADCON1bits.DONE); //checks if conversion is done ADCValue = ADCBUF0; return ADCValue - 16384; } void __attribute__((interrupt, no_auto_psv))_T1Interrupt(void){ if (counter < FFT_BLOCK_LENGTH){ sigCmpx[counter].real = getADCValue(); sigCmpx[counter].imag = 0; }else{ int i = 0; fractional *p_real = &sigCmpx[0].real ; fractcomplex *p_cmpx = &sigCmpx[0] ; fractional *p_fract = &sigCmpx[0].real ; for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )/* The FFT function requires input data */ { /* to be in the fractional fixed-point range [-0.5, +0.5]*/ *p_real = *p_real >>1 ; /* So, we shift all data samples by 1 bit to the right. */ *p_real++; /* Should you desire to optimize this process, perform */ } /* data scaling when first obtaining the time samples */ /* Or within the BitReverseComplex function source code */ p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real ; /* Set up pointers to convert real array */ p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ; /* to a complex array. The input array initially has all */ /* the real input samples followed by a series of zeros */ for ( i = FFT_BLOCK_LENGTH; i > 0; i-- ) /* Convert the Real input sample array */ { /* to a Complex input sample array */ (*p_cmpx).real = (*p_real--); /* We will simpy zero out the imaginary */ (*p_cmpx--).imag = 0x0000; /* part of each data sample */ } /* Perform FFT operation */ FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA); /* Store output samples in bit-reversed order of their addresses */ BitReverseComplex(LOG2_BLOCK_LENGTH, &sigCmpx[0]); /* Compute the square magnitude of the complex FFT output array so we have a Real output vetor */ SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real); sigCmpx[0].real = 0; sigCmpx[0].imag = 0; p_fract = &sigCmpx[0].real ; //inicia ponteiro for( i = 0; i < FFT_BLOCK_LENGTH/2; i++ ) { SquareMagnitude = *p_fract; *p_fract++; //incrementa o ponteiro } /* Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy*/ /* i.e., the largest spectral component */ VectorMax(FFT_BLOCK_LENGTH/2, &SquareMagnitude[0], &peakFrequencyBin); /* Compute the frequency (in Hz) of the largest spectral component */ peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LENGTH); //PWM(peakFrequency*0.00465); if(peakFrequency < 1500){ LATD = 0x0001; }else if(peakFrequency > 6000){ LATD = 0x0004; }else{ LATD = 0x0002; } counter = 0; } counter++; IFS0bits.T1IF = 0; return; } void time1_init(void){ T1CONbits.TCS = 0; T1CONbits.TGATE = 0; T1CONbits.TCKPS = 0; IPC0bits.T1IP = 5; IFS0bits.T1IF = 0; IEC0bits.T1IE = 1; start_timer(800); return; } void init_ADC(void){ ADCON1bits.ADSIDL = 0; //continues operation while microcontroller in idle(), 0 so it doesn't ADCON1bits.FORM = 3; //integer form, 1 for signed integer, 2 for fractional, 3 for signed fractional (sddd dddd dddd 0000) ADCON1bits.SSRC = 7; //7 for auto-convert, 0 for manual convert ADCON1bits.ASAM = 0; //0 for sampling begin when SAMP bit set, 1 for samp bit auto-step (start conversion after last one is finished) ADCON2bits.VCFG = 0; //which voltage references use for A/D ADCON2bits.CSCNA = 1; //0 to not scan inputs, 1 to scan inputs ADCON2bits.SMPI = 0; // ADCON2bits.BUFM = 0; ADCON2bits.ALTS = 0; ADCON3bits.SAMC = 1; ADCON3bits.ADRC = 0; ADCON3bits.ADCS = 21; ADCHS = 0; ADCSSL = 0x0001; ADPCFG = 0; IPC2bits.ADIP = 3; IEC0bits.ADIE = 0; IFS0bits.ADIF = 0; ADCON1bits.ADON = 1; //A/D module on, 0 for off return; } int main(void) { TwidFactorInit (LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0); init_ADC(); time1_init(); //time2_init(); //PWM_setup(); TRISB = 0x0001; //definir que portas sao input e output TRISD = 0x0000; counter = 0; while(1){ Idle(); } return 0; } So, what is the problem? I can't seem to be determining the right frequency, when my signal has a frequency of 500HZ, RD1 is on (which should only be on when frequency is higher than 1500Hz) and when my frequency is 3000Hz the leds (RD0 and RD1) are oscillating between them (the same happens for the 500Hz frequency), both leds are on, but oscillating between them. Any help would be appreciated. Best regards |
|
相关推荐
5个回答
|
|
尝试使用样本规范化。在我看来,右移位不是输入样本的适当操作。由于选定的格式,它会丢失样本的标志。尝试用2分部替换右移。这保留了样本标志,并使FFT结果正确。
以上来自于百度翻译 以下为原文 Try to play with sample normalization. It seems to me that right shift is not an appropriate operation for input samples. It looses the sign your samples have due to selected formatting. Try to replace the right shift by /2 division. This preserves the sample sign and will make the FFT result correct. |
|
|
|
是啊!我记得这个转变是这个例子的错误!它适用于方波示例,但不适用于其他信号。使用除法或无符号样本格式。
以上来自于百度翻译 以下为原文 Yeah! I did remember the shift was an error of this example! It works for square wave example, but not for another signals. Use division or unsigned sample format. |
|
|
|
删除代码的一部分,并将其改变为系统的稳定性有助于,但是仍然没有测量正确的频率(例如,当我使用700赫兹时,当频率大于1500赫兹时,LED是应该开启的,而在2个发光二极管中则是在67Hz。还有其他的想法或工作例子的FFT与ADC正在工作?最好的问候
以上来自于百度翻译 以下为原文 Removing that part of the code and changing it for the division helps in the stability of the system, but still, the correct frequency isnt being measured (for example, when i'm using 700Hz the LED on is the one that should be on when the frequency is higher than 1500Hz and, in the 657Hz the 2 leds are still oscillating). Do you have any other idea or an working example of the fft with adc that is working? Best regards |
|
|
|
1024个采样率为10KSPs的速率,作为FFT输入数据为1024SMP/10000 SPS=0.1024s。在700赫兹的输入频率,你的FFT得到700赫兹*0.1024s=这个频率的71.68个周期。应该足以检测到峰值在700赫兹/10000 SPS *1024SMP~72 bin。这个数字的bin,72,对应于你的代码中700赫兹的频率吗?这里也有过多的舍入误差:上面的操作是整数。所以10000/1024将被舍入到“9”。你会得到8.5%的错误。试着从频率术语转移到FFT-bin术语。I.e.then将峰值bin数与整数阈值进行比较。您确信采样信号在处理之前没有失真吗?您可以在1024个示例读取之后放置断点,并通过调试器工具读取缓冲区。在FFT示例之前,您需要检查信号。将变量显示为整数。此外,您可以将数据数组加载为CSV文件,并在电子表格中检查它的内容,甚至绘制时间图。至于最后一个问题。对。我有一个FFT的代码,它是按预期工作的。所有的转换,包括反向FFT。我已经成功地制作了一个具有时间匹配峰值搜索的交叉相关器。在一般情况下,它工作的一些注意事项的饱和度和量化。图书馆的程序是正确的。我看到了图书馆函数的解体。他们是专业创造的。一般情况下我不能做得更好。
以上来自于百度翻译 以下为原文 1024 samples at 10ksps rate you're taking as FFT input data are 1024smp/10000sps=0.1024s. This time interval without a window function you do analyze. At 700Hz input frequency your FFT gets 700Hz*0.1024s=71.68 periods of this frequency. Should be enough to detect a peak around 700Hz/10000sps*1024smp ~ 72 bin. Is the bin of that number, 72, corresponds the frequency of 700Hz in your code? Also here you have excessive rounding error: /* Compute the frequency (in Hz) of the largest spectral component */ peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LEe NGTH); The operation above is integer. So 10000/1024 will be rounded to "9". You will got 8.5% of error right there. Try to move from frequency terms into FFT bin terms. I.e. #define FreqThresHigh (int)(1500.0 / (float)SAMPLING_RATE * (float)FFT_BLOCK_LENGTH + 0.5) then compare peak bin number with that integer threshold. Are you sure your sampled signal is not distorted before the processing? You may place a breakpoint after 1024 samples reading and read the buffer by a debugger tool. You need to check the signal before claiming on the FFT example. Make the variable displaying as integer. Also you may load the array of data as a CSV file and check it contents in a spreadsheet, even to plot a time diagram. As for your last question. Yes. I have a code of FFT which is working as expected. All the conversions, including reverse FFT. I've successfully made a cross-correlator with time match peak searching. In general, it works with some precautions about the saturation and quantization. The library procedures are correct. I saw a disassembly of library functions. They are professionally-created. I can't do better for general cases. |
|
|
|
如果输入是一个在0~5V之间振荡的信号,你能不能把它通过一个10K电阻连接到一个数字输入管脚上?数字输入将正弦波转换成方波,然后你可以使用计时器来计算周期。
以上来自于百度翻译 以下为原文 If the input is a signal that oscillates between 0-5V, could you not just connect it to a digital input pin via a ~10K resistor? The digital input would convert the sine wave to a square wave, then you could use a timer to calculate the period. |
|
|
|
只有小组成员才能发言,加入小组>>
4814 浏览 9 评论
1823 浏览 8 评论
1743 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
2949 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2055 浏览 5 评论
452浏览 1评论
1107浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
355浏览 0评论
260浏览 0评论
LAN9252使用SQI通信,进行数字复位后读BYTE_TEST异常
1777浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-19 15:22 , Processed in 1.209279 second(s), Total 74, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号