FFT在单片机上的实现 下载本文

河南科技大学毕业设计(论文)

§3.3.1 LM324电压增益与偏移电路

本系统的信号输入来自数字音频播放器如PC机的声卡、MP3,或有源麦克风等有源设备,单声道输入。输入信号为均值为0,幅值为0.3V~1.5V的交流信号,由R?Chl输入。而进入单片机ADC模块的电压Vout要求0~Vcc,Vcc为USB供电的+5V。因此必须进行电压调理。整个系统采用单电源供电,所以无法对交流信号直接放大,必须先偏移再放大。该过程可由一个运算放大器来完成。运放选用LM324N,连线图如下:

图3-4 电压增益与偏移电路

这是一个同向加法电路,由模拟电路相关知识易得:

Vout?(1?V1VR7)(?2)((R2?R3)//R4//R5) R6R2?R3R4其中V1为R?Chl的输入信号,电压范围为?0.3V?1.5V,V2为偏移电压,由稳压二极管产生,其作用是使均值为0的交流音频信号偏移使全为正值。电阻

R2~R7的值的计算过程略,这里只对图中的数值进行验证。

当R?Chl输入电压为?0.3V时,应将放大倍数取最大,可变电阻R2取0,得:

Vout?(1?R7V1V2)(?)(R3//R4//R5)?0.8V R6R3R4当R?Chl的输入电压为?1.5V时,应将放大倍数取最小, 可变电阻R2取

10K?,得:

Vout?(1?V1VR7)(?2)((R2?R3)//R4//R5)?1.4V R6R2?R3R4可见电阻如图取值,当音频信号较大和较小时,都可以通过调节可变电阻R2来使采样达到较好的效果。

9

河南科技大学毕业设计(论文)

为使稳压管正常工作,稳压管的阴极应接在高于稳压管反向导通电压的位置。即有:

VR4?R5>D

R1?R4?R5Vcc将R4?51K?、R5?1.2K?、VD?3.3V、VCC?5V带入上式,得R1<K?,取R1=12K?。 §3.3.2 滤波电路

如果由于原信号频带很宽或采样频率fs选得太低,则频域中相邻周期的波形就会发生重叠,从而引起误差。这种现象称频率混叠,简称频混。

如果一个信号的频谱具有无限的带宽,则不论如何选择采样频率fs,频混误差都不可避免。然而这种信号并不多见,比较常见的是一个有用的低频信号混进了一个高频的噪声信号。因此在采样之前先用低通滤波器滤去高频噪声,这种低通滤波器称为抗混淆滤波器。在现代数字式分析系统中,它已被列为基本组成环节。抗混淆滤波器的截止频率选为fs/2。

由采样定理可知:对一个频率为0~fm的有限带宽连续信号进行采样,只有当采样频率fs?2fm时,其离散傅里叶变换才不会发生频率混淆,因而只有用这样采样的点才能得到离散信号的频谱。

人可感知的音频中多不超过12KHz,为了凸显低频声音信号的频谱变化,本系统只分析12KHz以下的音频信号。使用RC滤波器,当R8?1.2K?,截止频率

fs?12KHz时,电容值C1为:

C1?1?11(nF)

2?fs?R8取10nF。另外,单片机ADC输入的标准电路还要求加一个截止频率为3.2MHz的滤波器。总体滤波电路图如下:

图3-5 滤波电路

10

河南科技大学毕业设计(论文)

第4章 系统软件设计

§4.1 系统软件总体设计

该系统的软件需要完成控制ADC模块采样信号、对采集的数据计算、控制液晶显示屏显示三个任务。三个任务理论上应顺序运行,上一个任务完成后生成的数据交予下一个任务继续处理。但信号采样需要严格控制采样时间间隔,数据计算任务处理速度很快,而液晶显示的控制又会间隔较长时间。因此三个部分不能一个接一个运行。

程序还包括了各模块的初始化,总程序流程图如下:

图4-1 系统程序流程总图

本程序采用中断的方式,将需要定时的采样程序和显示程序分别放在两个中

11

河南科技大学毕业设计(论文)

断服务程序中,而主程序一直等待采样完成处理数据。数据的连接使用了两个全局变量数组。这样就使三个子程序在运行时,采样程序的采样时间间隔有了保障,而后两个子程序又始终有数据可以处理。

§4.2 系统软件详细设计

§4.2.1 系统的准备和初始化

Code代码段准备了一个32 个元素的nxd数组和一个8×8的User数组。定义如下:

unsigned char code nxd[32]=

{0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30, 1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31}; unsigned char code User[8][8]=

{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F}, {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}, {0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F}, {0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F}, {0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F}, {0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}};

nxd数组用于将32个采样点重新排列,其值为采样点重排的顺序。这将在下面的 §4.2.3蝶形运算的FFT算法 中详细介绍。User二维数组为液晶显示块的8种显示点阵的分布,这将在下面的 §4.2.4 显示子程序 中详细介绍。

main()函数的开始是一些初始化程序,这包括液晶显示屏的初始化、显示屏CGRAM的写入、ADC的初始化和定时器0的初始化。代码和注释如下:

LcdInt(); delay(15);

//调用LCD初始化函数,设置显示模式为:16×2显示,5×7点阵,8位数据接口,显示开,有光标,光标闪烁,光标右移,字符不移。并清屏。

CgInt(); delay(10);

//调用CgInt子函数,将User数组写入LCD1602的CGRAM中的0x10~0x17。

12