FFT Fast Fourier Transform algorithm suitable for single-chip microcomputer, 51 single-chip microcomputer can be used

Publisher:星际穿越Latest update time:2022-07-13 Source: csdnKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Source code

FFT.c

/************************************************************************

Fast Fourier Transform C package

Function Introduction: This package is a general fast Fourier transform C language function with strong portability. The following parts are not dependent on

This package uses a union to represent a complex number. The input is a complex number in natural order.

The input real number can make the complex imaginary part 0, and the output is the natural order of the FFT transformation.

Complex numbers. This package can call the create_sin_tab() function to create a sine function table during initialization.

In the future, the table lookup method can be used to calculate the sin and cos operations that take a long time to calculate, which can speed up the calculation speed.

Compared with Ver1.1, Ver1.2 only creates 1/4 of the sine wave sampling value when creating the sine table.

In comparison, it saves FFT_N/4 storage space

Instructions for use: To use this function, you only need to change the value of the macro definition FFT_N to change the number of points.

It should be 2 to the power of N. If this condition is not met, 0 should be added at the end.

cos value, you should call create_sin_tab() function to create a sine table before calling FFT function

Function call: FFT(Compx);

Author: Ji Shuaihu

Date: 2010-2-20

Version: Ver1.2

references:

**************************************************************************/

#include

#include "FFT.h"


struct compx Compx[FFT_N] = {0}; //FFT input and output: start from Compx[0] and define it according to the size

double SIN_TAB[FFT_N / 4 + 1]; //Define the storage space for the sine table


/*******************************************************************

Function prototype: struct compx EE (struct compx b1, struct compx b2)

Function: Multiply two complex numbers

Input parameters: two complex numbers a and b defined as a union

Output parameter: the product of a and b, output in the form of a union

***********************************************************************/

struct compx EE (struct compx a, struct compx b)

{

struct compx c;

c.real = a.real*b.real - a.imag*b.imag;

c.imag = a.real*b.imag + a.imag*b.real;

return(c);

}


/**************************************************************************

Function prototype: void create_sin_tab(double *sin_t)

Function: Create a sine sampling table with the same number of sampling points as the Foley transform points

Input parameter: *sin_t array pointer storing sine table

Output parameters: None

**********************************************************************/

void create_sin_tab(double *sin_t)

{

int i;

for (i = 0; i <= FFT_N / 4; i++)

sin_t[i] = sin(2 * PI*i / FFT_N);

}

/**************************************************************************

Function prototype: void sin_tab(double pi)

Function: Calculate the sine value of a number using a table lookup method

Input parameter: pi is the radian value of the sine value to be calculated, ranging from 0 to 2*PI, and needs to be converted if it does not meet the requirements

Output parameter: sine value of input value pi

**********************************************************************/

double sin_tab(double pi)

{

int n;

double a = 0;

n = (int)(pi*FFT_N / 2 / PI);


if (n >= 0 && n <= FFT_N / 4)

a = SIN_TAB[n];

else if (n>FFT_N / 4 && n {

n -= FFT_N / 4;

a = SIN_TAB[FFT_N / 4 - n];

}

else if (n >= FFT_N / 2 && n<3 * FFT_N / 4)

{

n -= FFT_N / 2;

a = -SIN_TAB[n];

}

else if (n >= 3 * FFT_N / 4 && n<3 * FFT_N)

{

n = FFT_N - n;

a = -SIN_TAB[n];

}


return a;

}

/**************************************************************************

Function prototype: void cos_tab(double pi)

Function: Calculate the cosine value of a number using a table lookup method

Input parameter: pi is the radian value of the cosine value to be calculated, ranging from 0 to 2*PI, and needs to be converted if it does not meet the requirements

Output parameter: cosine value of input value pi

**********************************************************************/

double cos_tab(double pi)

{

double a, pi2;

pi2 = pi + PI / 2;

if (pi2>2 * PI)

pi2 -= 2 * PI;

a = sin_tab(pi2);

return a;

}

/********************************************************************

Function prototype: void FFT(struct compx *xin)

Function: Perform fast Fourier transform (FFT) on the input complex array

Input parameter: *xin first address pointer of complex structure group, struct type

Output parameters: None

*********************************************************************/

void FFT(struct compx *xin)

{

register int f, m, nv2, nm1, i, k, l, j = 0;

struct compx u, w, t;


nv2 = FFT_N / 2; //Address operation, that is, changing the natural order into the reverse order, using the Reid algorithm

nm1 = FFT_N - 1;

for (i = 0; i < nm1; ++i)

{

if (i < j) //If i {

t = xin[j];

xin[j] = xin[i];

xin[i] = t;

}

k = nv2; //Find the next inversion sequence of j

while (k <= j) //If k<=j, it means the highest bit of j is 1

{

j = j - k; //Change the highest bit to 0

k = k / 2; //k/2, compare the second highest bit, and so on, compare one by one until a bit is 0

}

j = j + k; //Change 0 to 1

}


{

int le, lei, ip; //FFT operation core, use butterfly operation to complete FFT operation

f = FFT_N;

for (l = 1; (f = f / 2) != 1; ++l); //Calculate the value of l, that is, calculate the butterfly series

for (m = 1; m <= l; m++) // Control the number of butterfly knots

{   

//m represents the mth butterfly, l is the total number of butterfly levels l=log(2)N

le = 2 << (m - 1); //le butterfly knot distance, that is, the distance between the butterfly knot of the mth level butterfly and the point le

lei = le / 2; //The distance between two points in the same butterfly knot

u.real = 1.0; //u is the butterfly knot operation coefficient, the initial value is 1

u.imag = 0.0;

w.real = cos_tab(PI / lei); //w is the coefficient quotient, that is, the quotient of the current coefficient and the previous coefficient

w.imag = -sin_tab(PI / lei);

for (j = 0; j <= lei - 1; j++) //Control the calculation of different types of butterfly knots, that is, the calculation of butterfly knots with different coefficients

{

for (i = j; i <= FFT_N - 1; i = i + le) //Control the same butterfly knot operation, that is, calculate the butterfly knot with the same coefficient

{

ip = i + lei; //i, ip represent the two nodes participating in the butterfly operation

t = EE(xin[ip], u); //Butterfly operation, see the formula for details

xin[ip].real = xin[i].real - t.real;

xin[ip].imag = xin[i].imag - t.imag;

xin[i].real = xin[i].real + t.real;

xin[i].imag = xin[i].imag + t.imag;

}

u = EE(u, w); //Change the coefficient and perform the next butterfly operation

}

}

}

}


/********************************************************************

Function prototype: void Get_Result(struct compx *xin, double sample_frequency)

Function: Calculate the modulus of the transformed result, store the real part of the complex number, store the frequency in the imaginary part of the complex number, and the valid data is the first FFT_N/2 numbers

Input parameters: *xin first address pointer of complex structure group, struct type, sample_frequency: sampling frequency

Output parameters: None

*********************************************************************/

void Get_Result(struct compx *xin, double sample_frequency)

{

int i = 0;

for (i = 0; i < FFT_N / 2; ++i)

{          

//Find the modulus of the transformed result and store it in the real part of the complex number

xin[i].real = sqrt(xin[i].real*xin[i].real + xin[i].imag*xin[i].imag) / (FFT_N >> (i != 0));

xin[i].imag = i * sample_frequency / FFT_N;

}

}


/********************************************************************

Function prototype: void Refresh_Data(struct compx *xin, double wave_data)

Function: Update data

Input parameters: *xin first address pointer of complex structure group, struct type, id: label, wave_data: value of a point

Output parameters: None

*********************************************************************/

void Refresh_Data(struct compx *xin, int id, double wave_data)

{

xin[id].real = wave_data;

xin[id].imag = 0;

}


FFT.h

#ifndef FFT_H

#define FFT_H


#define FFT_N 16 //Define the number of points for Fourier transform

#define PI 3.14159265358979323846264338327950288419717 //define the value of pi


struct compx { double real, imag; }; //define a complex number structure


extern struct compx Compx[]; //FFT input and output: start from Compx[0] and define it according to the size

extern double SIN_TAB[]; //sine signal table


extern void Refresh_Data(struct compx *xin, int id, double wave_data);

extern void create_sin_tab(double *sin_t);

extern void FFT(struct compx *xin);

extern void Get_Result(struct compx *xin, double sample_frequency);


#endif


Instructions

Modify FFT_N 16 in FFT.h to define the number of Fourier transform points. After the FFT transform is normalized, the entire result table is symmetrical except for the DC component of 0Hz, that is, if the number of points is 16, we only need to look at the first 8 points. Therefore, the number of points of this Fourier transform can be determined according to the number of pixels in the long direction of your screen. For example, a 128x64 screen can consider using a 256-point FFT. Here I use an 8x8 LED dot matrix screen for display, so I use a 16-point FFT.


Before the operation, you need to call create_sin_tab(SIN_TAB) once to create a sine signal table. Then you will use the table lookup method to calculate the sine value to speed up the calculation.


After filling in data using the Refresh_Data (Compx, i, wave_data) function


Call FFT(Compx) to complete the transformation


Use the Get_Result (Compx, Sample_Frequency) function to find the modulus of the transformed result, store the real part of the complex number, and store the frequency in the imaginary part of the complex number. The valid data is the first FFT_N/2 numbers.

[1] [2]
Keywords:MCU Reference address:FFT Fast Fourier Transform algorithm suitable for single-chip microcomputer, 51 single-chip microcomputer can be used

Previous article:Precautions for using recursion on 51 MCU
Next article:[51 MCU Quick Start Guide] Simulation Example: Function Generator with Adjustable Amplitude and Adjustable Frequency

Recommended ReadingLatest update time:2024-11-17 00:40

Unveiling the circuit design of ARM single-chip ultrasonic monitoring and early warning system
  With the development of informatization, intelligence and networking, embedded system technology has gained a broad space for development, and the field of industrial control is also undergoing a huge change. Real-time embedded software and hardware technology based on 32-bit high-end processors will be applied in e
[Microcontroller]
Unveiling the circuit design of ARM single-chip ultrasonic monitoring and early warning system
Single-phase motor speed regulation method and its implementation based on single-chip microcomputer
0 Introduction   At present, the three-speed single-phase motor has a simple structure, low cost and convenient control. It enables the electric fan to have three speeds of high, medium and low, and improves the air supply quality of the electric fan. Therefore, this single-phase motor is widely used in household el
[Microcontroller]
Single-phase motor speed regulation method and its implementation based on single-chip microcomputer
Application of MCS-51 Single Chip Microcomputer and Wireless Modulator
GPS is the most mature and practical positioning system in technology. However, in the GPS positioning system, since it is a one-way navigation system, it transmits the ephemeris data to the ground receiver. In many specific applications, such as in the vehicle dispatch system, it is generally necessary to transmit
[Microcontroller]
Application of MCS-51 Single Chip Microcomputer and Wireless Modulator
#Microcontroller# Using pcf8591 to read the voltage value of the potentiometer
#include sbit sda=P2^0; sbit scl=P2^1; #define uint unsigned int #define uchar unsigned char uchar code table ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x40};   //Display codes of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, C, d, E, F   //--Define the read and write address of PCF8591--// #de
[Microcontroller]
Detailed explanation of 51 MCU infrared control decoding
The infrared remote control transmitter chip adopts PPM encoding. When the transmitter button is pressed, a set of 108ms encoding pulses will be emitted. The remote control encoding pulse consists of a preamble, an 8-bit user code, an 8-bit inverse code of the user code, an 8-bit operation code, and an 8-bit inverse c
[Microcontroller]
A high-speed communication scheme between DSP and single-chip microcomputer
This paper introduces a method of realizing high-speed data communication between DSP and single-chip microcomputer by using dual-port RAM, and gives the interface circuit and software implementation scheme between them. Keywords: DSP; dual-port RAM; interface circuit; data communication 1 Introduction Digital signal
[Embedded]
A high-speed communication scheme between DSP and single-chip microcomputer
Combination of TM1640 and PIC12F629 microcontroller
TM1640 is a dedicated integrated circuit for driving digital tubes. It can directly drive 16-bit common cathode digital tubes. Please download the attachment for the manual. /******************************* *This program directly drives 16-bit common cathode digital tubes, and each digital tube drives 0, 1, 2, ..., E
[Microcontroller]
51 MCU direct addressing mode and programming examples
Direct addressing means that the operand in the instruction is given directly in the form of unit address, that is, in this addressing mode, the operand item gives the address of the operand participating in the operation, rather than the operand. For example: in the instruction MOV A, 30H,   the operand is in unit 30
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号