4 系统软件设计
4.1 系统软件结构
整个程序包括主程序和延时子程序以及ISD语音录放程序等几部分。STC89C52RC单片机提供了用户按键、显示和ISD4004所需接口。它接收击键功作,并将相应指令传给ISD4004,同时监控ISD4004的中断输出。当开关闭合时,读取ISD4004的状态寄存器,从而根据OVF和EOM的状态进行相应的处理。当OVF=1,即存储器溢出时,则不管当前为何种状态均将ISD4004的地址置零,并继续运行原指令;当EOM=1时,当前状态只可能为放音或快进,若为快进则置为放音态,并继续运行。如此设计便实现了循环录放的功能,同时在快进时,自动停止在下一个语音段开始处,并继续放音。流程图如图4.1所示。
21
图4.1主程序开始 流程图 程序就是为计算机某一算式或完成某一工作的若干指令的有序集合。计算机的全部工作概括起来就是执行这一指令序列的过成。这一指令序列称为程序。主程序主要调用了4个子程序,分别是延时子单片机语音芯片初始化 设置允许外部中断T0, 并打开全局中断允许位 程序、ISD4004语音录放程序、LED点阵显示子程序、中断控制程序等。 4.2 系统软件设计 按键扫描 PR是否为1? N Play模式 N Y REC模式 按键是否按下? Y N 按键是否按下? 4.2.1 延时设计 录音播放 Y 语音录制 N Y 汉字滚动显示 为了精确的控制单总线N 接口的特殊时序要求,延时函停止键是否按下? Y 停止键是否按下? 数是相当关键
22
的,它是所有读控制和写控制的组成部分以及显示时延时用;下面us的延时(12M)延时子程序和ms的延时(12M)延时子程序。 void delay1(void) {
int16 i;
for (i=0;i<50;i++) ; }
void delay(unsigned int time) //延时n微秒 {while(time!=0) {time--; } }
void delayms(unsigned char g){/*延时gms*/ unsigned char i,j; }
for(i=0;i 4.2.2 语音录放设计 //*********************************** //入口:放音位置的高低位 //放音程序 //功能:从指定位置放音 //*********************************** void play(unsigned char adl,unsigned char adh) { unsigned char ovflog; while(AN == 0) {;} isd_setplay(adl,adh); //发送setplay指令,从0x0000地址开始放音 do 23 { isd_play(); //发送放音指令 delay(20); while(ISD_INT == 1) //等待放音完毕的EOM中断信号 {;} LED2 = 1; isd_stop(); //放音完毕,发送stop指令 if(ovflog == chk_isdovf()) //检查芯片是否溢出,如溢出则停止放音,芯片复位 break; while(AN == 1) //等待AN键再次按下 { if(STOP == 0) break; if(AN == 0) delayms(20); } }while(AN == 0); //An键再次按下,播放下一段语音 } 4.2.3 中断控制设计 中断定时控制程序,对LED点阵动态扫描进行控制,同时也对汉字显示进行中断控制,让汉字可以按照从右至左的顺序进行滚动显示。 /*****定时器T0中断子程序*******/ void timer0() interrupt 1 using 3 { TF0=0; TH0=0xb1; TL0=0xe0; if (n<10) { n++; } else 24 { offset+=2; if (offset>860) offset=0; n=0; } } 4.2.4 LED点阵汉字显示设计 该程序段主要完成向LED点阵点阵动态扫描显示,控制系统的汉字显示部分。 /*********汉字显示函数**************/ while (1) { for (i=0;i<8;i++) //显示左半边屏幕 { P0=*(p+offset+2*i); P2=i|0x08; //P2.4=0,P2.3=1 选中U2, 输出扫描码给U6 delay1(); P0=*(p+offset+2*i+1); P2=i|0x10; //P2.4=1,P2.3=0 选中U3, 输出扫描码给U7 delay1(); } for (i=8;i<16;i++) //显示右半边屏幕 { P0=*(p+offset+2*i); P2=(i-8)|0x20; //P2.5=1 P2.4=0, P2.3=0 选中U4,输出扫描码U8 delay1(); P0=*(p+offset+2*i+1); P2=(i-8)|0x40; / /P2.6=1 P2.5=0, P2.4=0 选中U5,输出扫描码U9 delay1(); } 25