您好,欢迎来到星星旅游。
搜索
您的当前位置:首页基于单片机的音频频谱显示器设计

基于单片机的音频频谱显示器设计

来源:星星旅游
如果您需要使用本文档,请点击下载按钮下载!

目 次

1 绪论-----------------------------------------------------------1 2 系统功能-------------------------------------------------------1 3 系统设计-------------------------------------------------------2 3.1 主控单元----------------------------------------------------2 3.2 STC12C5A60S2 系列单片机单片机的A/D转换器-------------------10 3.3 STC12C5A60S2 系列单片机单片机的I/O口结构-------------------11 3.4 频谱显示单元-----------------------------------------------14 4 音频频谱显示相关问题-------------------------------------------16 4.1 频谱及频谱显示---------------------------------------------16 4.2 FFT运算规则及编程思想--------------------------------------17 5 总结-----------------------------------------------------------22 参考文献-------------------------------------------------------24 致谢-----------------------------------------------------------23 附录A 源程序-------------------------------------------------25 附录B 系统电路图---------------------------------------------32

如果您需要使用本文档,请点击下载按钮下载!

1 绪论

随着电子技术的进步发展在功率放大器的设计上功能也不断更新。电子信息技术几乎主宰了整个电器行业的发展。

我们知道,一切声音都是由振动产生的。声音之所以千变万化各不相同,是因为它们的振动各不相同。产生音调高低的不同,是由于振动的频率不同。频率越高,音高也就越高。根据傅立叶分析,任何声音可以分解为数个甚至无限个正弦波,而它们往往又包含有无数多的谐波分量。而它们又往往是时刻在变化着。所以一个声音的构成其实是很复杂的。将声音的频率分量绘制成曲线,就形成了频谱。

本设计通过STC12C5A60S2单片机及外围器件组成的系统实现音频信号的频谱显示,将音频信号送入STC12C5A60S2单片机的A/D转换接口进行数据的采集和预处理, 然后送入单片机中通过编程实现频谱计算,在LCD1604上实时显示音频信号的频谱。

2 系统功能

图2.1为系统整体设计原理图

音频信号 数据采集,A/D转换 FFT算法计算频谱值 频谱显示电路 图2.1 系统整体设计原理图

本设计以STC12C5A60S2单片机作为主控单元,进行数据采集,A/D转换,频谱计算(FFT),再由LCD1604显示频谱。且在完成系统其他控制任务的前提下,充分利用单片机剩余计算资源,采用优化FFT算法计算音频信号频谱。音频数据通过STC12C5A60S2的A/D接口实现模拟音频信号的采样保持和量化处理,包括音频采集和转换(该单片机内置A/D转换);频谱显示电路实现模拟音频信号频谱的分段显示,它将音频信号频谱划分成14段,每段按照14级量化,由

如果您需要使用本文档,请点击下载按钮下载!

LCD1604显示器件显示。

3 系统设计

3.1 主控单元

本设计以STC12C5A60S2单片机作为主控单元,进行频谱计算和数据采集,A/D

转换,频谱计算(FFT)。

3.1 STC12C5A60S2 系列单片机简介 3.1.1.1 简介

STC12C5A6OS2是宏晶公司推出的完全集成的混合信号片上系统MCU。1个时钟/机器周期,低成本、高可靠性、高速A/D转换。带8通道模拟多路开关, 转换速度250K/S(25万次/秒);具有可编程数据更新方式;60KB系统编程的Flash内存。1280字节的片内RAM, 可寻址KB地址空间的外部数据存储器接口。硬件实现的ISP/IPA在线系统可编程/在线应用可编程。可通过串口(P3.0/P3.1)直接下载用户程序:6个通用 的16位定时器。兼容普通8051的定时器T0/T1 , 4路PCA也是4个定时器:2通道捕获/比较单元(PWM2路/PCA可编程计数器阵列4路/CCU)一可用来当2路D/A使用、用来再实现2个定时器或2个外部中断STC12C5A60S2是真正能工作的片上系统STC12C5A60S2的功能 均可由用户进行设置使能/禁止。

3.1.1.2 STC12C5A60S2主要性能:

▲ 高速:1个时钟/机器周期,速度比普通MCS一51单片机快8~l2倍; ▲ 宽电压:5.5~3 .3 V,2 .2~3 .6 V;

▲ 低功耗设计:掉电模式(可由外部中断唤醒)。可支持下降沿/上升沿和远程唤醒;

▲ 增加外部掉电检测电路,可在掉电时及时将数据保存EPROM; ▲ 工作频率:0~35 MHz,相当于普通MCS一51单片机的0~420 MHz ; ▲ 8通道,10位高速ADC,速度可达25万次/秒,2路PWM还可当2路D/A使用;

▲ 每个I/OEl驱动能力均可达到2OmA。但整个芯片最大不得超过100mA。 图3.1为STC12C5A60S2 单片机实物图

如果您需要使用本文档,请点击下载按钮下载!

图3.1 STC12C5A60S2 单片机实物图 3.1.2 STC12C5A60S2 系列单片机内部结构

STC12C5A60S2系列单片机的内部结构框图如下图所示。STC12C5A60S2单片机中包含处理器(CPU)、程序存储器(Flash)、数据存储器(SRAM)、定时/计数器、UART串口、串口2、I/O接口、高速A/D转换、SPI接口、PCA、看门狗及片内R/C振荡器和外部晶体振荡电路等模块。STC12C5A60S2系列单片机几乎包含了数据采集和控制中所需的所有单元模块,可称得上一个片上系统。 图3.2为STC12C5A60S2系列内部结构框图

如果您需要使用本文档,请点击下载按钮下载!

图3.2 STC12C5A60S2系列内部结构框图

3.1.3 STC12C5A60S2 系列单片机管脚及管脚说明

图3.3为STC12C5A60S2系列单片机管图

如果您需要使用本文档,请点击下载按钮下载!

图3.3 STC12C5A60S2系列单片机管图

管脚说明:

▲P0.0-P0.7:P0口既可作为输入/输出口,也可作为地址/数据复用总线使用。当P0口作为输入/输出口时,P0是一个8位准双向口,内部有弱上拉电阻,无需外接上拉电阻。当P0作为地址/数据复用总线使用时,是低8位地址线 [A0-A7],数据线 [D0-D7]。

▲CLKOUT2/ADC0/ P1.0:p1.0 标准I/O口 PORT1[0] ADC0 ADC 输入通道-0

CLKOUT2 波特率发生器的时钟输出,可通过设

置WAKE-CLKO[2]位/BRT-CLKO将该管脚配置为CLKOUT2。

▲ADC1/P1.0:p1.1 标准I/O口 PORT1[1] ADC1 ADC 输入通道-1

▲RxD2 /ECI / ADC2/P1.2:p1.2 标准I/O口 PORT1[2] ADC2 ADC 输入通道-2

ECI PCA计数器的外部脉冲输入脚 RxD2 第二串口数据接收端 ▲TxD2 /CCP0/ADC3/P1.3:P1.3 标准I/O口 PORT1[3] ADC3 ADC 输入通道-3

CCP0 外部信号捕获(频率测量或当外部中断使

用)、高速脉冲输出及脉宽调制输出。

TxD2 第二串口数据发送端 ▲SS/CCP1/ADC4/ P1.4:P1.4 标准I/O口 PORT1[4] ADC4 ADC 输入通道-4

CCP1 外部信号捕获(频率测量或当外部中断使

用)、高速脉冲输出及脉宽调制输出。

SS SPI同步串行接口的从机选择信号 ▲MOSI/ADC5 /P1.5:P1.5 标准I/O口 PORT1[5] ADC5 ADC 输入通道-5

如果您需要使用本文档,请点击下载按钮下载!

MOSI SPI同步串行接口的主出从入(主器件的输出和

从器件的输入)

▲MISO/ADC6/P1.6:P1.6 标准I/O口 PORT1[6] ADC6 ADC 输入通道-6

MISO SPI同步串行接口的主入从出(主器件的输入和从

器件的输出)

▲SCLK/ADC7/P1.7:P1.7 标准I/O口 PORT1[7] ADC7 ADC 输入通道-7

SCLK SPI同步串行接口的时钟信号

▲P2.0-P2.7:P2口内部有上拉电阻,即可以作为输入/输出,也可以作为高8位地址总线使用[A8-A15],当P2口作为输入/输出口时,P2是一个8位准双向口。

▲RxD/ P3.0:P3.0 标准I/O口 PORT3[0] RxD 串口1数据接收端 ▲TxD/P3.1:P3.1 标准I/O口 PORT3[1] TxD 串口1数据发送端 ▲INT0 /P3.2:P3.2 标准I/O口 PORT3[2]

INT0外部中断0,下降沿中断或低电平中断 ▲INT1/ P3.3:P3.3 标准I/O口 PORT3[3]

INT1外部中断1,下降沿中断或低电平中断 ▲CLKOUT0/INT/T0/P3.4:P3.4 标准I/O口 PORT3[4] T0 定时器/计数器0的外部输入 INT定时器0下降沿中断

CLKOUT0 定时器/计数器0的时钟输出,可通过设

置WAKE-CLKO[0]位/TOCLKO将该管脚设置为CLKOUT0

▲CLKOUT1/INT/T1/P3.5:P3.5 标准I/O口 PORT3[5]

如果您需要使用本文档,请点击下载按钮下载!

T1 定时器/计数器1的外部输入 INT 定时器1下降沿中断

CLKOUT1 定时器/计数器1的时钟输出,课通过设

置WAKE-CLKO[1]位/TOCLKO将该管脚设置为CLKOUT1

▲ WR/P3.6:P3.6 标准I/O口 PORT3[6]

WR 外部数据存储器写脉冲

▲RD/ P3.7:P3.7 标准I/O口 PORT3[7]

RD 外部数据存储器读脉冲

▲SS/P4.0:P4.0 标准I/O口 PORT4[0]

SS SPI同步串行接口的从机选择信号 ▲MOSI/ECI/P4.1:P4.1 标准I/O口 PORT4[1] ECI PCA计数器的外部脉冲输入脚

MOSI SPI同步串行接口的主出从入(主器件的输出和从器件的输入)

▲MISO/CCP0/P4.2:P4.2 标准I/O口 PORT4[2]

CCP0 外部信号捕获(频率测量或是当外部中断使用),

告诉脉冲输出或脉宽调制输出。

MISO SPI同步串行接口的主入从出(主器件的输入和

从器件的输出)

▲SCLK/CCP1/P4.3:P4.3 标准I/O口 PORT4[3]

CCP1 外部信号捕获(频率测量或是当外部中断使用),

告诉脉冲输出或脉宽调制输出。 SCLK SPI同步串行接口的时钟信号

▲NA/P4.4:P4.4 标准I/O口 PORT4[4]

设置为1 P4.4/NA脚为I/O口(P4.4) 设置为0 P4.4/NA脚是弱上拉,无任何功能。

如果您需要使用本文档,请点击下载按钮下载!

▲ALE/P4.5:P4.5 标准I/O口 PORT4[5] ALE 地址锁存允许

▲EX-LVD/P4.6/RST2:P4.6 标准I/O口 PORT4[6] EX-LVD 外部低压式中断/比较器 RST2 第二复位功能脚 ▲P4.7/RST:P4.7 标准I/O口 PORT4[7] RST 复位脚 ▲P5.0:标准I/O口 PORT5[0] ▲P5.1:标准I/O口 PORT5[1] ▲P5.2:标准I/O口 PORT5[2] ▲P5.3:标准I/O口 PORT5[3]

▲XTAL1:内部时钟电路反相放大器输入端,接外部晶振的一个引脚,当直接使用外部时钟源时,此引脚是外部时钟的输入端。

▲XTAL2:内部时钟电路反相放大器输出端,接外部晶振的另一端,当直接使用外部时钟源时,此引脚可悬空。此时XTAL2实际将XTAL1输入的时钟进行输出。

▲VCC:电源 ▲GND:接地

3.1.4 STC12C5A60S2 单片机最小应用系统

图3.4为STC12C5A60S2单片机最小系统构成的电路图

如果您需要使用本文档,请点击下载按钮下载!

图3.4 STC12C5A60S2单片机最小系统构成的电路

3.1.4.1 系统组成

▲复位电路:时钟频率低于12MHz时,可以不用C1,R1接1K电阻到地。时钟频率高于12MHz时,建议使用第二复位功能脚。(STC12C5A60S2系列在RST2/EX_LVD/P4.6口STC12C5201AD系列RST2/EX_LVD/P1.2口)

▲晶振电路:如果外部时钟频率在33MHz以上时,建议直接使用外部有源晶振。如果使用内部R/C振荡器时钟(室温情况下5V单片机为:11MHz~17MHz,3V单片机为8MHz~12MHz),XTAL1和XTAL2脚浮空。如果外部时钟频率在27MHz以上时,使用标称频率就是基本频率的晶体,不要使用三泛音的晶体,否则如参数搭配不当,就有可能振在基频,此时实际频率就只有标称频率的1/3了,或直接使用外部有源晶振,时钟从XTAL1脚输入,XTAL2脚必须浮空。 3.1.4.2 结构特点

▲复位电路的极性电容C1的大小直接影响单片机的复位时间,一般采用10~30uF,51单片机最小系统容值越大需要的复位时间越短。

▲晶振Y1也可以采用6MHz或者11.0592MHz,在正常工作的情况下可以采用更高频率的晶振,51单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。

▲起振电容C2、C3一般采用15~33pF,并且电容离晶振越近越好,晶振离单

如果您需要使用本文档,请点击下载按钮下载!

片机越近越好

如果您需要使用本文档,请点击下载按钮下载!

4.P0口为开漏输出,作为输出口时需加上拉电阻,阻值一般为10k。 ▲设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。

▲设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2 ms。

3.2 STC12C5A60S2 系列单片机单片机的A/D转换器

3.2.1 STCl2C5A60S2高速A/D转换

本设计无需外加A/D转换,使用的单片机内置A/D接口,音频信号可直接送入单片机进行数据采集和预处理。STC12C5A60S2单片机的A/D转换口在P l口(P1.0~P 1.7)有10位8路高速A/D转换器,A/D是电压输入型转换速度25万次/s(250KHz)。复位后P1口为弱上拉型I/O口。通过软件可设置将P1(P1.0~P 1.7)El中的任何一位为A/D转换位,不用作A/D转换的位可继续用作普通YO口使用。

3.2.2 与A /D转换有关控制位的设置

▲对P1ASF寄存器的设置:当P1口中的相应位作为A /D使用时,需先将P1ASF中的相应位置“1”相应的口设置为模拟功能。如:P1ASF.0~P1ASF.7中哪一位为“1”,则P1口中对应的位作为模拟功能D使用。

▲对ADC_CONTR特殊功能寄存器设置:建议直接用MOV赋值语句。选择模拟输入通道CHS2/CHSl/CHS0:如CHS2/CHS1/CHSO=l11~000可分别选择P1.7~P1.0作为ADC的A/D转换输入位。ADC_START位:ADC模数转换器转换启动控制位,ADC_START=1时,开始转换。转换结束后为ADC_START=0。中断请求标志位ADC_FLAG:ADC模数转换器转换结束标志位。当AID转换完成后,ADC_FLAG=1,一定要由软件清零,A/D转换完成后由该位申请中断。ADC电源控制位ADC_POWER:ADC_POWER=O,关闭ADC电源,ADC_PO WER=1,打开A/D转换器电源。建议进人空闲模式前,将ADC电源关闭,启动A/D转换前一 定要确认A/D电源已打开,A /D

如果您需要使用本文档,请点击下载按钮下载!

转换完成后关闭AD电源可降低功耗。在A/D转换结束之前, 不改变任何I/ O口的状态,有利于高精度A/D转换。

如果您需要使用本文档,请点击下载按钮下载!

▲对IE的设置:如果允许A /D转换中断,将EA=1打开单片机中断允许总控制位;将EAD C =1,这时ADC中断的允许中断控制位。

STC12C5A60S2系列单片机的A /D转换模块使用的时钟是外部晶体时钟或内部R/C振 荡器所产生的时钟。不使用时钟分频寄存器CLK_DIV。这样可以让ADC用较高的频率工作,提高A/D的转换速度;还可以让CPU用较低的频率工作,降低系统的功耗。

▲程序中需要注意的问题:由于是2套时钟,所以,设置ADC_CONTR控制寄存器后, 加4个空操作延时才可以正确读到ADC_CONTR寄存器的值。原因是设置ADC _CO N T R控制 寄存器的语句执行后,要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR控制寄存器。

▲对AUXR1寄存器设置:AUXR1寄存器中的ADRJ位是A/D转换结果寄存器(ADC_RES,ADC_RESL)的数据格式调整控制位。ADRJ=0,10位A/D转换结果的高八位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中。ADI~I=1,10位A/D转换结果的高2位存放在ADC_RES中低2位中,低8位存放在ADC_RESL中。 图3.5为STC12C5A60S2系列单片机ADC(A/D转换器)的结构图

图3.5 STC12C5A60S2系列单片机ADC(A/D转换器)的结构图

如果您需要使用本文档,请点击下载按钮下载!

3.3 STC12C5A60S2 系列单片机单片机的I/O口结构

STC12C5A60S2系列单片机所有I/O口均(新增P4口和P5口)可由软件配置成4种工作类型之一,如表1-6所示。4种类型分别为:准双向口/弱上拉(标准8051输出模式)、强推挽输出/强上拉、仅为输入(高阻)或开漏输出功能。每个口由2个控制寄存器中的相应位控制每个引脚工作类型。STC12C5A60S2系列单片机上电复位后为准双向口/弱上拉(传统8051的I/O口)模式。2V以上时为高电平,0.8V以下时为低电平。每个I/O口驱动能力均可达到20mA,但整个芯片最大不得超过120mA。

I/O口工作类型设定

表1 P5口设定 (P5口地址:C8H)

P5M1 [3:0] 0 0 1 1 P5M0 [3:0] 0 1 0 1 I/O口模式 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻) 仅为输入(高阻) 开漏(open drainl),内部上拉电阻断开,要外加 表2 P4口设定 (P4口地址:C0H)

P4M1 [7:0] 0 0 1 1 P4M0 [7:0] 0 1 0 1 I/O口模式 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻) 仅为输入(高阻) 开漏(open drainl),内部上拉电阻断开,要外加 表3 P3口设定 (P3口地址:B0H)

P3M1 [7:0] 0 0 P3M0[7:0] 0 1 I/O口模式 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻)

如果您需要使用本文档,请点击下载按钮下载!

1 1 0 1 仅为输入(高阻) 开漏(open drainl),内部上拉电阻断开,要外加 表4 P2口设定 (P2口地址:A0H)

P2M1 [7:0] 0 0 1 1 P2M0[7:0] 0 1 0 1 I/O口模式 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻) 仅为输入(高阻) 开漏(open drainl),内部上拉电阻断开,要外加 表5 P1口设定 (P1口地址:9 0H)

P1M1 [7:0] 0 0 1 1 P1M0[7:0] 0 1 0 1 I/O口模式(P1.x如果做A/D使用,需先将其设置成开漏或高阻输入) 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻) 仅为输入(高阻),如果该I/O口需作A/D使用,可以选此模式 开漏(open drainl),如果该I/O口需作A/D使用,可以选此模式 表6 P0口设定 (P0口地址:80H)

P0M1 [7:0] 0 0 1 1 P0M0[7:0] 0 1 0 1 I/O口模式 准双向口(传统8051 I/O口模式) 灌电流可达20mA,拉电流为230uA 由于制造误差,实际为250uA~150uA 强推挽输出(强上拉输出,可达20mA,要加限流电阻) 仅为输入(高阻) 开漏(open drainl),内部上拉电阻断开,要外加

★ 值得注意的是::

虽然每个I/O口在弱上拉时都能承受20mA的灌电流(还是要加限流电阻,如1K,560Ω等),在强推挽输出时都能输出20m A的拉电流(也要加限流电阻)

如果您需要使用本文档,请点击下载按钮下载!

,但整个芯片的工作电流推荐不要超过120mA。即从MCU-VCC流入的电流不超过120mA,从MCU-Gnd流出电流不超过120mA,整体流入/流出电流都不能超过120mA.。

3.4 频谱显示单元

由STC12C5A60S2单片机计算得到的频谱值将显示于LCD1604 3.4.1 LCD简介

液晶显示器(Liquid Crystal Display,简称LCD)已被视为下一代显示器的主要产品。

3.4.1.1 在单片机系统中应用晶液显示器作为输出器件的优点

▲显示质量高:由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。因此,液晶显示器画质高且不会闪烁。

▲数字式接口:液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。

▲体积小、重量轻:液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。

▲功耗低:相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。 3.4.1.2液晶显示器的分类

液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。除了黑白显示外,液晶显示器还有多灰度有彩色显示等。如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。 3.4.2 LCD1604简介

字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,16*4,20*2和40*2行等的模块。 图3.6为一般1604字符型液晶显示器实物

如果您需要使用本文档,请点击下载按钮下载!

,

图3.6 一般1604字符型液晶显示器实物图

3.4.3 LCD1604 显示原理

▲线段的显示:点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。例如屏的第一行的亮暗由RAM区的000H——00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H,……(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和暗线组成的虚线。

▲字符的显示:用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。 ▲汉字的显示:汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节

如果您需要使用本文档,请点击下载按钮下载!

……直到32B显示完就可以LCD上得到一个完整汉字。 3.4.4 LCD1604 接口定义及参数说明 3.4.4.1 LCD1604接口定义

LCD1604采用标准的14脚(无背光)或16脚(带背光)接口,带背光的比不带背光的厚,是否带背光在应用中并无差别.各引脚接口说明如表2所示。

表2 LCD1604引脚接口说明表

引脚号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 标识 GND VCC V0 RS R/W EN D0 D1 D2 D3 D4 D5 D6 D7 LED+ LED- 说明 接0V 接4.8V~5V 对地接电阻470~2K RS=0,指令寄存器;RS=1,数据寄存器 R/W=0,写;R/W=1,读 允许信号 数据0 数据1 数据2 数据3 数据4 数据5 数据6 数据7 背光正极,接4.8V~5V 背光负极,接0V 3.4.4.l LCD重要技术参数 ▲显示容量:16×4个字符 ▲芯片工作电压:4.5~5.5V ▲工作电流:2.0mA(5.0V) ▲模块最佳工作电压:5.0V ▲字符尺寸:2.95×4.35(W×H)mm

4 音频频谱显示相关问题

4.1 频谱及频谱显示

如果您需要使用本文档,请点击下载按钮下载!

我们知道,一切声音都是由振动产生的。声音之所以千变万化各不相同,是因为它们的振动各不相同。看看琵琶,吉他或者其他的弦类乐器,可以发现它的每一根琴弦的直径都是不一样的。琴弦越细,音调也就越高。反之则越低。显然粗的弦就不如细的弦振动得快或者说是振动的频率高。产生音调高低的不同,就是由于振动的频率不同。很显然频率越高,音高也就越高。

频率的单位是赫兹(简写为 Hz),赫兹 (1857-14),是德国物理学家,他发现了电磁波,为了纪念他,人们用它的名字来做为频率的单位。所谓的一赫兹,就是一秒钟振动一次。那么440Hz呢,当然就是每秒振动440次,这个声音就是音乐中的标准A音,是乐器定音的标准。而钢琴C的频率则是261.63Hz。我们人的耳朵能够听到的频率范围,是20Hz到20000Hz。低于这个频率范围的声音叫次声波,而高于这个频率范围的声音叫做超声波。所以我们能听到的音乐的频率,即都在人耳可听到的这个范围之内,约从20Hz到20KHz。

根据傅立叶分析,任何声音可以分解为数个甚至无限个正弦波,而它们往往又包含有无数多的谐波分量。而它们又往往是时刻在变化着。所以一个声音的构成其实是很复杂的。将声音的频率分量绘制成曲线,就形成了频谱。对频谱进行分析的仪器就是频谱分析仪,早期频谱仪都是模拟分析的。频谱仪的原理就是将声音以信号通过一系列不同中心频率的模拟带通滤波器。每个带通滤波器相当于一个共振电路,其特性由中心频率(步进的)、频带宽度及响应时间表示。在声音信号通过滤波器后,经过平方检波器,并进行平均之后,在每个频率上测定所传输的功率,从而得到信号的频谱。然而,传统的频谱仪受到滤波器性能的制约,因为模拟电路本身的特性所局限,滤波器的带宽和响应时间成反比,也就是说模拟滤波器的频率分辨力与时间分解能力之间存在矛盾。因为频谱仪所测量的往往都是非稳态声,一般来说,都是使用若干个滤波器来覆盖整个频率范围,并将信号同时并联地输入到这些滤波器上去。或者使用中心频率能够从低到高连续变化的滤波器。

4.2 FFT运算规则集编程思想

音频频谱值的计算采用快速傅里叶算法FFT(Fast Fourier Transform),为了提高显示器的刷新频率,系统每隔10ms读取16次A/D转换值,得到16点实数序列,紧接着完成16点FFT运算得到16点复数序列。

如果您需要使用本文档,请点击下载按钮下载!

4.2.1蝶形运算及其优化算法

基2-FFT算法分为两类:时域抽取法FFT,简称DIT-FFT;频域抽取法FFT,简称DIF-FFT。根据基2-FFT算法,N点FFT运算可以分成log2N级,每一级都有N/2个蝶形运算。

图4.1 蝶形运算

4.2.1.1 蝶形运算公式的推导过程如下:

X(k)=X'(k)+X'(k+b)WPN X(k+b)=X'(k)—X'(k+b)WPN

p式中,WN=cos(2πP/N)—jsin(2πP/N)

将式(1)化简成实部和虚部的形式,得到:

XR(k)=XR'(k)+XR'(k+b)cos(2πP/N)+X1'(k+b)sin(2πP/N) X1(k)=XR'(k+b)sin(2πP/N)+X1'(k+b)cos(2πP/N) 同理,式(2)化简得到:

XR(k+b)=XR'(k)+XR'(k+b)cos(2πP/N)-X1'(k+b)sin(2πP/N) X1(k+b)=X1'(k)+XR'(k+b)sin(2πP/N)-X1'(k+b)cos(2πP/N) 可见每个蝶形运算的输出都是由其输入值与某一正弦函数和余弦函数的乘积累加得到的。由式(3)—(6)编制正弦和余弦表,每次做蝶形运算时刻查表加快运算速度。

4.2.1.2 基2-FFT算法的基本思想

基2-FFT算法的基本思想是用3层循环完成全部N点FFT运算: ▲最里层循环处理单独的一个蝶形运算,采用查表方法实现乘法运算; ▲中间层循环完成每一级的N/2个蝶形运算 ▲最外层循环完成log2N级蝶形运算

由此可看出:在每一级中,最里层循环完成N/2L个蝶形运算;中间层循环控

如果您需要使用本文档,请点击下载按钮下载!

制最里层循环进行

如果您需要使用本文档,请点击下载按钮下载!

2L-1次运算。因此,中间层循环完成时,共进行(2L-1)N/2L=N/2个蝶形运算。实际上最里层和中间层循环完成了第L级计算,最外层则最终完成log2级蝶形运算。

★ 需要加以说明的数据是:

▲在第L级中,每个蝶形的两个输入端相距b=2L-1个点 ▲同一乘数对应这相邻间隔为2L个点的N/2L个蝶形

▲第L级的2L-1个蝶形因子中的P,可表示为P=jx25-L,其中 j=0,1,2,…(2L-1-1)

4.2.2 编程思想及程序图

由图4.2可以归纳出一些对编程有用的运算规律:第L级中,每个蝶形的两个输入数据相距B=2L1个点;每级有B个不同的旋转因子;同一旋转因子对应着间隔为2L点的2ML个蝶形。

总结上述运算规律,便可采用下述运算方法。先从输入端(第一级)开始,逐级进行,共进行M级运算。在进行L级运算时,依次求出B个不同的旋转因子,每求出一个旋转因子,就计算完它对应的所有2ML个蝶形。这样,我们可用三重循环程序实现DIF-FFT运算。

另外,DIF-FFT算法运算流图的输出X(k)为自然顺序,但为了适应原位计算,其输入序列不是按x(n)的自然顺序排列,这种经过M次偶奇抽选后的排列成为序列x(n)的倒序(倒位)。因此,在运算M级蝶形之前应先对序列x(n)进行倒序。

如果您需要使用本文档,请点击下载按钮下载!

T A(k)+A(k+B)WN p开始 读入x(n),M N=2M 倒序 L=1,M B=2L1 J=0,B-1 P=2L1J K=J,N-1,2 L图4.2 DIF-FFT运算程序框图

输出 A(k+B) A(k)+A(k+B)WN A(k) T p结束

如果您需要使用本文档,请点击下载按钮下载!

4.2.3 序列的倒序

DIT-FFT算法的输入序列的排序看起来似乎很乱,但仔细分析就会发现这种倒序是很有规律的。由于N=2M,因此序列数可用M位二进制数(nM1,nM2,nM3…n1,n0)表示。第一次按最低位n0的0和1将x(n)分解为偶奇两组,第二次又按次低位n1的0和1值分别对偶奇组分组;以此类推,第M次按nM1为分解,。 表4.1列出了N=8时的二进制数表示的序列数和倒序数,由表可知,只要将顺序数(n2n1n0)的二进制位倒置,则得到对应的二进制倒置(n0n1n2)。自然序列数I增加1,是在序列数的二进制数最低位加1 ,逢2向高位进位。而倒序数则是在M位二进制数最高位加1,逢2向低位进位。

表4.1 顺序和倒序二进制数对照表

顺 序 十进制数I 0 1 2 3 4 5 6 7 二进制数 000 001 010 011 100 101 110 111 二进制数 000 100 010 110 001 101 011 111 倒 序 十进制数J 0 4 2 6 1 5 3 7

如果您需要使用本文档,请点击下载按钮下载!

总 结

在做毕业设计的前期,我选用了ATC51单片机。ATC51单片机内部无A/D转换,片上集成128字节RAM,用户应用程序空间8K字节。在设计电路中需加一个A/D转换电路。在中期报告中,我把ATC51单片机换成了STC12C5A60S2单片机。STC12C5A60S2单片机内部设有8路高速10位A/D转换(250K/s,即25万次/每秒),片上集成1280字节RAM,用户应用程序空间用户应用程序空间8K/16K/20K/32K/40K/48K/52K/60K/62K字节。外部电路不用再设A/D转换电路,使用的单片机内置A/D接口,音频信号可直接送入单片机进行数据采集和预处理。在整体电路设计中使用STC12C5A60S2单片机比使用ATC51单片机电路要简单,运行速度要快8-12倍。

在设计功能实现的同时,充分考虑了整个系统的成本控制,以及最重要的系统稳定性。在系统涉及的各个领域,我还需要更进一步进行学习和探索,以使在以后的设计中能将自己的新鲜思维应用至实际操作中。本设计频谱显示系统的应用面广,结构较为简单,系统易集成。无论是哪种音频信号,多数情况下能保证频谱显示的精度与速度。当音频信号频率较高是,普通的单片机运算速度相对较慢,延时比较厉害,需要使用增强型的单片机才能实时显示频谱。

如果您需要使用本文档,请点击下载按钮下载!

参 考 文 献

1 谭浩强.C程序设计.北京:清华大学出版社,1999,12

2 江志红.51单片机技术与应用系统开发案例精选.北京:清华大学出版社,2008,12

3 蔡美琴,张为民.MCS-51系列单片机系统及其应用.北京:高等教育出版社,1992

4 郭天祥.新概念51单片机C语言教程 入门、提高、开发、拓展全攻略.北京: 电子工业出版社,2009,1

5 高西全,丁玉美.数字信号处理.西安:西安电子科技大学出版社,2008,8

6 刘娟.单片机C语PROTUES仿真技能实训.北京:中国电力出版社,2010

7 唐志德.数字电子技术.北京:科学出版社,2010,6 8 丁向荣.STC系列单片机原理与应用.北京:电子工业出版社,2011,1 9 杜洋.爱上单片机.北京:人人民邮电出版社,2011,10

10 温子琪,刘志峰.51单片机c语言创新教程.北京:北京航空航天大学出版社,2011,4

11严天峰,王耀奇.电子设计工程师实践教程.北京:北京航空航天大学出版社,2011,1

12赵会成.51单片机c程序应用实例详解.北京:北京航空航天大学出版社,2011,3

13 Baldenlus T.The 8051 Microcontroller.Joumal of Business,1999,4

14 Reichelstein S.Advanced Topics In Dsp.Review of Accounting Studies,1998,5

15 Hirshieifer J.Project Report .Joumal of Business,2001,7

如果您需要使用本文档,请点击下载按钮下载!

致 谢

首先我由衷的感谢我的指导老师,在我的毕业设计完成过程中给予我的帮助。其次,感谢所有教过我们的老师,无论是学习上还是生活上,都给了我很多的帮助和关心。老师老师们深厚的学术功底,严谨的治学作风,精益求精的工作态度,将时时影响着我,为我将来的工作奠定了坚实的基础。在做毕业设计的这段时间,使我不仅学到了科学知识与操作方法,而且更让我体会到了做人一定要做一个认真负责的人,这一切都将是我一生成长的动力。在此向我亲爱的老师们致以最崇高的敬意和衷心的感谢!最后,我也要感谢我周围的同学们对我的帮助与支持,更要感谢我的家人对我学业上的支持与鼓励。

如果您需要使用本文档,请点击下载按钮下载!

附录 A 源程序 LCD显示程序

********************************** #include \"MyType.h\" #include \"stc.h\" #include \"lcd.h\" sbit busyFlag = P0^7; //sbit debugFlag= P2^0;

//自定义字符 分别为1横格-8横格 uchar code Pic[8][8]= {

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f}, {0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x1f}, {0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x1f}, {0x00,0x00,0x00,0x00,0x1f,0x00,0x1f,0x1f}, {0x00,0x00,0x00,0x1f,0x1f,0x00,0x1f,0x1f}, {0x00,0x00,0x00,0x1f,0x1f,0x00,0x1f,0x1f}, {0x00,0x1f,0x00,0x1f,0x1f,0x00,0x1f,0x1f}, {0x1f,0x1f,0x00,0x1f,0x1f,0x00,0x1f,0x1f}, };

void lcdCheckbusy() //检查LCD忙 {

lcdDb=0xff;

lcdRs=0; //rs=1为数据,=0为命令. lcdRw=1; //rw=1为读,=0为写. lcdE=1; //cs=1选通 delay40us(1); while(busyFlag); lcdE=0; }

/*******初始化函数***************/

如果您需要使用本文档,请点击下载按钮下载!

void lcdInit(void) { lcdWriteCommand(0x38); //设置8位格式,2行,5x7 lcdWriteCommand(0x0c); //整体显示,关光标,不闪烁 lcdWriteCommand(0x06); //设定输入方式,增量不移位 lcdWriteCommand(0x01); //清除屏幕显示 }

//******************************** //********写指令函数************ void lcdWriteCommand(uchar dat) {

lcdCheckbusy(); lcdDb=dat;

lcdRs=0; //指令 lcdRw=0; //写入 lcdE=1; //允许 delay40us(1); lcdE=0; }

//******************************* //********写数据函数************* void lcdWriteData(uchar dat) {

lcdCheckbusy(); lcdDb=dat;

lcdRs=1; //数据 lcdRw=0; //写入 lcdE=1; //允许 lcdE=0; }

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

//********写入CGRAM自定义字符************* void lcdWritePic() {

uchar i,j; for(i=0;i<8;i++) {

lcdWriteCommand(0x40+i*8);

for(j=0;j<8;j++)lcdWriteData(Pic[i][j]);

如果您需要使用本文档,请点击下载按钮下载!

} }

/******************************************************* 显示一个字符函数

函数参数 : 显示坐标(x,y)范围 (0~f,0~3)

*******************************************************/ void dispString(uchar x,uchar y,uchar dat) {

uchar address; switch (y) {

case 0: address=0x80+x;

break;

case 1: address=0xc0+x;

break;

case 2: address=0x90+x;

break;

case 3: address=0xd0+x;

break;

}

lcdWriteCommand(address); lcdWriteData(dat); }

//******************************** //********延时函数 1T 22.1148M*************** void delay40us(uint n) {

uchar a,b; while(n--) {

for(b=185;b>0;b--) for(a=1;a>0;a--); } }

//******************************* Main函数 //头文件

#include

如果您需要使用本文档,请点击下载按钮下载!

#include \"MyType.h\" #include \"stc12c5a60s2.h\" #include \"lcd.h\"

struct compx //定义复数结构体 {

float real; float imag; };

xdata struct compx s[ ]; //FFT数据缓存放在XDATA空间 struct compx EE(struct compx,struct compx); //复数乘法函数的声明 void FFT(struct compx xin[],int N); //FFT函数的声明 struct compx EE(struct compx a1,struct compx b2) //复数乘法 {

struct compx b3;

b3.real=a1.real*b2.real-a1.imag*b2.imag; b3.imag=a1.real*b2.imag+a1.imag*b2.real; return(b3); }

/*FFT函数*/

void FFT(struct compx xin[],int N) {

int f,m,nv2,nm1,i,k,j=1,l; struct compx v,w,t; nv2=N/2; f=N;

for(m=1;(f=f/2)!=1;m++){;} nm1=N-1;

for(i=0;it=xin[j]; xin[j]=xin[i]; xin[i]=t; }

k=nv2; //k为倒序中相应位置的权值

如果您需要使用本文档,请点击下载按钮下载!

while(kj=j-k; k=k/2; } j=j+k; } {

int le,lei,ip; float pi; for(l=1;l<=m;l++) {

le=pow(2,l); //乘方 lei=le/2; pi=3.14159265; v.real=1.0; v.imag=0.0;

w.real=cos(pi/lei); //旋转因子 w.imag=-sin(pi/lei);

for(j=1;j<=lei;j++) //控制蝶形运算的级数 {

for(i=j-1;iip=i+lei;

t=EE(xin[ ip ],v);

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;

}

v=EE(v,w); } } } }

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

如果您需要使用本文档,请点击下载按钮下载!

显示频谱函数

LCD1604显示方式:从下往上,从左往右 x=0 x=4 x=8 x=12 x=16 x=20 x=24 x=28 j=1 j=2 j=3 j=4

******************************************************************/ void showbar(void) {

uchar i,j,dat1,dat2; uint tmp1=33,tmp2=33; for(i=0;i<32;i+=4) {

float t0=0,t2=0;

t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),

2))/2;

t2=sqrt(pow((s[i+2].real+s[i+3].real),2)+pow((s[i+2].imag+s[i+3].imag),

2))/2;

tmp1=(uint)(t0/3); tmp2=(uint)(t2/3); for(j=4;j>0;j--) {

if (tmp1>=8){dat1=7;tmp1=tmp1-8;} //满格 else if(tmp1==0) dat1=20; //空格 else {dat1=tmp1-1;tmp1=0;} //1-7格 if (tmp2>=8){dat2=7;tmp2=tmp2-8;} //满格 else if(tmp2==0) dat2=20; //空格 else {dat2=tmp2-1;tmp2=0;} //1-7格 dispString(i/2,j-1,dat1); dispString(i/2+1,j-1,dat2); } } }

/*主函数*/ void main()

如果您需要使用本文档,请点击下载按钮下载!

{

int N=,i; //变量初始化,点FFT运算 float offset; P0=0xff;P2=0xff; lcdInit(); lcdWritePic();

P1ASF=0x01; //P10口做AD 使用

P1M0 = 0x01; //0000,0001用于A/D转换的P1.x 口,先设为开漏 P1M1 = 0x01; //0000,0001 P1.0先设为开漏。断开 内部上拉电阻 ADC_CONTR=0xC8; //40.96K采样率 while(!(ADC_CONTR&0x10));

offset=((float)ADC_RES*4+(float)(ADC_RESL%0x04)); //AD结果高8位左移2位,低2位不变,然后相加 while(1) {

for(i=0;iADC_CONTR=0xC8; //40.96K采样率

while(!(ADC_CONTR&0x10));

s[i].real=((float)ADC_RES*4+(float)(ADC_RESL%0x04)-offset)/4;//((((int)ADC_DA TA-128)/2))*4;

s[i].imag=0; }

FFT(s,N); //调用FFT函数进行变换 showbar(); //显示频谱 } }

如果您需要使用本文档,请点击下载按钮下载!

附录B 系统电路图

(注:可编辑下载,若有不当之处,请指正,谢谢!)

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- stra.cn 版权所有 赣ICP备2024042791号-4

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务