FFT在单片机上的实现

更新时间:2024-05-08 02:17:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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

FFT在单片机上的实现

摘 要

音频信号分析仪是一种可广泛见于各种音响、调音和录音设备上的,能实时地采样及分析输入的音频信号的频谱,并将其显示在显示屏上的设备,使人在聆听音乐时能对音乐的高低频能有直观的了解。本文所介绍的即是这样一个音频信号分析系统。系统的硬件由信号调理、控制处理器、显示模块三部分组成。

信号调理电路使信号可输入300mV~3V的交流音频信号。这里只对单路信号处理:当电压较低时使用LM324运放获得增益,对超过12800Hz的信号进行滤波处理。另外设置输出音频接口以便监听。

控制处理器采用51内核1T单片机STC12C60A5S2,晶振频率为32.768MHz。该单片机自带8路10位高速ADC,这里只用1路ADC的高8位。对信号连续采32个点进行浮点型FFT运算。一次完整采样的时间为1.25ms,最高采样频率为25600Hz,分辨频率为800Hz~12800Hz,分16级。

显示部分主体为1602液晶显示屏,其具有2行×16列的8×5点显示点阵。16分频谱将分别以柱高形式显示在显示屏上。程序中设置了频率下落效果以使观感更好。另设置了对比度调节电阻,使屏幕对比度可调。

关 键 词:FFT 单片机 音频 频谱

I

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

THE REALIZATION OF FFT IN THE

MICROCONTROALER

ABSTRACT

Audio signal analyzer is a kind of device which can be widely found in various of audio, mixing and recording devices, and can sampling and analysis of the spectrum of the input have an intuitive audio signal and displays it on the display in real-time, people can are listening to Music for music when high frequency understanding. What presented in this article is just such an audio signal analysis system. The hardware of the system are formed with three parts: the signal conditioner, the control processor and the display module.

Signal conditioning circuit makes the signal of 300mV ~ 3V AC audio signal available for inputting. In this system,we only process with single-channel signal: When the voltage is lower the system uses LM324 op amp to gain voltage, and as to signals more than 12800Hz it filters them. In addition the system sets an output audio interface for monitoring.

The control processor of the system is the 51 cores 1T MCU STC12C60A5S2, with 32.768MHz crystal frequency. The device comes with 8-channel &10-bit high-speed ADC, where only one channel ADC high 8. The signal collected 32 points in consecutive floating-point FFT operation. A complete sampling time is 1.25ms, the maximum sampling frequency is 25600Hz, and the distinguish frequency is 800Hz ~ 12800Hz, with 16 levels.

The main display section is 1602 LCD screen, which has 2 rows × 16 columns - 8 × 5 dot display matrix. 16 points to the column height spectrum will be displayed on the display. The process of setting of the frequency drop in the perception of better effect. There is also contrast adjustment resistor, which makes the screen contrast adjustable.

KEY WORDS:FFT,MCU,AUDIO SPECTRUM

II

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

目 录

第1章 绪论 ...................................................................................... 1 §1.1 研究的背景及意义 ................................. 1 §1.1.1 课题研究背景 ................................ 1 §1.1.2 课题研究意义 ................................ 1 §1.2 课题发展的状况 ................................... 1 §1.3 设计任务 ......................................... 2 第2章 系统方案设计 ....................................................................... 3 §2.1 系统方案设计 ..................................... 3 §2.2 系统硬件的选择 ................................... 3 §2.2.1 处理器的比较与选择 .......................... 3 §2.2.2 采样模块的确定 .............................. 4 §2.2.3 显示器件的比较和选择 ........................ 4 第3章 系统硬件设计 ....................................................................... 5 §3.1 单片机STC12C5A60S2 ............................. 5 §3.1.1 单片机STC12C5A60S2功能简介 ................. 5 §3.1.2 单片机STC12C5A60S2引脚图 ................... 6 §3.1.2 单片机的最小系统 ............................ 6 §3.2 显示屏LCD1602 .................................. 7 §3.2.1 LCD1602简介 ................................ 7 §3.2.2 LCD1602的硬件连接 ......................... 8 §3.3.1 LM324电压增益与偏移电路 ................... 9 §3.3.2 滤波电路 ................................... 10 第4章 系统软件设计 ..................................................................... 11 §4.1 系统软件总体设计 ................................ 11 §4.2 系统软件详细设计 ................................ 12 §4.2.1 系统的准备和初始化 ......................... 12 §4.2.2 AD采样子程序 ............................. 13 §4.2.3 蝶形运算的FFT算法 ......................... 15

III

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

§4.2.4 显示子程序 ................................. 17 第5章 系统调试 ............................................................................. 20 §5.1 信号电压调试 .................................... 20 §5.2 单频率信号测试 .................................. 20 §5.2.1 实际频率分度测试 ........................... 21 §5.2.1 频率混叠和滤波效果 ......................... 22 §5.3 实际使用效果 .................................... 22 结 论 .............................................................................................. 24 参考文献 .......................................................................................... 25 致 谢 .............................................................................................. 26 附 录 .............................................................................................. 27 一、主程序代码 ...................................... 27 二、原理图 .......................................... 35

IV

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

第1章 绪论

§1.1 研究的背景及意义

§1.1.1 课题研究背景

在家庭影院、卡拉OK等音响系统中,实时显示音乐信号的频谱将为音响系统增不少色彩。目前实际生产的音响系统产品,大多采用以下两种方法实现音频频谱显示:一是利用硬件滤波器和A/D转换器;二是利用单片机或DSP处理频谱显示。前者实现简单,但硬件成本高;后者软件和硬件实现都较复杂。

§1.1.2 课题研究意义

目前,大多数音频信号处理仪不但体积大而且价格贵,在一些特殊方面难以普及使用,而嵌入式系统分析仪具有小巧可靠的特点,所以开发基于特殊功能单片机的音频信号分析仪器是语音识别的基础,具有很好的现实意义。

§1.2 课题发展的状况

早期专业的音频分析仪种类很少,在做音频测量时一般是利用万用电表、频率计、示波器及频谱仪等组合成一套音频测试系统。这种测试系统中间环节多,各环节之间接口匹配较为困难,使用起来比较麻烦,测量结果往往也不精确。

传统的频谱分析仪的前端电路是一定带宽内可调谐的接收机,输入信号经变频器变频后由低通滤器输出,滤波输出作为垂直分量,频率作为水平分量,在示波器屏幕上绘出坐标图,就是输入信号的频谱图。由于变频器可以达到很宽的频率,例如30Hz-30GHz,与外部混频器配合,可扩展到100GHz以上,频谱分析仪是频率覆盖最宽的测量仪器之一。无论测量连续信号或调制信号,频谱分析仪都是很理想的测量工具。但是,传统的频谱分析仪也有明显的缺点,它只能测量频率的幅度,缺少相位信息,因此属于标量仪器而不是矢量仪器。

近年来出现的音频分析仪器也与仪器的主流发展趋势一致,朝着高度集成化、

1

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

智能化的方向发展,这些仪器集成了复杂音频信号发生装置、功率放大装置等,具备了一些初步的图形化分析功能,使用户很容易组建音频测量系统。

基于快速傅里叶变换(FFT)的现代频谱分析仪,通过傅里叶运算将被测信号分解成分立的频率分量,达到与传统频谱分析仪同样的结果,。这种新型的频谱分析仪采用数字方法直接由模拟/数字转换器(ADC)对输入信号取样,再经FFT处理后获得频谱分布图。

在这种频谱分析仪中,为获得良好的仪器线性度和高分辨率,对信号进行数据采集时ADC的取样率最少等于输入信号最高频率的两倍,亦即频率上限是100MHz的实时频谱分析仪需要ADC有200MS/S的取样率。

目前半导体工艺水平可制成分辨率8位和取样率4GS/S的ADC或者分辨率12位和取样率800MS/S的ADC,亦即,原理上仪器可达到2GHz的带宽,为了扩展频率上限,可在ADC前端增加下变频器,本振采用数字调谐振荡器。这种混合式的频谱分析仪可扩展到几GHz以下的频段使用。

§1.3 设计任务

1、 完成信号电压调理电路和硬件的连接电路的设计。制作出硬件实物。 2、 ADC模块能正确采集到音频的完整波形,并保证一定的精度。

3、 学习频谱分析和傅里叶变换有关原理,使用FFT算法分析出当前音频的频谱。 4、 设计显示程序,使显示屏能实时地、以柱状图的形式将音频频谱显示出来,并有一定的美观效果。

2

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

第2章 系统方案设计

§2.1 系统方案设计

图2-1 系统总体方案

系统由信号调理电路、数模转换模块、主控制器、显示部件组成。信号调理电路主要负责对音频信号的电压进行变换,使其电压变化能正确地被数模转换模块采集。对信号的滤波处理也在这里进行。ADC模块将连续变化的电压值转化为单片机可识别的离散数字量。主控制器对采集的数据处理得到信号频谱,并控制显示屏将频谱实时显示出来。由于是对模拟信号的实时采集分析,本系统除了可应用于数码音乐播放器的音频谱显示,还可连接麦克风显示分析环境或人声音频谱。

§2.2 系统硬件的选择

§2.2.1 处理器的比较与选择

鉴于本次设计的学习目的,处理器选择最易操作的51内核的单片机。传统8051单片机以12个晶振周期作为一个机器周期,处理速度慢,内存较小,且在用到ADC时需要与ADC芯片通讯花费时间,因此舍弃传统8051单片机。

3

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

升级版的51内核单片机有STC12系列和Cygnal的C8051F系列待选。其中后者被誉为51系列最快单片机,内部有最高12位高速ADC和最高4K的RAM。但这款单片机价格较贵且仅有贴片形式的封装,调试困难。

STC的12系列单片机同样有较快的处理速度,内部有最高10位高速ADC和1280字节RAM。考虑到本次设计目的为普通的频谱分析器,且液晶显示屏整体刷新速度有100ms的瓶颈限制,这里采用双排插针封装的STC12C560S2单片机作为处理器。晶振使用单片机最高允许的32.768MHz晶振。 §2.2.2 采样模块的确定

由于单片机自带ADC转换模块,可以直接使用。内部ADC模块的采样速度高达250K/S,远高于音频最高频率20KHz的二倍。使用内部ADC模块还可以省去通信、存储等使用外部ADC芯片时的繁琐操作。因此确定使用单片机内部ADC模块作为采样模块。

§2.2.3 显示器件的比较和选择

常见的单片机操作的8位显示屏有1602和12864两种,均为单色显示屏。前者是分块显示的显示屏。每格块的像素点为8×5,共2行16列。后者12864为128×64个像素点的整块点阵显示屏,用于显示图形十分方便,但每次更新图形都需要整屏刷新,需要传输的数据量较大。综合考虑,采用1602作为显示设备。利用同列的两个显示块显示一个变化高度的亮柱来表示一个频率分量的幅值大小。

4

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

第3章 系统硬件设计

§3.1 单片机STC12C5A60S2

§3.1.1 单片机STC12C5A60S2功能简介

1. 增强型8051CPU,单时钟/机器周期,指令代码完全兼容传统8051 2. 工作电压:STC12C5A60S2系列工作电压: 5.5V - 3.5V(5V单片机) 3. 工作频率范围:0~35MHz,相当于普通8051的

0~420MHz

4. 用户应用程序空间8K /16K / 20K / 32K / 40K / 48K / 52K / 60K / 62K 5. 片上集成1280字节RAM

6. 通用I/O口(36/40/44个),复位后为:准双向口/弱上拉(普通8051传统I/O口)可设置成四种模式:准双向口/弱上拉,强上拉,仅为输入/高阻,开漏上拉,仅为输入/高阻,开漏上拉,仅为输入/高阻,每个I/O口驱动能力均可达到20mA,但整个芯片最大不要超过120mA

7. ISP (在系统可编程)/ IAP(在应用可编程),无需专用编程器,无需专用仿真器可通过串口(P3.0/P3.1 )直接下载用户程序。

8. 有EEPROM功能(STC12C5A62S2/AD/PWM无内部EEPROM) 9. 看门狗

10. 内部集成MAX810专用复位电路(外部晶体12M以下时,复位脚可直接1K电阻到地)

11. 外部掉电检测电路:在P4.6口有一个低压门槛比较器 5V单片机为1.33V,误差为±5%,3.3V 单片机为1.31V,误差为±3%

12. 时钟源:外部高精度晶体/时钟,内部R/C振荡器(温漂为±5% 到±10%以内)用户在下载用户程序时,可选择是使用内部R/C

振荡器还是外部晶体/时

钟常温下内部R/C振荡器频率为:5.0V单片机为: 11MHz ~ 17MHz单片机为: 8MHz~12MHz。精度要求不高时,可选择使用内部时钟,但因为有制造误差和温漂,以实际测试为准 。

13. 共4个16位定时器,两个与传统8051兼容的定时器/计数器,16位定时器

5

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

T0和T1,没有定时器2,但有独立波特率发生器做串行通讯的波特率发生器,再加上2路PCA模块可再实现2个16位定时器

14. 3个时钟输出口,可由T0的溢出在P3.4/T0输出时钟,可由T1的溢出在P3.5/T1输出时钟,独立波特率发生器可以在P1.0口输出时钟

15. 外部中断I/O 口7路,传统的下降沿中断或低电平触发中断,并新增支持上升沿中断的PCA模块。16. PWM (2路)/ PCA (可编程计数器阵列,2路)也可用来当2路D/A使用,也可用来再实现2个定时器,也可用来再实现2个外部中断(上升沿中断/下降沿中断均可分别或同时支持)

17. A/D转换, 10位精度ADC,共8路,转换速度可达250K/S

18. 通用全双工异步串行口(UART),由于STC12系列是高速的8051,可再用定时器或PCA软件

19. STC12C5A60S2系列有双串口,后缀有S2标志的才有双串口,RxD2/P1.2 (可通过寄存器设置到P4.2),TxD2/P1.3 (可通过寄存器设置到P4.3)

20. 工作温度范围:-40 ~ +85℃(工业级) /0 ~ 75℃(商业级) 21. 封装: PDIP-40

§3.1.2 单片机STC12C5A60S2引脚图

图3-1 STC12C5A60S2引脚图

§3.1.2 单片机的最小系统

STC12C60S2最高支持33MHz的晶振,为使单片机处理数据的速度尽量快,

6

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

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

§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

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

P1ASF = 0x06;

//P1.1 P1.2口作为AD输入,P1.1作为今后可能开发双通道分析的保留。 AUXR1&= 0xfb;

//ADRJ=0,10位ADC的高8位放在ADC_RES中,后续将不再用低2位。 EADC=1;

//开AD中断 //启动ADC转换

//T0x12=1,定时器0以12倍速运行 //定时器0工作在方式1

ADC_CONTR=0x8a; NOP5; AUXR = 0x80; TMOD = 0x01; TL0 = T1MS; TH0 = T1MS>>8; TR0 = 1; ET0 = 1; EA = 1;

//定时器0赋初值 //开定时器0中断 //定时器0启动 //开总中断

§4.2.2 AD采样子程序

AD采样的数据将反映信号的频率,因此AD采样的间隔必须保证。有两种方案来保证时间间隔:使用高中断优先级的定时器或直接连续采样,靠ADC自己的采样延时来控制时间间隔。定时器控制看似更加准确,但ADC的采样延时仍存在,实际每两采样点的时间间隔=定时器延时时间?两次ADC采样延时时间之差。若ADC采样延时时间有误差,以这种方式定时的误差仍存在,且程序结构复杂,编写困难。

实际上,STC12C5A60S2单片机对模数转换速度已经有了很好的控制。本程序拟使用单片机数模转换的转换时间来控制采样速率,而不再使用另外的定时器。程序流程图如图:

13

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

图4-2 AD采样子程序流程图

STC12C5A60S2单片机对模数转换速度由AUXR1中的SPEED1、SPEED0两位控制。速度定义如表:

表4-1 STC12C5A60S2数模转换速度控制位

SPEED1 1 SPEED0 1 A/D转换所需时间 90个时钟周期转换一次,CPU工作频率21MHz时,A/D转换速度约250KHz 1 0 0

0 1 0 180个时钟周期转换一次 360个时钟周期转换一次 540个时钟周期转换一次 当SPEED1=0,SPEED0=0,fsoc=32MHz时,采样时间间隔td有:

14

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

td?540?16.9(us) fsoc采样的信号的最高频率分量fh有:

fh?1?29KHz 2?tdfh高于音频最高频率22KHz。由于人可感知的音频中多不超过12KHz,若隔点采样,则fh变为:

fh?1?15KHz 2?2td定采样点数为32个点,则通过FFT变换可将原信号变为16个频率分量相加(采样点数的确定和FFT结果的解释见下节)。最小频率分量为940Hz。

采样过程并未关断定时器0中断,因此采样过程会被打断。但定时器0的溢出间隔较长(5ms),期间可进行很多次完整的32点采样。只有当32个点是连续采样并被移出时,主循环中的数据处理函数才开始运行。 §4.2.3 蝶形运算的FFT算法

FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。

设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次复数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT变换大约就需要N^2次运算。当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。这样变换以后,总的运算次数就变成N+2*(N/2)^2=N+N^2/2。继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算

15

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

单元,那么N点的DFT变换就只需要Nlog2N次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。

2点DFT运算称为蝶形运算,而整个FFT就是由若干级迭代的蝶形运算组成,而且这种算法采用原位运算,故只需N个存储单元

×1X1(k)×1×1k×WNkX(k)?X1(k)?WNX2(k)X2(k)×(-1)X(Nk?k)?X1(k)?WNX2(k)2

图4-3 蝶形运算单元

图4-3是FFT频域抽取算法的基本运算单元,一般称为蝶形运算.下一步再将X(4m+i),i=0,1,2,3分解成4个N42序列,迭代r次后完成计算,整个算法的复杂度减少为O(Nlog4N)

上诉结论可以推广到N点的一般情况,规律是第一列只有一种类型的蝶形运算,系数是 ,以后每列的蝶形类型,比前一列增加一倍,到第是N/2个蝶形类型,系数是,共N/2个。由后向前每推进一列,则用上述系数中偶数序号的那一半,例如第列的系数则为参加蝶形运算的两个数据点的间距,则是最末一级最大,其值为N/2,向前每推进一列,间距减少一半。

对N = 2L点FFT,共需L级蝶形运算,每级有N/2个蝶形运算组成,蝶形运算两节点的距离:2L-1(L表示级数)每个蝶形运算有一次复乘和2次复加。如

第L级的系数因子为(L?1,2,3...M)W2JL,J?0,1,2.......2L?1?1即第L级的蝶形运算系数因子类型数为2L?1个,如N=8,共有M?3级JJ2第一级20个为:W2J1?WM1?M?WM222M-LM?1L?1,J?00?WN0?W?N;L?2,J?0第二级21个为:WNJ2=?2??WN;L?2,J?10?WN;L?3,J?0?1M-L?WN;L?3,J?1第三级22个为:WNJ2=?2?WN;L?3,J?2?W3;L?3,J?3?N16

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

图4-4 8点FFT运算示意图

本程序每次采样32个点,进行32点FFT运算。限于篇幅不再画出32点FFT运算图。程序用排好的32个序号来重排采集到的32个信号点。运算时的复数用结构体存储和表示。具体运算程序见附录。 §4.2.4 显示子程序

由信号处理的相关知识知,非周期信号的频谱图为连续函数。声音信号显然为非周期信号,但在单片机内,频谱只能表示为离散且成倍的频率分量。本系统将每个频谱分量以亮柱的高度形式显示在显示屏上。

LCD1602一般只能显示CGROM内的160个字符,不能显示图形。要显示不同高度的立柱,只能编辑CGRAM。在程序初始化阶段,已将CGRAM的0x10~0x17的用户自定义位置写入如下图形:

17

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

图4-5 1602字符空间(字库)图

当需要在第p列显示高为l的亮柱时,先对LCD写入p列第二行的地址,若l<8,就在这个位置调取CGRAM中0x10~0x16对应高度的图形(当l=0时调取0x20显示空格),若l≥8,则在p列第二行显示0x17全亮图后,在第p列第一行显示高度为l-8的亮柱。这样就实现了以亮柱高度直观展示频率分量幅值的目的。

为了获得更好的视觉感受,显示程序还加入了频谱亮柱缓慢下落的动画效果。做法为:当本次计算的的频率幅值大于等于上次的幅值时,立即更新此幅值以待显示。若本次计算的频率幅值小于上次的幅值时,只将上次的幅值减1显示。如此就会使得亮柱可以突然升高,却只能缓慢下落。这符合了人对突然增强的事件敏感而对突然减弱的事件不敏感的感受。

由LCD1602的资料知,控制一个亮块需要有写地址和写数据两步操作,且间隔的典型时间为5ms。整屏刷新一次需要经历32?2?5ms?320ms。若计算出16个频率分量幅值后统一显示,则信号采集后至少要经过320ms才能看到结果,实时性太差。本程序利用定时器,采用了显示与频谱计算工作交替处理的方式,即:

18

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

在两次写1602的等待过程中进行采样和计算工作,每次对1602的同列两个亮块操作时,取到的数据都是刚刚计算好的数据。这样就使得屏幕上每隔

2?2?5ms?20ms都会有一个亮柱显示新的数据。程序流程图如下:

图4-6 显示子程序流程图

显示程序见附录。

19

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

第5章 系统调试

§5.1 信号电压调试

根据§3.3.1 的设计,为了达到最好的采样效果,需要根据信号的幅值调节可变电阻R2,使输入的信号在0~Vref中能有较大的变化。编写调试程序,使显示屏显示出一段时间内(1s左右)从P1.2脚输入的信号电压最大值,以VP1.2/Vref?255表示。调试过程为:将系统输入连接PC机的声卡,输出端连接耳机,PC机播放音乐并调到合适的音量。然后调整R2阻值,使显示屏显示到一个200左右的数值。如屏幕显示值为191,在无信号输入时显示为100,则交流的信号在输入单片机以后就变成了9~191,以100为均值的数据。这里需要说明的是,FFT变换的交流部分并不会因信号的均值不同而不同,所以无信号时的输入值并不需引入FFT计算中。

图5-1 电压调试

§5.2 单频率信号测试

调整好信号电压后,使用虚拟仪器v0.94,使声卡发出特定频率的正弦波对系统性能进行测试。

20

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

§5.2.1 实际频率分度测试

在§4.2.2小结中计算得系统能识别的最小频率分量为940Hz。实际测试中,当发生800Hz的正弦信号时,屏幕的第一个亮柱显示满幅值,第二个和以后的分量基本不显示。如果再调低频率,第一亮柱高度会下降;调高频率,第一亮柱下降的同时第二格也会有了幅值。因此可以确定该系统实际频率分度,也即最小能识别的频率分量为800Hz。

图5-2 800Hz正弦波显示效果

将频率调高3倍和10倍屏幕显示的情况如下:

图5-3 2400Hz正弦波显示效果

图5-4 8000Hz正弦波显示效果

该系统在采样后并没有进行特殊的加窗处理,理论上会造成频谱泄露,即最后计算结果在主频率的两侧也有较小的幅值。但从上面的结果来看,频谱泄露的现象并不很明显,为了节省计算量,不再加特别的窗函数。

21

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

附 录

一、主程序代码

#include #include #include

#define NOP5 _nop_();_nop_();_nop_();_nop_();_nop_()

#define FOSC 32782266L #define NMS 4

#define T1MS (65536-NMS*FOSC/12/1000)

sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚 sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚 sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚 sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚

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}};

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 data1[32];

struct complex{float re,im;}; struct complex data2[32];

27

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

unsigned char frq1[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; unsigned char frq2[16]=

{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}; unsigned char p=0;unsigned char l; unsigned char lcd_flag=0; unsigned char count=10; bit AD_flag=0;

unsigned char point=0; unsigned char temp;

/*********************函数功能:延时1ms*********************/ void delay1ms()

{ unsigned char i,j; for(i=0;i<12;i++) for(j=0;j<30;j++); }

/*******************函数功能:延时若干毫秒********************/ void delay(unsigned int n) { unsigned int i; for(i=0;i

/*****************函数功能:判断液晶模块的忙碌状态**************/ bit BusyTest(void) {

bit result;

RS=0; // RS为低电平,RW为高电平时,可以读状态 RW=1;

E=1; //E=1,才允许读写 }

NOP5; //空操作 NOP5; NOP5;

NOP5; //空操作四个机器周期,给硬件反应时间 result=BF; //将忙碌标志电平赋给result E=0;

return result;

28

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

/****************函数功能:将控制字写入液晶模块****************/ void Write_com (unsigned char dictate) {

while(BusyTest()==1); //如果忙就等待

RS=0; // RS和R/W同时为低电平时,可以写入指令 RW=0;

E=0; //写指令时,让E从0到1发生正跳变 NOP5;

NOP5; //空操作两个机器周期,给硬件反应时间 P0=dictate; //将数据送入P0口,即写入指令或地址 NOP5;

NOP5; NOP5; NOP5; E=1; NOP5; NOP5; NOP5; NOP5; E=0;

//空操作四个机器周期,给硬件反应时间 //E置高电平

//空操作四个机器周期,给硬件反应时间

//当E由高电平跳变低电平时,液晶开始执行命令

}

/****************函数功能:指定字符显示的实际地址***************/ void WriteAddress(unsigned char x) {

Write_com(x|0x80); //显示位置的确定方法规定为\地址码x\ }

/*********函数功能:将数据(字符的标准ASCII码)写入液晶模块********/ void WriteData(unsigned char y) {

while(BusyTest()==1);

RS=1; RW=0; E=0; P0=y; NOP5; NOP5; NOP5; NOP5;

//RS为高电平,RW为低电平时,可以写入数据 //写指令时,让E从0到1发生正跳变

//将数据送入P0口,即将数据写入液晶模块

//空操作四个机器周期,给硬件反应时间

29

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

E=1; //E置高电平

NOP5; NOP5; NOP5;

NOP5; //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变低电平时,液晶开始执行命令 }

/***********函数功能:对LCD的显示模式进行初始化设置*************/ void LcdInt(void) { delay(15); //延时15ms,给LCD一段较长的反应时间 Write_com(0x38); delay(5); Write_com(0x38); delay(5);

Write_com(0x38); delay(5);

Write_com(0x0C); delay(5);

Write_com(0x06);

//显示模式:16×2、5×7点阵,8位数据接口 //延时5ms

//3次写 设置模式

//显示模式设置:显示开,有光标,光标闪烁 //显示模式设置:光标右移,字符不移

delay(5);

Write_com(0x01); //清屏幕指令,将以前的显示内容清除 delay(5); }

/****************函数功能:将User的字模写入CGRAM*************/ void CgInt(void)

{unsigned char i,j,org; delay(50);

for(i=0;i<8;i++) {

org=0x40|(i*8);

Write_com(org); //设定CGRAM地址 delay(5);

for(j=0;j<8;j++)

{WriteData(User[i][j]); //写入自定义图形 delay(5); } } }

30

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

/********函数功能:频谱回落一格(操作全局变量frq1,frq2)**********/ void frqfall(void) {

unsigned char i; if(count==0)

{for(i=0;i<16;i++) if(frq2[i]!=0) frq2[i]--; count=10;} count--;

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

if(frq1[i]>16) frq2[i]=16;

else if(frq1[i]>frq2[i]) frq2[i]=frq1[i]; }

/**************函数功能:在第p位显示高为l的柱子****************/ void disp(void) interrupt 1 {

AD_flag=1; //把AD状态转为打断

switch(lcd_flag) //0~3,上地址 上数据 下地址 下数据 {case 0:

{frqfall(); if(p==16) p=0;

l=frq2[p]; //从frq2中取l,更新p

WriteAddress(0x00+p); lcd_flag++; break;

} case 1:

{if(l>8)

WriteData(l-9); else

WriteData(0x20); lcd_flag++; break;

31

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

}

case 2:

{WriteAddress(0x40+p); lcd_flag++; p++; break; } case 3:

{if(l==0)

WriteData(0x20); else if(l>8) WriteData(0x07); else

WriteData(l-1); lcd_flag=0; break; } }

TL0 = T1MS; TH0 = T1MS>>8;

//下面满上

}

/*******************函数功能:求两个复数的积 ******************/ struct complex productComplex(struct complex complex1,struct complex complex2) {

struct complex Node;

Node.re=complex1.re*complex2.re-complex1.im*complex2.im; Node.im=complex1.im*complex2.re+complex2.im*complex1.re; return Node; }

/***********函数功能:对data1的数据fft运算后放入frq1**********/ void fftgo(void) {

unsigned char i,ii,j,k,kp,p,mm,Nz; struct complex WN,u,t; for(p=0;p<32;p++) { i=nxd[p];

32

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

data2[p].re=data1[i];

data2[p].im=0;} for(mm=0;mm<5;mm++) { Nz=pow(2,mm+1); u.re=1;u.im=0;

WN.re=cos(-2*3.1416/Nz); WN.im=sin(-2*3.1416/Nz); for(j=0;j

{ for(k=j;k<32;k=k+Nz) { kp=k+Nz/2;

t=productComplex(data2[kp],u); data2[kp].re=data2[k].re-t.re; data2[kp].im=data2[k].im-t.im; data2[k].re=data2[k].re+t.re; data2[k].im=data2[k].im+t.im; }

u=productComplex(u,WN); }

}

for(ii=0;ii<16;ii++)

frq1[ii]=sqrt(data2[ii+1].re*data2[ii+1].re+data2[ii+1].im*data2[ii+1].im)/4; }

/************函数功能:AD采样32个点,放入data1中***************/ void AD_res(void) interrupt 5 {

if(!(point%2)) temp=ADC_RES; else }

data1[point/2]=(ADC_RES+temp)/2; point++;

if(point==64) {point=0; AD_flag=1; }

33

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

/**************************主函数**************************/ void main(void) {

LcdInt(); delay(10); CgInt(); delay(10);

P1ASF = 0x0x06; AUXR1&= 0xfb; EADC=1;

PADC=1;

ADC_CONTR=0x8a; NOP5;

AUXR = 0x80; TMOD = 0x01; TL0 = T1MS; TH0 = T1MS>>8; TR0 = 1;ET0 = 1;

EA = 1; while(1) {

if(AD_flag) {fftgo(); AD_flag=0; } } }

//调用LCD初始化函数

//P1.1 P1.2口作为AD输入

//11111011 ADRJ=0,高八位放在ADC_RES中

//AD、定时器初始化 //开总中断 34

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

二、原理图

图 附-1 系统原理总图

35

本文来源:https://www.bwwdw.com/article/ovog.html

Top