📄 maxqfft.c
字号:
/*
********************************************************************
* maxqfft.c
*
* July 01, 2005
*
* Paul Holden (Paul_Holden@maximhq.com)
* Maxim Integrated Products
*
* SOFTWARE COMPILES USING IAR EMBEDDED WORKBENCH FOR MAXQ
*
* NOTE: All fft input/outputs are signed and in Q8.7 notation
*
* Copyright (C) 2005 Maxim/Dallas Semiconductor Corporation,
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM/DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim/Dallas Semiconductor
* shall not be used except as stated in the Maxim/Dallas Semiconductor
* Branding Policy.
*
********************************************************************
*/
// INCLUDE STATEMENTS ---------------------------
#include "iomaxq200x.h"
#include "maxqfft.h"
#include <intrinsics.h>
// DEFINE STATEMENTS ----------------------------
#define NOP __no_operation()
/*
* Windowing: Uncomment one of the following define
* statements to enable the corresponding windowing
* function on input samples. Comment all to disable
* windowing.
*/
//#define WINDOWING_HAMMING
//#define WINDOWING_HANN
/*
* x_n_re
*
* This array will store the FFT input samples, x(n),
* and the real part of the spectrum, X(n).
*/
__no_init int x_n_re[N];
/*
* tmp_32
*
* a union that allows accessing the individual 16-bit
* words of a 32-bit double word as well as the entire
* double word. This union is used by the multiplication
* macros that make use of the hardware multiplier and
* convert the multiplication result to Q8.7 notation.
*/
__no_init union
{
long tmp_32;
struct
{
int LSW; // Least Significant 16-bit Word
int MSW; // Most Significant 16-bit Word
} tmp_16;
};
/*
* Hardware Multiplier Macros
*
* These macros are used to access the hardware multiplier. For
* the MAXQ, registers MA and MB are the hardware multiplier
* operands while MC1:MC0 store the hardware multiplier result.
*
* (1) MUL_1(A,B,C) : C=A*B (result converted to Q8.7 notation)
* (2) MUL_2(A,C) : C=A*MB (result converted to Q8.7 notation)
* (3) MUL_INIT(B) : MB=B
* (4) MUL_NC(A,C) : C=A*MB (result not converted to Q8.7 notation)
*/
#define MUL_1(A,B,C) MA=A;MB=B; NOP; tmp_16.LSW=MC0; tmp_16.MSW=MC1; C=tmp_32>>7
#define MUL_2(A,C) MA=A; NOP; tmp_16.LSW=MC0; tmp_16.MSW=MC1; C=tmp_32>>7
#define MUL_INIT(B) MB=B
#define MUL_NC(A,C) MA=A; NOP; C=MC0
/*
* initADC()
*
* Initializes the ADC to send single channel 8-bit data to the
* MAXQ. Refer to the included circuit schematic for connection
* information.
*/
void initADC()
{
__no_init unsigned int i;
// Configure the MAXQ GPIO pins for a write to the ADC
// configuration register.
PD0 = 0xFF; PD1 = 0xFF; PD2 = 0x3F;
PO0 = 0x04; PO1 = 0x00; PO2 = 0xDF;
// Waste time to allow ADC to exit shutdown mode
for(i=0; i<2048; i++) __no_operation();
// Enable the ADC Channel 0
PO2_bit.bit2 = 0; NOP; // ADC /CS pin low
PO2_bit.bit1 = 0; NOP; // ADC /WR pin low
PO2_bit.bit1 = 1; NOP; // ADC /WR pin high
// Configure the MAXQ GPIO pins to read samples
// from the ADC
PD0 = 0x00; PD1 = 0x00;
PO0 = 0x00;
// Send dummy byte to ADC
PO2_bit.bit3 = 0; NOP; // ADC CONVST pin low
PO2_bit.bit3 = 1; NOP; // ADC CONVST pin high
while(!PO2_bit.bit7); // Wait for End-Of-Last-Conversion flag
PO2_bit.bit0 = 0; NOP; // ADC /RD pin low
PO2_bit.bit0 = 1; NOP; // ADC /RD pin high
PO2_bit.bit2 = 1; // ADC /CS pin high
}
/*
* getSamplesFromADC()
*
* Captures N 8-bit samples (in 2's complement format) from
* the ADC and stores them in the array x_n_re. If windowing
* is enabled, the data will be multiplied by the
* appropriate function.
*/
void getSamplesFromADC()
{
/* 1. Init variables */
__no_init unsigned int i;
int *ptr_x_n_re = x_n_re;
/* 2. Set ADC /CS pin low to enable interface */
PO2_bit.bit2 = 0;
/* 3. Capture 256 samples from the ADC. This loop does not include
any decision structure to ensure that the sampling rate is
consistent. Delays are also introduced to force a sampling
rate of 200ksps.
*/
for(i=0; i<256; i++)
{
/* 3.1. Acquire sample */
PO2_bit.bit3 = 0; // ADC CONVST pin low
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP; // Wait tacq
PO2_bit.bit3 = 1; // ADC CONVST pin high
/* 3.2. Wait for sample to convert */
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP; // Wait for tconv
/* 3.3. Read the sample from the ADC. Pointer notation instead
of array notation is used for x_n_re to increase sampling
speed.
*/
PO2_bit.bit0 = 0; // ADC /RD pin low
*(ptr_x_n_re++) = PI1; // Read sample
PO2_bit.bit0 = 1; // ADC /RD pin high
/* 3.4. Wait for 400nS. This will force a sampling rate of 200ksps */
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
}
/* 4. Set ADC /CS pin high to disable the ADC digital interface */
PO2_bit.bit2 = 1; // ADC /CS pin high
/* 5. Perform adjustments to samples:
- If the sample is negative (sign bit is 1), convert the
sampled byte to the corresponding negative 16-bit word
- Multiply sample by windowing function if enabled
*/
for(i=0; i<256; i++)
{
if (x_n_re[i]&0x0080)
x_n_re[i] += 0xFF00; // Convert to negative 16-bit word (2's comp)
#ifdef WINDOWING_HAMMING
MUL_1(x_n_re[i],hammingLUT[i],x_n_re[i]); // x(n) = x(n)*hamming(n);
#endif
#ifdef WINDOWING_HANN
MUL_1(x_n_re[i],hannLUT[i]),x_n_re[i]); // x(n) = x(n)*hann(n);
#endif
}
}
/*
* main()
*/
void main()
{
/* 1. Init ADC */
initADC();
/* 2. Init Serial Port */
PD7_bit.bit0 = 1; // Set TX0 pin as output
SCON0 = 0x42; //
SMD0 = 0x02; //
PR0 = 0x2F2F; // Set baud rate to 115200bps with fsysclk=20MHz
/* 3. Init Hardware Multiplier */
MCNT = 0x08; // Configure Hardware Multiplier for signed multiply
/* 4. FFT Loop */
while (1)
{
/* 4.0. Variable Declaration and Initialization */
__no_init unsigned int i; // Misc index
int n_of_b = N_DIV_2; // Number of butterflies
int s_of_b = 1; // Size of butterflies
int a_index = 0; // fft data index
int a_index_ref = 0; // fft data index reference
char stage = 0; // Stage of the fft, 0 to (Log2(N)-1)
__no_init int nb_index; // Number of butterflies index
__no_init int sb_index; // Size of butterflies index
int x_n_im[N] = {0x0000}; // Imaginary part of x(n) and X(n),
// initialized to 0 before every fft
/* 4.1. Get Input Samples from the ADC: Data will be stored in x_n_re */
getSamplesFromADC();
/* 4.2. Perform Bit-Reversal: Uses an unrolled loop that was created with
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -