Scope and FFT on a PIC 18F14K22 in asm

Got it working.

Usin ga 8 bit sine table, doin ga 16 bits siged Hamming correction, doing mosty of teh FFT in 16 bits signed, and finally the root of teh sum of teh squares in 32 buits signed, to get iot all on a 64 pixles high display.

Fisrt Ithough 'FFT just for fun', but it is actually very accurate and allows you to measure the frequency and amplitude of individual components.

Some remarks for Microchip and their users: First Idid some looking on teh web for already existin gFFT coe. I found a person crying the Microchip application note did not work, and they had to BUY FFT code and lost 2 weeks of development time and pissed of a customer/ Now that was a challenge, so I decided to write my own FFT code. Had to modify the Microchip math libray so it could use signed and unsigned mixed, and used Peter Hemsley's 32 bit signed math routines for the final multiply and square root.

Peter's library does not use the hardware multiply the PIC has, and neitehr does my modified math library, so both will have to be rewritten (not today eeeek, used my calculator more in the last week then in the whole preceeding year). So what do we have: Well RAM is teh big limitation, not code space, I have not even filled half th3 code space! But 256 bytes continuous RAM, plus 96 bytes for variables, and one 32 bit variable takes 4 bytes... Where to store teh samples? Whre to store the Hamming modified samples? Sampels of a 10 bit ADC alo take 2 byets each... Anyways, working back from teh end result we have a 128 x 64 (or 64 x 128 if you libve on tha tsort of planet) LC>

So any frequency component lower the 1/64 of ful lscale wil ldisplay no pixel on thLCD, at least if yo uuse teh LCD horizonlat, as I do for the scope. So 128 samples (scope) fill a screen, OK all memory full! Part of that memory is also used to 'unplot' teh wave form for teh scope, so as to speed it up (clear screen beteen traces makes no sense). So I used those bytes twice (!LOL). Then did the Hamming, as now no unplot is needed in between displaying teh scope waveform and the FFT, I have 2 bytes signed for Hamming window corrected samples. Then as there is no need to store the FFT result in RAM, as it only needs to go to the LCD (with it's own RAM), and we calculate one spectral component at the time, that solves the memory problem. Not teh variable space problem, but I am stil lat 96 bytes, and knwo a few tricks so save some more vars. The resulting FFT is 64 wide on teh LCD, and is displayed for teh left half over the scope waveform picture, could clear that waveform, but it looks nice this way, and leaves speace on teh right side for displayin gamplitude and frequency of teh component a cursor is on (still have to write that part).

As the whole thing uses the PIC internal 16 MHz oscillator, multiplied by 4 wit ha PLL, stability (= accuracy) is a point. When sub-smapling a high frequency waveform I noticed the PLL is 'locked', but waves around teh centre frequency i nan amzing way! Yo udon not notice this alot on noraml sampling, but subsampin gincreases tha teffect by say 100x or 1000x and shows your waveform FM modulated... Anyways subsampling is an other chapter for some otehr time. The 18F14K22 does a 128 points FFT in about 1 second, inclusive display, whne not using the hardware multiplier it has. I did not try to optimise anything, except teh scope aquisition and trigger, so i am sure that speed could be improved.

Reply to
Jan Panteltje
Loading thread data ...

I have also done FFT in a micro. In my case it was an 8051.

A few tricks I picked up:

The DC and Nyquist part can be stripped out first. This reduces the number of bits and the number of values that you need to deal with in the main code.

For an FFT of length 256, the order reshuffle can be done quickly with a table that gives were to look for the number that makes a given result sent to the output.

Log2() makes a good stand in for dBs 77/256 is well with 1% of log10(2) so an integer convert comes out very exact.

A table lookup based mantissa part of the log2 is also way under

1% of error with just 128 16 bit values.
Reply to
MooseFET

On a sunny day (Fri, 26 Mar 2010 06:40:10 -0700 (PDT)) it happened MooseFET wrote in :

Yes, that is what I did, half the loop size :-) And I subtract the DC component, removes that big spike at zero...

Yes, I noticed that while coding, that some things could be done faster with a table lookup.

I will think about that, great info, thank you :-) I have just implemented a moving cursor so I can point to any point in the waveform (scope or fft) and display values at that point, It already displays to RS232, now to write the 32 bits number in ASCII to the LCD somewhere. Maybe better use 16 bits and use MHz and kHz etc, as the display is so small... Funny how this PIC FLASH code space never seems to get full.

Reply to
Jan Panteltje

.

If you know that there is a lot of one frequency in the information you can use the "not very bad fit" method to reduce that one part and then FFT what is left and correct the estimate of the one frequency. This works well for picking noise and distortion out of sine waves.

Basically:

NVBF =3D (max(X) - min(X))/2

for I =3D 0 to 255 X =3D X - NVBF * sin(B*I)

Y=3DFFT(X)

Y(BN) +=3D NVBF

Reply to
MooseFET

Well, besides stripping out the 180 deree points, the 90 degree points are next, then the 45 degree points (slight time savings on these).

Reply to
Robert Baer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.