硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
功能介绍
FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
代码实现了通过 Visual DSP++ 软件的 BTC(Background Telemetry Channels)功能进行后台监测,FFT 算法产生一个输入的波形数据,经计算后产生输出的波形数据,然后将输入和输出波形数据由 BTC 控制,通过视图实时输出显示。
调试步骤
- 按下图,选择“Restore”菜单。
-
在弹出会话框上找到工程路径下 fft_in.vps 文件,打开。
-
用同样的方法打开工程路径下 fft_out.vps 文件。
-
打开后在 Visual DSP++软件下可以看到两个波形窗口。
- 打开 BTC Memory 窗口
BTC Memory 窗口必须采用 AD-HP560ICE仿真器和 ADZS- HPUSB-ICE 仿真器时,才能使用。
AD-HP530ICE 仿真器不支持该功能,该选项为灰色。
- 打开后 BTC Memory 如图
- 选中 FFT OUT 波形视图框,按鼠标右键,选择“Auto Refresh Settings…”选项。
- 在弹出会话框中,按如下设置,完后后点“OK”
- 再次调出鼠标右键菜单,选择“Auto Refresh”
- 用同样的方法,对 FFT IN 波形视图框进行设置。
- 选中 BTC Memory 窗口,鼠标右键调出菜单,选择格式为“Hex32”
- 选中后 BTC Memory 窗口以 32bit 显示。
- 选中 BTC Memory 下拉菜单,选择“FREQ STEP SIZE”。
- 在下面的地址中输入 10~100 任意数据,来设置改变波形和数据刷新的频率。
- 编译并全速运行代码。
运行代码后,在两个波形窗口中可以看到变化的波形图像。
BTC 窗口检测到的 FFT_INPUT 的数据:
BTC 窗口检测到的 FFT_OUTPUT 的数据:
程序源码
#include <sys/exception.h>
#include <complex.h>
#include <filter.h>
#include <math.h>
#include <math_const.h>
#include <btc.h>
#define NUMPOINTS 512
complex_fract16 out[NUMPOINTS];
complex_fract16 w[NUMPOINTS]; //twiddle sequence
fract16 input_arr[NUMPOINTS];
fract16 mag[NUMPOINTS];
#define MINFREQ 100.0
#define MAXFREQ 20000.0
// BTC Definitions
fract16 BTC_CHAN0[NUMPOINTS+8];
fract16 BTC_CHAN1[NUMPOINTS+8];
int BTC_CHAN2 = 0x10;
BTC_MAP_BEGIN
// Channel Name, Starting Address, Length
BTC_MAP_ENTRY(“FFT_INPUT”, (long)&BTC_CHAN0, sizeof(BTC_CHAN0))
BTC_MAP_ENTRY(“FFT_OUTPUT”, (long)&BTC_CHAN1, sizeof(BTC_CHAN1))
BTC_MAP_ENTRY(“FREQ STEP SIZE”, (long)&BTC_CHAN2, sizeof(BTC_CHAN2))
BTC_MAP_END
// function prototypes
void initTimer(void);
void create_samples(float f);
/
// interrupt handler prototypes
/
EX_INTERRUPT_HANDLER(timerISR); // timer interrupt handler
void main()
{
int i,j;
int wst = 1;
int n = NUMPOINTS;
int block_exponent;
int scale_method = 1;
float freq;
btc_init();
// install our interrupt handlers
register_handler(ik_timer, timerISR);
//init twiddle factors
twidfftrad2_fr16(w, NUMPOINTS);
//increment freq
freq = MINFREQ;
create_samples(freq);
// initialize the timer and the programmable flags
initTimer();
while (1) {
//generate input
create_samples(freq);
//fft
rfft_fr16(input_arr, out, w, wst, n, &block_exponent, scale_method);
for (i=0; i<NUMPOINTS; i++) {
mag[i] = cabs_fr16(out[i]);
}
//write to BTC channel
btc_write_array(0, (unsigned int*)input_arr, sizeof(input_arr));
btc_write_array(1, (unsigned int*)mag, sizeof(mag));
freq += BTC_CHAN2;
if (freq > MAXFREQ) freq = MINFREQ;
}
}
void create_samples(float f)
{
int i,j;
float fs = 48000.0;
float step;
//generate input
for (i=0; i<NUMPOINTS; i++) {
step = (float)i/fs;
input_arr[i] = (fract16) (sin(2*PI*f*step)*32760.0);
}
}
//
// initTimer
//
void initTimer()
{
unsigned int *mmrPtr;
mmrPtr = (unsigned int*)0xffe03000; // timer control register
*mmrPtr = 5;
mmrPtr = (unsigned int*)0xffe03004; // timer period register
*mmrPtr = 0x00001000;
mmrPtr = (unsigned int*)0xffe03008; // timer scale register
*mmrPtr = 0x00000000;
mmrPtr = (unsigned int*)0xffe0300c; // timer count register
*mmrPtr = 0x00001000;
mmrPtr = (unsigned int*)0xffe03000; // timer control register
*mmrPtr = 7; // enable the timer
}
// timer interrupt handler
EX_INTERRUPT_HANDLER(timerISR)
{
btc_poll();
}