湖南工业科技职工大学 毕业设计(论文)
题 目 语音电子时钟 作 者 张浩 年 级 专 业 机电一体化 办学地点 指导老师 赖强 成 绩
年 月 日
湖南工业科技职工大学
毕业论文鉴定意见
实际完成时间: 年 月 日至 年 月 日
论文题目:语音电子时钟 内容提要:世界上的东西都是为人服务的,所以所有产品都要更 加人性化。此款语音电子钟是专为情侣设计的,它当你有什么话说不 出口时,或是给对方造成伤害的拒绝都可以用这种方法,把要说的话 录在语音芯片中然后把它当作礼物送给对方,同时给闹钟定时就可以 了。 上面所说的语音芯片是ISD4002-120,通过DS12C887的闹钟中 断控制ISD4002放音。本来要选用录放时间更长的ISD4004-16M,但 程序调试过程中其音频输出引脚损坏,故改用已有的ISD4002,其中 难点是ISD4002的地址输入控制程序的编写等。其次调试时尽量保证 电路焊接正确,尤其是ISD4002的录音电路,DS12C887无外围芯片, 故简单;显示用HG12864带字库的液晶,除正常时钟显示外还可以节 日提提醒,录放音时间提示等。 关键词:语音芯片ISD4002、时钟芯片DS12C887、HG12864液晶、LM386音频功 放、STC89C51RC单片机。 指 导 教 师 评 语 : 指导教师(签字) 日期 答辩委员会(评审小组)意见: 评 定 成 绩 答辩委员会主任 (评审小组组长) 日期: 年 月 日
目 录
一、 项目实现的功能------------------------------第1页 二、 所选各器件及介绍----------------------------第2页 (1)STC89C52RC---------------------------------第2页 (2)DS12C887-----------------------------------第页 (3)ISD4002-120--------------------------------第页 (4)HG1286412-B--------------------------------第页 (5)音频功放LM386-----------------------------第页 (6)电压转换芯片ht7133-A和LM78L05------------第页 (7)电平转换芯片MAX232------------------------第页 三、硬件电路设计--------------------------------第页 (1)单片机和语音芯片电源设计------------------第页 (2)单片机最小系统设计------------------------第页 (3)TTL到RS232的电平转换电路-----------------第页 (4)ISD4002电源设计---------------------------第页 (5)ISD4002的录音电路设计---------------------第页 (6)ISD4002的放音电路(功放)------------------- 第页 (7)DS12C887电路设计--------------------------第页 (8)HG12864电路设计---------------------------第页 (9)键盘电路设计-------------------------------第页 四、软件设计及调试------------------------------第页 (1)头文件及引脚定义-------------------------第页 (2)ISD4002控制程序--------------------------第页 (3)HG12864控制程序--------------------------第页 (4)DS12C887控制程序-------------------------第页
(5)节日提醒程序------------------------------第页 (6)闹钟和时间、日期的读取及显示-------------第页
(7)图片显示---------------------------------第页 (8)按键扫描程序-----------------------------第页 (9)开机初始化程序---------------------------第页 (10)主函数----------------------------------第页
已经有很多人做过电子时钟了,多说无义,学生就要从实践中获得经验,这既是自己的需要更是社会的需要,为此我们要多做一些自己感兴趣的实践项目来提高自己从而更加从容的成为社会需要的人才。
一、 项目功能的实现
(1) 在HG12864液晶上显示年、月、日、时、分、秒、星期及节日提醒话语和
录放音提示的相关操作。
(2) 具有闹钟及到时响铃功能,报警响起时按除录放音及地址选择键时闹钟停
止报警。
(3) 设三个键调整闹钟,分别是时、分的加减和功能选择;另设三个录音、放
音和录放音地址选择键。
(4) 还可以设置按键音(但此程序没无此功能);利用DS12C887掉电可继续走
时的特性,可实现断电不停,上电后仍可准确走时的功能。
二、 所选各器件及介绍
(1)STC89C52RC的介绍
STC89C52RC是STC公生产的以8051为内核芯片的单片机:内部含有Flash E2PROM存储器;内部含有关8K的程序存储空间;内部RAM(随机读写存储器)为512位;具有可ISP可在线编程功能,不用买昂贵的编程器,只需搭建简单的TTL—RS232的电平转换电路,很适合学无经济基础的毕业生,这里选用美信公司的MAX232芯片;DIP—40封装。引脚定义参照其date sheet。
(2)DS12C887介绍
DS12C887时钟芯片能够自动产生世纪、年、月、日、时、分、秒等时间信息,其内部有世纪寄存器,从而利用硬件电路解决“千年”问题。DS12C887中自带锂电池,外部掉电时其内部信息还可以保持10年之久,这样就可以不用调整时,分、秒等一些参数,少一些按键。但各数据要在初始化时设置正确。对于一于内的时间记录有12小时制和24小时制两种模式。在12小时模式中用AM和PM区分上午和下午。芯片内部的存储格式也有两种,一种用二进制表示一种是用BCD码表示。DS12C887的时钟芯片带有128位RAM,其中之11位用来存储时间信息;4位RAM用来存储DS12C887的控制信息,称为控制寄存器;113位RAM供用户使用。此外用户还对DS12C887编程实现多种方波的输出,并可对其内部的三路中断通过软件进行屏蔽。该芯片内部有一个精密的温度补偿电路,用来监视VCC的状态,如果检测到主电源的故障,该器件可以自动切换到备用电源供电。VBACKUP用于支持可充电电池或超级电容,内部包括一个始终有效的涓流充电器。DS12C887可以通过一个多路复用的单字节接口访问,该接口支持Intel和Motorola模式。DS12C887将它自己与石英晶体和电池集成在一起。引脚定义及操作时序参照其date sheet。
(3)ISD400X介绍
ISD400X系列语音芯片工作电压3V,单片录放时间为8—16分钟,音质好,适用于移动电话及其他便携式电子产品。芯片采用CMOS技术,内含振荡器,防混淆滤波器、平滑滤波器、音频放大器、自动静噪及高密度多电平闪烁存储阵列。芯片设计是基于所有操作基于微控制器控制,操作命令可通过串行通信接(SPI或Microwire)送入。芯片采用多电平直接模拟存储技术,每个采样值直接存储到片内闪烁存储器中,因此能够非常真实的自然的再现语音、音乐、音调等,避免了一般固体录音电路因量化和压缩造成的量化造声和“金属声”,采样频率可为4.0KHz,5.3KHz,6.4KHz,8.0KHz,频率越低录放时间越长,而音质则有所下降,片内信息存于闪烁存储器中,在掉电的情况下保存一百年以上,可反复录音10万次以上。重点是对其寻址程序的编写,地址范围是0-600。引脚定义及操作时序参照其date sheet。
(5) HG12864介绍
本实验用的12864液晶使用ST7920控制器,5V电压驱动,带背光,内置8192个16*16点阵,128个字符(8*16点阵)及64*256点阵显示RAM(GDRAM),这样就可以为单片机节省很多系统资源。与外部CPU接口采用并行(本实验采用并行操作时序)或串行两种控制方式。操作时序和控制码请参照date sheet。
(6)音频功放LM386介绍
该器件采用8引脚双列直插式封装开式,5V电压供电,该器件具有静态电流小,电源电压范围宽,失真度低,电压增益可调和失真度低等特点。适用于收音机、对讲机中作音频放大器。
(7) 电压转换芯片7133-A和LM78L05
图1.1 Lm78l05连接原理图
图1.2 ht7133连接原理图
在本系统中使用7133—A为ISD4002提供3.3V电压,输入电压为5V,使用LM78L05为单片机及整个系统提供电源。正常用工作时7805的输入输出电压
差为2—3V,本系统采用12V输入电压,其次还要根据输出电流的大小选择合适的散热器,否则会由于过热而无法达到额定工作电流。
三、 硬件电路设计
(1) 单片机电源设计
图1.3单片机电源电路
图1.3的左边为lm78l05组成的稳压电路,两个滤波电容的典型值请参照 图1.2。但据实际经验采用0.1uf的电容。lm78l05输入端为12V,输入和输出接线时注意正负!
图1.4 ISD4002电源电路
需要注意的是:电源VCCD,VCCA是芯片内部数字电路电源正极引脚和模拟电源正极引脚。为使噪声减小,芯片的模拟和数字电路最好使用不同的电源供电,并且分别引到外封装的不同引脚上,模拟和数字电源端最好分别走线,尽可能在靠近供电端处相连,而去耦电容应尽量靠近器件。系统的模拟地和数字地也最好分
别接地。
(2)单片机最小系统设计
图1.5 单片机最小系统
主要完成对从时钟芯片读取信息并进行处理;控制语音芯片录放音及录放音的起始地址。刚开始时感觉这很神秘,可照电路图做出来后竟然可以工作,所以硬件不是很难,重要的是你得动手去做。图1.5是实验的单片机最小系统,和其他的单片机最小系统也是一样的。两个22pf的电容是从废旧的板子上的单片机系统电路拆下来的,但我拆的是贴片电容,并不知道具体的容量,晶振是11.0592MHZ。复位电路采用按键复位,这样复位时可以不用掉电。
(3)TTL到RS232的电平转换电路
前文忘记介绍MAX232了,因为它不是时钟的一部分,它与单片机及电脑的连接如图1.6,但要注意硬件连线的正确,否则很难达到想要的效果将程序下载进去,一定要确定用的是什么样的串口下载线,是平行的还是交叉的。STC单片机是上电检测是否需要下载程序到用户程序区,所以下载时要断电然后下载程序再上电。
图1.6 TTL到RS232的电平转换电路
(4)ISD4002录音电路设计
图1.7 ISD4002的录音电路
主要完成对语音信号的采集,存储及输出。模拟信号的输入可以用单位端或差分驱动。此种电路用的ISD4002的差分驱动,录音信号的最大幅度为峰峰值16mV。话筒为驻极体话筒,驻极体话筒体积小,结构简单,电声性能好,价格低廉。还要注意驻极体话筒的正负极。
(5)ISD4002放音电路设计
图1.8 ISD4002放音电路
图1.8为LM386的语音放大电路,主要对语音芯片输出的语音信号进行放大处理。通过改变增益端的接法可以得到不同的电压增益,当脚1和8脚开路时电压增益为20,若在接一电容增益可达200,若串接电阻元件则增益可在20到200之间选取,电阻越小增益越大。
(6) DS12C887电路设计
图1.9 DS12C887电路
主要完成对时间信息的生成,时钟电路是最简单的,不用连接多余的外围元件,只需接电源即可。复位电路为上电复位,通信方式选Intel模式。
(7) HG12864液晶电路设计
图2.0 HG12864液晶电路
主要完成对时时时间信息的显示,年、月、日、时、分、秒等,尽量让一些功能有可见提示。本来Vo端要接调节电位器的,但难以在现有的材料中找到,故实际电路中让它直接与电源相连,复位路也是上电复位,RST端直接接高电平。
(8)键盘电路设计
采用独立式键盘,根据时钟要完成的功能设7个按键,分别是闹钟的时和分的调查整选择,时和分的加减,录音地址的选择,放音,录音及停止键。连接
方式如图2.1。
图2.1 键盘电路
四、 软件设计
(1)头文件及引脚定义
#include #define uchar unsigned char #define uint unsigned int uchar hh=0,mm=0,ss=0,year=0,month=0,day=0,week=1,a=0,nhh=0,nmm=0,n=0; uchar max,min,d,flag1=0,ad=0,i=0,f=0,g=0,go; uint c=0,e=0; bit w=0,flag=0; void xiao(); sbit dscs=P2^0; //各 sbit dsrw=P2^2; //芯 sbit dsas=P2^1; //片 sbit dsds=P2^3; //的 sbit lcdrw=P2^5; //引 sbit lcden=P2^6; //脚 sbit lcdrs=P2^4; sbit beep=P2^7; sbit s1=P1^0; //位置选择。 sbit s2=P1^1; //按键加。 sbit s3=P1^2; //按键减。 sbit s4=P1^3; sbit s5=P1^4; //录音 sbit s6=P1^5; //放音 sbit s7=P1^6; sbit ssisd=P1^7; sbit mosisd=P3^0; sbit misoisd=P3^1; sbit sclkisd=P3^3; sbit intisd=P3^5; sbit racisd=P3^4; void lcd_ss(); //函数声明 void delay(uint z) //延时程序 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } (2)ISD4002控制程序 //为什么输入的命令全是16位的,因为单片机模拟SPI输入端一次输入就是16位,所以和地址相与也必须是16位的命令。 void writeisd_4002(uint data16) //通过SPI总线向4002写16位数据 { ssisd=1; ssisd=0; //使能4002 sclkisd=0; //时钟线拉高 for(i=0;i<16;i++) { mosisd=data16&0x0001; //关键 sclkisd=0; //时钟线拉低 delay(1); sclkisd=1; //时钟线拉高 data16>>=1; //数据移位 } ssisd=1; //禁止4002 } void record4002(uint addr) //录音,addr为地址,key键保持按下时录音持续 { writeisd_4002(0x2000); delay(25); writeisd_4002(0x2000); delay(50); writeisd_4002(addr|0xa000); //设置录音起始地址 writeisd_4002(0xb000); //录音命令 } void fangyin(uint addr) //放音,addr为地址,del为放音等待时间(试听决定) { writeisd_4002(0x2000); delay(25); writeisd_4002(addr|0xe000); //设置放音起始地址 writeisd_4002(0xf000); //放音命令 } (3)HG12864液晶控制程序 void write_com(uchar com) { lcdrs=0; lcdrw=0; lcden=0; P0=com; lcden=1; delay(5); lcden=0; } void write_dat(uint dat) { lcdrs=1; lcdrw=0; lcden=0; P0=dat; lcden=1; delay(5); lcden=0; } void lcd_pos(uchar x,uchar y) { uchar pos; if(x==0) { x=0x80; } else if(x==1) { x=0x90; } else if(x==2) { x=0x88; //写LCD命令! //写LCD数据。 //变换显示地址。 } else if(x==3) { x=0x98; } pos=x+y; write_com(pos); } void lcd_init() //LCD初始化 { write_com(0x30); //基本指令操作 delay(5); write_com(0x0c); //显示开,关光标 delay(5); write_com(0x01); //清除LCD的显示内容 delay(5); } void write_word(uchar *str) //向LCD中写入字符串 { while(*str!='\\0') //检测字符串结束标志 { write_dat(*str); str++; } } (4)DS12C887控制程序 void write_ds(uchar add,uchar dat) //写DS12C887数据,写数据时要先发送地址。 { dsds=1; dsas=1; dsrw=1; dscs=0; P0=add; dsas=0; dsrw=0; P0=dat; dsas=1; dsrw=1; dscs=1; } uchar read_ds(uchar add) //读取DS12C887,时,分,秒,也要先写地址。 { } uchar dat; dscs=0; dsas=1; dsds=1; dsrw=1; P0=add; dsas=0; dsds=0; P0=0xff; dat=P0; dsas=1; dsds=1; dscs=1; return dat; (5)节日提醒程序 void warning() { lcd_pos(3,0); switch (month) { case 1: if(day== 1) {write_word(\"Happy New Year\");} if(day==28) {write_word(\" 世界麻风日 \");} break; case 2: if(day==02) {write_word(\" 世界湿地日 \");} else if(day==13) {write_word(\" 明天情人节 \");} else if(day==14) {write_word(\" 该死的情人节 \");} break; case 3: if(day== 1) {write_word(\" 国际海豹日 \");} else if(day== 3) {write_word(\" 全国爱耳日 \");} else if(day== 8) {write_word(\" 三八妇女节 \");} else if(day==12) {write_word(\" 植树节 \");} else if(day==14) {write_word(\" 国际警察日 \");} else if(day==15) {write_word(\"消费者权益保护日\");} else if(day==17) {write_word(\" 国际航海日 \");} else if(day==21) {write_word(\" 世界森林日 \");} else if(day==22) {write_word(\" 世界水日 \");} break; case 4: if(day== 1) {write_word(\" 禺人节 \");} else if(day== 5) {write_word(\" 清明 \");} else if(day== 8) {write_word(\" 复活节 \");} else if(day==13) {write_word(\" 黑色星期五 \");} break; case 5: if(day== 6) {write_word(\" 国际劳动节 \");} else if(day== 4) {write_word(\" 青年节 \");} else if(day== 8) {write_word(\" 世界红十字日\");} else if(day==12) {write_word(\" 国际护士节 \");} else if((day<15)&&week==2) {write_word(\" 近日母亲节 \");} else if(day==15) {write_word(\" 国际家庭日 \");} else if(day==31) {write_word(\" 世界无烟日 \");} break; case 6: if(day== 1) {write_word(\" else if(day== 5) {write_word(\" else if(day== 6) {write_word(\" else if(day==13) {write_word(\" else if(day==15) {write_word(\" else if(day==26) {write_word(\" break; case 7: if(day== 1) {write_word(\" else if(day== 7) {write_word(\" else if(day==11) {write_word(\" break; case 8: if(day== 1) {write_word(\" else if(day== 8) {write_word(\" else if(day==15) {write_word(\" break; case 9: if(day==10) {write_word(\" else if(day==18) {write_word(\" else if(day==20) {write_word(\" else if(day==27) {write_word(\" break; case 10:if(day== 1) {write_word(\" else if(day== 4) {write_word(\" else if(day==13) {write_word(\" else if(day==24) {write_word(\" break; case 11:if(day==10) {write_word(\" if(day==17) {write_word(\" break; case 12:if(day== 1) {write_word(\" else if(day==23) {write_word(\" else if(day==24) {write_word(\" else if(day==25) {write_word(\" else if(day==31) {write_word(\" break; 国际六一儿童节\");} 世界环境日 \");} 全国爱眼日 \");} 近日父亲节 \");} 祝父亲们节日快乐\");} 国际禁毒日 \");} 共产党诞生 \");} 纪念七七事变 \");} 世界人口日 \");} 八一建军节 \");} 中国男子节 \");} 抗日战争胜利 \");} 中国教师节 \");} 纪念九一八事变\");} 国际爱牙日 \");} 世界旅游日 \");} 国庆 \");} 世界动物日 \");} 国际教师节 \");} 联合国日 \");} 世界青年节 \");} 世界学生节 \");} 世界艾滋病日 \");} 明晚平安夜 \");} 今晚平安夜 \");} 圣诞快乐 \");} 新年快乐 \");} } } (6)闹钟和时间、日期的读取及显示 void lcd_nz_h() { nhh=read_ds(5); lcd_pos(1,3); write_dat(nhh/10+0x30); write_dat(nhh%10+0x30); } void lcd_nz_m() { nmm=read_ds(3); lcd_pos(1,4); write_dat(0x3a); write_dat(nmm/10+0x30); write_dat(nmm%10+0x30); } void lcd_hh() { hh=read_ds(4); lcd_pos(1,0); write_dat(hh/10+0x30); write_dat(hh%10+0x30); } void lcd_mm() { mm=read_ds(2); lcd_pos(1,1); write_dat(0x30+0x0a); write_dat(mm/10+0x30); write_dat(mm%10+0x30); write_dat(0x30+0x0a); } void lcd_year() { year=read_ds(9); lcd_pos(0,2); write_dat(year/10+0x30); write_dat(year%10+0x30); } void lcd_month() { month=read_ds(8); //读闹钟时并显示 //读闹钟分并显示 //时显示 //分显示 //年显示 //月显示 lcd_pos(0,3); write_dat(0x20+0x0d); write_dat(month/10+0x30); write_dat(month%10+0x30); write_dat(0x20+0x0d); } void lcd_day() //日显示 { // f=day; day=read_ds(7); lcd_pos(0,5); write_dat(day/10+0x30); write_dat(day%10+0x30); warning(); } void lcd_week() //星期显示 { week=read_ds(0x06); lcd_pos(1,4); write_word(\"星期\"); if(week==1) {write_word(\"一\");} if(week==2) {write_word(\"二\");} if(week==3) {write_word(\"三\");} if(week==4) {write_word(\"四\");} if(week==5) {write_word(\"五\");} if(week==6) {write_word(\"六\");} if(week==7) {write_word(\"日\");} } void lcd_ss() //秒显示 { a=ss; //录放音,及笑脸和心形显示标志 ss=read_ds(0); lcd_pos(1,3); write_dat(ss/10+0x30); write_dat(ss%10+0x30); xiao(); } //更新LCD显示 void update_lcd() { lcd_hh(); //时 lcd_mm(); //分 lcd_ss(); //秒 } lcd_year(); lcd_month(); lcd_day(); lcd_week(); //年 //月 //日 //星期 (7)图片显示 void xiao() //利用HG12864液晶内自带的图象字库循环显示一些图片 { uchar i; if(a!=ss) { if(flag1==0) { i++; //i不会和writeisd4002中的I有冲突 switch (i) { case 1: lcd_pos(0,0); write_dat(0x20); write_dat(0x02); break; case 2: lcd_pos(0,0); write_dat(0x03); write_dat(0x20); break; case 3: lcd_pos(0,0); write_dat(0x20); write_dat(0x05); break; case 4: lcd_pos(0,0); write_dat(0x06); write_dat(0x20); i=0; break; default : i=0;break; } } else if(flag1==1) { lcd_pos(0,0); write_word(\"录\"); //录放音显示及相应时间提示 e++; //录音时间 lcd_pos(0,6); write_dat(0x20); write_dat(e/100+0x30); write_dat(e%100/10+0x30); write_dat(e%100%10+0x30); } else if(flag1==2) { lcd_pos(0,0); write_word(\"放\"); e++; //放音时间 lcd_pos(0,6); write_dat(0x20); write_dat(e/100+0x30); write_dat(e%100/10+0x30); write_dat(e%100%10+0x30); } } } void set_time() //闹钟时主,分相关参数及显示 { switch (n) { case 1: w=1; write_com(0x01); lcd_nz_h(); lcd_nz_m(); break; case 2:go=nmm;ad=3; max=59;min=0; lcd_pos(1,6); write_word(\"调分\"); break; case 3:go=nhh;ad=5; max=23;min=0; lcd_pos(1,1); write_word(\"调时\"); lcd_pos(1,6); write_dat(0x20); write_dat(0x20);write_dat(0x20);write_dat(0x20); break; } } (8)按键扫描程序 keyscan() { uchar i; if((flag==1)&&(n==0)) //关停闹钟(S1—S7任意键) { if((s1==0)||(s2==0)||(s3==0)||(s4==0)||(s5==0)||(s6==0)||(s7==0)) { delay(10); if((s1==0)||(s2==0)||(s3==0)||(s4==0)||(s5==0)||(s6==0)||(s7==0)) { while(!s1||!s2||!s3||!s4||!s5||!s6||!s7); writeisd_4002(0x3000); delay(10); flag=0; } } } if((s1==0)&&(flag==0))//闹钟调整选择 { delay(10); if(s1==0) } { while(!s1); n++; set_time(); if(n==4) {n=0;w=0; //清除闹钟调整显示 write_com(0x01); lcd_pos(0,1); write_dat(0x32); //固定显示20,年份 write_dat(0x30); } } if((n!=0)&&(flag==0)) //闹钟加 { if(s2==0) { delay(10); if(s2==0) { while(!s2); go++; if(go>max) go=min; write_ds(ad,go); } } } if((n!=0)&&(flag==0)) //闹钟减 { if(s3==0) { delay(10); if(s3==0); { while(!s3); go--; if(go==-1) go=max; write_ds(ad,go); //把闹钟值写进时钟芯片 } } } if(w==1) { lcd_nz_h(); //显示闹钟小时,及分 lcd_nz_m(); } if((n==0)&&(flag==0)) { if(s4==0) //录音及放音地址选择。和闹钟时间标志 { delay(5); if(s4==0) { while(!s4); i++; switch (i) { case 1: d=0; lcd_pos(1,7);write_dat(0x30+1);write_dat(0x30+2);break; case 2: d=150; lcd_pos(1,7);write_dat(0x30+1);write_dat(0x30+5);break; case 3: d=300; lcd_pos(1,7);write_dat(0x30+1);write_dat(0x30+8);break; case 4: d=450; lcd_pos(1,7);write_dat(0x30+2);write_dat(0x30+1);break; case 5: i=0,lcd_pos(1,7);write_word(\" \");break; } } } if(s5==0) //从指定地址开始录音,并显示录音字符(标志)及录音时间提示。 { delay(5); if(s5==0) { while(!s5); flag1=1; //录放音调整标志, e=0; record4002(d); //调查用录音函数。 } } if(s6==0) //放音开始并显示放音标志 { delay(5); if(s6==0) { while(!s6); fangyin(d); e=0; flag1=2; //录放音调整标志, } } if(s7==0) //STOP停止录音放音等并停止显示录音提示及录音时间,放音提示。 { delay(5); if(s7==0) { while(!s7); writeisd_4002(0x2000); //没有测试,可能不需要 delay(25); writeisd_4002(0x3000); //停止命令行禁止 e=0; lcd_pos(0,6); write_word(\" \");//可以写一些表明自己的东西。 flag1=0; } } } } void nz() interrupt 0 { uchar c; flag=1; //闹钟停止标志,如果flag=1则进入中断,则 // lcd_pos(2,1); // write_word(\"已进入中断\"); //测试进入中断标志 // w=1; //想在中断时显示一幅图片所以停止显示时间,需完善。 fangyin(d); //放音命令 c=read_ds(0x0c); //消除中断信号 } (9)开机初始化程序 void init() { EA=1; EX0=1;IT0=1; } /*void kaiji() //闹钟中断 //开机显示图画猴子 { uchar y,b; write_com(0x34); y=0x80; for(i=0;i<32;i++) { write_com(y++); write_com(0x80); for(b=0;b<16;b++) { write_dat(table[++c]); } } y=0x80; for(i=0;i<32;i++) { write_com(y++); write_com(0x88); for(b=0;b<16;b++) { write_dat(table[++c]); } } write_com(0x36); delay(2000); write_com(0x34); write_com(0x30); }*/ (10)主函数 void main() { /* write_ds(0,0); //时钟芯片初始化,也可以放在开机初始化中 write_ds(1,0); write_ds(2,1); write_ds(3,0); write_ds(4,11); write_ds(5,0); write_ds(6,3); write_ds(7,26); write_ds(8,4); write_ds(9,10); */ /*write_ds(0x0a,0x20); //开启时钟芯片的振荡器及时间中断 write_ds(0x0b,0x26);*/ lcd_init(); init(); lcd_pos(0,1); write_dat(0x32); write_dat(0x30); writeisd_4002(0x2000); //加上电指令后4002的工作才和串口线无关 delay(25); writeisd_4002(0x2000); delay(50); while(1) { if(w!=1&&n==0) { update_lcd(); keyscan(); } else { keyscan();} } } ISD4002一定要加初始化程序,否则不能正常工作。此程序包含在开机时显示一幅猴子的图画,有的地方可以做得很生动,可以尽可能的发挥自己的想像。遇到的一些困难:各元件的资料均需从网上下载。刚开始时不知道图表该怎样做上去,后来才用截图工具把用PROTELL画的电路原理图分块截取下来并和一些在网上下载的图用WINDOWS自带的画图工具进行编辑。 参考文献: 郭天祥.51单片机C语言教程—入门、提高、开发、拓展全攻略.北京:电子工业出版社,2009.1 因篇幅问题不能全部显示,请点此查看更多更全内容