语音存储回放——系统软件设计班级:电科0801姓名:学号:语音存储回放系统软件的基本功能是通过按键控制系统实现录音与放音。录音(语音的存储)时,采集语音信号并将采集的数据存入M25P16中;放音(语音的回放)时,从M25P16中读取数据送DAC。一、设计题目设计并制作一个数字化语音存储与回放系统,设计要求:①前置放大器增益可调,功率放大器输出功率≥0.5W。②带通滤波器:通带为300Hz~3.4kHz。③ADC:采样频率fs=8kHz,字长8位。④语音录放时间≥60s。⑤DAC:变换频率fc=8kHz,字长8位。⑥回放语音质量良好。⑦采用语音压缩算法,增加录放时间。在建立系统软件的框架时,应考虑以下几个问题。⑴人机接口的功能设计语音存储与回放系统的人机接口功能比较简单,按照功能要求要求只需要3个功能键:“擦除”键、“录音”键、“放音”键。“擦除”键有效时,单片机调用擦除子程序将M25P16拾音器前置放大器带通滤波器ADC微控制器存储器DAC带通滤波器功率放大器喇叭中数据整片擦除,以便进行录音操作。“录音”键有效时,单片机以8kHz的频率采集语音信号,并将数据写入M25P16中。当“放音”键有效时,单片机通过读数据子程序从M25P16中取出数据送入DAC输出语音信号。语音存储与回放系统在工作时需要提示一些简单的信息,入显示三种工作状态:录音状态、放音状态、擦出状态,另外,需要显示录音和放音的时间。根据设计方案,语音存储与回放系统的单片机子系统采用并行总线单片机最小系统,人机接口采用LCD模块和矩阵式键盘。根据键盘的工作原理,当键有效时,单片机通过执行INT0中断服务程序读取键值。单片机根据读取的键值,执行相应的键处理程序。这里需要考虑的是,键处理程序放在INT0中断服务程序中还是放在主程序中。如果将键处理程序放在INT0中断服务程序中,则单片机在执行键处理程序时,无法响应同级别的中断,影响程序的效率和实时性。因此,将键处理程序放在主程序中,INT0中断服务程序只需要读取键值并设置一个键有效标志。主程序则不断循环检测键有效标志,如键有效标志置1,则根据键执行响应的键处理程序。每次检测到键有效标志置1后,应立即将键有效标志清零,以免键处理程序重复执行。⑵M25P16的读写方案设计由于对M25P16写一字节数据和写一页(256字节)数据所需编程时间是相同的,约需0.64ms。语音存储与回放系统的数据采样频率为8kHz,采样周期为u0.125ms。如果每采集一字节数据就立即写入M25P16,显然M25P16在写操作时间上是不能满足要求的。因此,在程序设计中,采集的语音数据先存放在C8051F360内部的XRAM中,待采满256字节数据,调用M25P16页编程子程序将数据写入M25P16。由于采集256字节数据需要32ms的时间,可以满足M25P16对写操作时间的需求。(3)A/D和D/A转化器的控制为了精确控制采样频率,DAc由定时器2控制,在定时器2中断服务程序中向DAC送一字节数据,将数字化的语音信号转化成模拟信号。ADC由定时器3溢出启动A/D转化(注意需要禁止定时器3溢出中断),A/D转化结束后产生中断,通过ADC中断服务程序读取采样值。为了提高定时精确,定时器2和定时器3均采用16为自动重装工作方式。(4)C8051F360单片机内部资源的使用在语音存储回放系统中,需要使用C8051F360单片机的ADC、DAC、SPI0、XRAM、定时器等资源。由于C8051F360单片机具有丰富的片上外设,除了人机接口和大容量的存储器外,不需要扩展其他外部设备,大大简化了系统硬件电路的设计。根据上述分析,语音存储与回放系统的软件框架由主程序、键盘中断服务程序、定时器2服务程序、ADC中断服务程序组成。1.主程序流程图主程序的流程图如图。在主程序中首先执行C8051F360单片机和M25P16的初始化程序。C8051F360单片机的初始化包括I/O口初始化、内部振荡器初始化、ADC初始化、DAC初始化、SPI0初始化、定时器初始化、中断系统初始化、M25P16的初始化主要目的是通过写状态字消除M25P16的写保护。YYNNNY“录音”键?“放音”键?“擦除”键?开始C8051F360与M25P16初始化LCD初始化界面清录音和放音标志根据键值散转键有效标志=1?清键有效标志调用M25P16擦除子程序显示“正在擦除”显示“正在放音”显示“正在录音”置录音标志置放音标志显示初始化界面清录放音标志位XRAM、M25P16地址初始化XRAM、M25P16地址初始化录音标志=1?已采集256字节数据?显示录音时间调用M25P16页编程子程序XRAM地址置0M25P16地址加256清录音标志M25P16数据是否存满?YYY已转换256字节数据?放音标志=1?XRAM地址置0调用M25P16读数据子程序M25P16地址加256显示放音时间M25P16数据是否读完?清放音标志NNN主程序实际上是一个循环程序,不断的检测有无按键输入。有键输入时,根据键值做相应的处理。主程序中设置了两个工作状态:录音状态和放音状态,分别用两个标志位来表示。在录音状态下,数据每采集满256个字节,就调用页编程子程序,将XRAM中的数据写入M25P16中。在放音状态下,每转化完成256个字节的数据,就再从M25P16中读取下一页数据。在录音和放音的过程中,还需要显示录音和放音的时间。由于采样频率是固定的,M25P16的存储地址的变化是与录音与放音时间是相关的,因此,可以用M25P16的存储地址换算后可得录音和放音的时间。2.键盘中断(INT0)服务程序流程图当有键按下时,键盘接口电路产生INT0中断信号。键盘中断服务程序的功能十分简单:读取4位键值,置键有效标志位。其流程图如图所示:3.A/D中断服务程序流程图A/D转化的启动通过定时器3的溢出实现。当A/D转化结束以后,启动一次中断。在A/D转化中断服务程序中首先判断是否处于录音状态,如果出于录音状态,将高8位数据(ADC0H)存入C8051F360单片机内部XRAM。注意,ADC中断标志必须软件清零。A/D中断服务程序流程图如图所示:中断入口读取键值置键有效标志位中断返回4.定时器T2终端服务流程图定时器T2每中断一次,单片机向DAC写一字节的语音数据。根据8kHz的采样频率,可以计算T2定时常数为FF83H(0.125ms)。由于定时时间很短,定时器采用16位自动加载工作方式,既提高了定时精度,又简化了程序设计。T2中断服务程序流程图如图在DAC中断服务程序流程图和定时器T2中断服务程序流程图中,需要单片机对XRAM的读写操作。单片机对XRAM的读写有16位MOVX指令和8位MOVX指令。由于在程序中只需要对256字节的XRAM操作,因此,采用8位MOVX指令可大大简化程序设计。YN中断入口清中断标志读A/D转换值中断返回录音标志为1?XRAM地址加1向XRAM存放数据YN从XRAM读取数据中断返回放音标志为1?XRAM地址加1数据送DAC中断入口附件:程序#includeC8051F360.h#defineuncharunsignedchar#defineRCOMADDR0XC00A#defineWCOMADDR0XC008#defineWDATADDR0XC009#defineRDATADDR0XC00B#defineKEY_READ0XC00Cuncharkeycode,keysign,sh_time,time_sign;unsignedlongADDR=0x0000;xdatauncharData_byte[256];uncharcodefiguer[]={'0','1','2','3','4','5','6','7','8','9',':'};/////////////////////////端口初始化voidport_io_init(void){SFRPAGE=0x0f;P0MDIN=0xe7;////P0.3--P0.4设置为模拟输入P0MDOUT=0x83;////P0.0,P0.7,P0.1推拉式输出P0SKIP=0xf9;////P0.0,P0.3--P0.7被交叉开关跳过P1MDIN=0xff;P1MDOUT=0xff;P1SKIP=0xff;P2MDIN=0xfe;///P2.0模拟输入,漏极开路输出P2MDOUT=0xfe;P2SKIP=0xe1;///P2.1--P2.4不被交叉开关跳过P3MDIN=0xff;P3MDOUT=0xff;P3SKIP=0xfe;P4MDOUT=0xff;XBR0=0x03;///UART连接到端口引脚,使能SPI总线XBR1=0xc0;SFRPAGE=0x00;return;}/////////////////////////内部振荡器初始化voidosc_init(void){SFRPAGE=0x0f;OSCICL=OSCICL+4;OSCICN=0xc2;OSCXCN=0x00;CLKSEL=0x00;SFRPAGE=0x00;return;}/////////////////////////外部数据存储器初始化voidxram_init(void){SFRPAGE=0x0f;EMI0CF=0x07;SFRPAGE=0x00;return;}/////////////////////////外部中断初始化voidint01_init(void){IT01CF=0x65;IT0=1;IT1=1;EX0=1;EX1=0;return;}/////////////////////////定时器初始化voidtimer_init(void){TMOD=0X11;CKCON=0X00;TH0=(65536-10000)/256;///T0定时10MsTL0=(65536-10000)%256;//TL1=0X0C;//TH1=0XFE;TMR2CN=0X04;TMR2RLL=0X83;///T3,T3定时0.125msTMR2RLH=0XFF;TMR3CN=0X0C;TMR3RLL=0X83;TMR3RLH=0XFF;//TR0=1;//TR1=1;return;}/////////////////////////中断系统初始化voidinterrupt_init(void){EX0=1;///允许INT0中断PX0=1;///INT0高优先级ET0=1;//ET1=1;ES0=1;//IE0=0;EA=1;return;}/////////////////////////PCA初始化voidpca_init(void){PCA0CN=0X40;return;}/////////////////////////异步串口通信接口初始化voiduar_init(void){SCON0=0X00;return;}/////////////////////////延时子程序voiddelay(unsignedintt){unsignedinti,j;for(i=0;it;i++)for(j=0;j100;j++)return;}/////////////////////////检查BF标志位子程序voidCheck_Lcd(){unchartemp=0x00;uncharxdata*addr;while(1){addr=RCOMADDR;temp=*addr;temp&=0x80;if(temp==0x00)break;}return;}/////////////////////////LCD写指令子程序voidWrite_Com(uncharn){uncharxdata*addr;Check_Lcd();addr=WCOMADDR;*addr=n;return;}/////////////////////////LCD写数据子程序voidWrite_Data(uncharm){uncharxdata*addr;Check_Lcd();addr=WDATAD