单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc

上传人:laozhun 文档编号:4147437 上传时间:2023-04-07 格式:DOC 页数:28 大小:382.50KB
返回 下载 相关 举报
单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc_第1页
第1页 / 共28页
单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc_第2页
第2页 / 共28页
单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc_第3页
第3页 / 共28页
单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc_第4页
第4页 / 共28页
单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc_第5页
第5页 / 共28页
点击查看更多>>
资源描述

《单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc》由会员分享,可在线阅读,更多相关《单片机最小应用系统设计报告用8051单片机定时器产生乐谱的各种频率方波.doc(28页珍藏版)》请在三一办公上搜索。

1、 电 子 科 技 大 学微 机 单 片 机 接 口设计报告指导老师: 学 生: 学 号: 电子科技大学机电工程学院2009年5月单片机最小应用系统设计报告一、设计题目1二、设计目的1三、系统硬件图23.1 电路设计原理图23.2 电路设计PCB图4四、程序流程图6五、系统说明与分析95.1设计思路及设计过程95.2系统结构及各部分说明95.3系统连线说明165.4系统参数分析17六、源程序17七、总结25八、参考文献26一、设计题目用8051单片机定时器产生乐谱的各种频率方波,要求信号经过放大后由喇叭发出声音。可选取某段音乐令单片机连续播放。二、设计目的1、通过单片机最小系统的设计,了解常用单

2、片机应用系统开发手段和过程,进一步熟悉和掌握单片机的结构和工作原理,并能初步掌握一般单片机控制系统的编程和应用,从而进一步加深对单片机理论知识的理解。2、掌握单片机内部功能模块的应用:如定时器、计数器、中断系统、I/O口等。3、熟悉基本硬件电路的设计与制作。 4、掌握以单片机核心的电路设计的基本方法和技术,了解单片机的基本外围电路的设计和矩阵按键电路及数码管驱动电路的设计。5、学习UVISION对单片机的编程和调试方法。6、学习PROTEL软件的使用,掌PROTEL的基本用法,懂得绘制简单得原理图及其PCB的绘制。7、通过此次课程设计能够将单片机软硬件结合起来,对程序进行编辑,校验。三、系统硬

3、件图3.1 电路设计原理图整个设计主要包括单片机基本的晶振电路,按键复位电路。具体的电路图如下图所示:对于不同的电路模块进行了分别画图:下图是最小系统模块。功放模块:四乘四键盘模块:图1 电路原理图3.2 电路设计PCB图 本次小系统的设计要求设计的电路板实单面板,因为设计中电路板较小,二元器件的数目较多,尤其是矩阵按键部分需要的连线较多,所以本次设计的PCB 板中夹杂着几根跳线。PCB的生成,主要是在绘制好电路原理图之后,定义各个元器件的封装形式,生成网络表之后,在新建的PCB中导入网络表,即可一自动生成PCB。根据元器件之间的飞线,设置各个参数之后手动布线。本次设计的PCB图如图2所示。图

4、2 电路PCB图四、程序流程图 键盘扫描程序:4X4行列式键盘识别;音乐产生的方法;一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数T0相关的计数值如下表所示音符频率(HZ)简谱码(T值)音符频率(HZ)简谱码(T值)低1DO26263628# 4 FA#74064860#1DO#27763731中 5 SO7

5、8464898低2RE29463835# 5 SO#83164934#2 RE#31163928中 6 LA88064968低 3 M33064021# 693264994低 4 FA34964103中 7 SI98865030# 4 FA#37064185高 1 DO104665058低 5 SO39264260# 1 DO#110965085# 5 SO#41564331高 2 RE117565110低 6 LA44064400# 2 RE#124565134# 646664463高 3 M131865157低 7 SI49464524高 4 FA139765178中 1 DO523645

6、80# 4 FA#148065198# 1 DO#55464633高 5 SO156865217中 2 RE58764684# 5 SO#166165235# 2 RE#62264732高 6 LA176065252中 3 M65964777# 6186565268中 4 FA69864820高 7 SI196765283下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据低音019之间,中音在2039之间,高音在4059之间TABLE:DW 0,63628,63835,64021,64103,64260,64400,64524,0,0DW 0,63731,63928,

7、0,64185,64331,64463,0,0,0DW 0,64580,64684,64777,64820,64898,64968,65030,0,0DW 0,64633,64732,0,64860,64934,64994,0,0,0DW 0,65058,65110,65157,65178,65217,65252,65283,0,0DW 0,65085,65134,0,65198,65235,65268,0,0,0DW 02、音乐的音拍,一个节拍为单位(C调)曲调值DELAY曲调值DELAY调4/4125ms调4/462ms调3/4187ms调3/494ms调2/4250ms调2/4125ms

8、对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。下面就用AT89S51单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。在这个程序中用到了两个定时/计数器来完成的。其中T0用来产生音符频率,T1用来产生音拍。开始行列式键盘按键按下成功否?识别按键功能根据按键功能,装入音符数组值到T0中启动T0工作行列式键盘按键释放成功否?停止T0工作T0初始化并开中断允放T0中断T0中断入口根据音乐数组值重装TH0,TL0初值P1.0取反中断返回图3 程序流程图五、系统说明与分析5.1设计思路及设计过程设计的主要思想:矩阵式按键识别系统,为了节省单片机的I/O口,我们采用了一种“行扫描法”。

9、单片机的P3口用作键盘I/O口,键盘的列线接到P3口的低4位,键盘的行线接到P3口的高4位。列线P3.0-P3.3分别接有4个上拉电阻到正电源+5V,并把列线P3.0-P3.3设置为输入线,行线P3.4-P3.7设置为输出线。4根行线和4根列线形成16个相交点。按不同位置的按键的时候,在数码管上显示相应的键值。显示部分使用数码管显示键值,单片机的P0口作为数码管的驱动口。还包括单片机的基本外围电路,晶振电路和按键复位电路。系统机构如图4所示。 单片机显示电路键盘接口复位电路时钟电路图4系统结构图软件设计主要是通过UVISION软件使用C 语言进行编程。设计过程:1、 设计相应的电路原理图,编写

10、C语言程序;2、 在实验箱上进行程序调试;3、 程序通过调试后,使用绘图软件PROTEL99,绘制相应的原理图,进行元器件封装后,生成相应的PCB 图,对其进行布局整理和单面板布线;4、 打印PCB图,印制在电路板上,放入氯化铁溶液中进行腐蚀;5、 腐蚀电路板之后进行元器件的焊接工作,焊接相应的电源线;6、 通过试验箱和下载软件,将程序烧如到单片机中;7、 进行最终的软、硬件的调试,直至完成相应的功能。5.2系统结构及各部分说明本次设计的单片机最小系统包括:单片机AT89S51部分,矩阵按键识别部分,数码管显示部分以及软件设计部分。下面就针对个法儿部分的特点进行简要的说明。 1、单片机部分(1

11、)AT89S51介绍AT89S51单片机是美国ATMEL公司生产的低功耗,高性能CMOS 8位单片机,片内含4K bytes的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度,非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器,既可在线编程(ISP)也可用传统方法进行编程及通用8位微处理器于单片芯片中,ATMEL公司的功能强大,低价AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。图5 AT89S51引脚图AT89S51是一个低功耗,高性能CMOS 8位单片机,片内含8k Bytes ISP(In-system pr

12、ogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及89C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。AT89S51具有如下特点:40个引脚,8k Bytes Flash片内程序存储器,128 bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片

13、内时钟振荡器。AT89S51有两种节电运行模式:空闲模式和掉电模式。 空闲模式 在空闲模式下,CPU处于睡眠状态,振荡器和所有片内外围电路仍然有效。空闲模式可由软件设置进入(设IDL1)。在这种模式下,片内RAM和SFR中的内容保持不变。 空闲模式可通过任何一个允许中断或硬件复位退出。 若用硬件复位方式结束空闲模式,则在片内复位控制逻辑发生作用前长达约两个机器周期时间内,器件从断点处开始执行程序。片内硬件禁止访问内部RAM,但不禁止访问端口。为避免采用复位方式退出空闲模式时对端口的不应有的访问,在紧随设置进入空闲指令(即设IDL1)的后面,不能是写端口或外部RAM的指令。 掉电模式引起掉电模式

14、的指令是执行程序中的最后一条指令(使PD1的指令)。在掉电模式下,振荡器停止工作,CPU和片内所有外围部件均停止工作,但片内RAM和SFR中的内容保留不变,直到掉电模式结束。 退出掉电模式可用硬件复位或任何一个有效的外部中断INT0和INT1。复位可重新设置SFR中的内容,但不改变片内RAM中的内容。在Vcc电源恢复到正常值并维持足够长的时间之后,允许振荡器恢复并达到稳定,方可进行复位,以退出掉电模式。(2)晶振电路图6 系统晶振电路系统的时钟电路设计是采用的内部方式,即利用芯片内部的振荡电路(如图6所示)。AT89S单片机内部有一个用于构成振荡器的高增益反相放大器。引脚XTAL1和XTAL2

15、分别是此放大器的输入端和输出端。这个放大器与作为反馈元件的片外晶体谐振器一起构成一个自激振荡器。外接晶体谐振器以及电容C1和C2构成并联谐振电路,接在放大器的反馈回路中。对外接电容的值虽然没有严格的要求,但电容的大小会影响震荡器频率的高低、震荡器的稳定性、起振的快速性和温度的稳定性。因此,此系统电路的晶体振荡器的值为12MHz,电容应尽可能的选择陶瓷电容,电容值约为22F。在焊接刷电路板时,晶体振荡器和电容应尽可能安装得与单片机芯片靠近,以减少寄生电容,更好地保证震荡器稳定和可靠地工作。(3)按键复位电路复位电路的基本功能是:系统上电时提供复位信号,直至系统电源稳定后,撤销复位信号。为可靠起见

16、,电源稳定后还要经一定的延时才撤销复位信号,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。图7所示的复位电路可以实现上述基本功能。但解决不了电源毛刺(A点)和电源缓慢下降(电池电压不足)等问题 而且调整 RC 常数改变延时会令驱动能力变差。左边的电路为高电平复位有效 右边为低电平Sm为手动复位开关,Ch可避免高频谐波对电路的干扰。图7 按键复位电路2、矩阵按键识别部分(1)矩阵式键盘的结构与工作原理在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图8所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1

17、口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。列行图8 矩阵按键结构图矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程

18、方法如下所述。(2)矩阵式键盘的按键识别方法 矩阵式键盘识别按键的方法有两种: 一是行扫描法, 二是线反转法。这里只说明一下我们使用的方法“行扫描法”。行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。 判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平

19、时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。(3)按键去抖当用手按下一个键时,如图9所示,往往按键在闭合位置和断开位置之间跳几下才稳定到闭合状态的情况;在释放一个键时,也回会出现类似的情况。这就是抖动。抖动的持续时间随键盘材料和操作员而异,不过通常总是不大于10ms。很容易想到,抖动问题不解决就会引起对闭合键的识别。用软件方法可以很容易地解决抖动问题,这就是通过延迟10ms来等待抖动消失,这之后,在读入键盘码。键按下前沿抖动后沿抖动闭合稳定图9 键抖动信号波形(4)键编码及键值用键盘连接的I/O

20、线的二进制组合表示键码。例如用4行、4列线构成的16个键的键盘,可使用一个8位I/O口线的高、低4位口线的二进制数的组合表示16个键的编码,如图所示。各键相应的键值为88H、84H、82H、81H、48H、44H、42H、41H、28H、24H、22H、21H、18H、14H、12H、11H。这种键值编码软件较为简单直观,但离散性大,不便安排散转程序的入口地址。顺序排列键编码。如图所示。这种方法,键值的形成要根据I/O线的状态作相应处理。键码可按下式形成:键码=行首键码+列号。编码相互转换可通过计算或查表的方法实现。3、显示电路显示器普遍地用于直观地显示数字系统的运行状态和工作数据,按照材料及

21、生产工艺,单片机应用系统中常用的显示器有: 发光二极管LED显示器、液晶LCD显示器、CRT显示器等。LED显示器是现在最常用的显示器之一,如右图。七段数码管在工业控制中有着很广泛的应用,例如用来显示温度、数量、重量、日期、时间,还可以用来显示比赛的比分等,具有显示醒目、直观的优点。 图10 数码管LED显示器的显示控制方式按驱动方式可分成静态显示方式和动态显示方式两种。对于多位LED显示器,通常都是采用静态方法进行显示,其硬件连接方式如系统原理图。数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数字,因此根据数码管的驱动方式的不同,可以分为静态式和动态式两类。 静态

22、显示驱动:静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5840根I/O端口来驱动,要知道一个89S51单片机可用的I/O端口才32个呢:),实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。 动态显示驱动:数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划a,b,c,d,e,f,g,dp的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路

23、,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为12ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功

24、耗更低。数码管使用条件:段及小数点上加限流电阻;使用电压:段:根据发光颜色决定; 小数点:根据发光颜色决定;使用电流:静态:总电流 80mA(每段 10mA);动态:平均电流 4-5mA 峰值电流 100mA。4、软件设计部分(1)键盘扫描程序的设计:假定图中列2行1键被按下,则判定键位置的扫描过程如下:首先是判定有没有键被按下。先使P3口输出0EH(1110),然后输入行线状态,测试行线中是否有低电平的,如果没有低电平,再使输出口输出0DH(1101),再测试行线状态。到输出口输出0BH(1011)时,行线中有状态为低电平者(行1),则闭合键找到,通过此次扫描的列线值和行线值就可以知道闭合键

25、的位置。当经扫描表明有键被按下之后,紧接着应进行去抖动处理。采用软件延时的方法,一般为1020 ms,待行线上状态稳定之后,再次判断按键状态。按键确定之后,下一步是计算闭合键的键码,我们以键的排列顺序安排键号,键码既可以根据行号列号以查表求得,也可以通过计算得到。键码的计算公式为:键码=行首号+列号。计算键码之后,延时等待键释放,目的是为了保证键的一次闭合仅进行一次处理。在计算机中每一个键都对应一个处理子程序,得到闭合键的键码后,就可以根据键码,转相应的键处理子程序,进行字符、数据的输入或命令的处理。这样就可以实现该键所设定的功能。总结上述内容,键处理的流程如图所示。(2)显示程序设计静态显示

26、是将段码输送到相应的驱动口P0口。根据所给定的高低电平,点亮不同的段,从而显示不同的数值。5.3系统连线说明1、AT89S51单片机的P3口用作键盘I/O口,键盘的列线接到P3口的低4位,键盘的行线接到P1口的高4位。列线P3.0-P3.3分别接有4个上拉电阻到正电源+5V,并把列线P3.0-P3.3设置为输入线,行线P3.4-P3.7设置为输出线。4根行线和4根列线形成16个相交点。(1)检测当前是否有键被按下。检测的方法是P3.4-P3.7输出全“0”,读取P3.0-P3.3的状态,若P3.0-P3.3为全“1”,则无键闭合,否则有键闭合。(2)去除键抖动。当检测到有键按下后,延时一段时间

27、再做下一步的检测判断。(3)若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P3.4-P3.7按下述4种组合依次输出:P3.7 1 1 1 0P3.6 1 1 0 1P3.5 1 0 1 1P3.4 0 1 1 1在每组行输出时读取P3.0-P3.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值(4)为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。2、 AT89S51单片机的P1口的P1.0P1.7端口用8芯排线连接到静态数码显示模块中的任一个ah端口上;

28、要求:P1.0对应着a,P1.1对应着b,P1.7对应着h。根据数码(0,1,2,3,4,5,6,7,8,9)来决定七段中的某一段或某几段进行绘制,例如如果数码为0,则显示0、1、2、3、4、5段;数码为1,则显示1、2段,依次类推。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极

29、管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。所以数码管的类型不同设置的段码就不同。3、AT89S51单片机的18、19脚连接系统的晶振电路。4、AT89S51单片机的9脚节系统的按键复位电路。5、AT89S51单片机的31脚、EA接VCC,使单片机读内部程序。5.4系统参数分析1、复位电路一般R取10K,C取10UF,教科书上R肯定是8.2K,都可以的,RC越大,充电时间越长,单片机上电复位过程越长,其实RC取值不是需要特别严格。还有种说法,R=1K,C=22UF,抗干扰性更好。复位电路的电阻和电容要根据复位脉冲的宽度要求计算得到:比如如果单片机的复位脉冲要

30、求至少20ms,高电平是5V,最大低电平为0.8V,则应按RC电路的放电(或充电)方程计算,使从5V放电到0.8V(或相反)所用的时间不小于20ms。2、两晶振电路的小电容一般取15-30PF即可。影响不大的。理论上是用的晶体越高,应该用更小的电容。比如说12M晶体,用20PF,1M晶体,用30PF,其实日常应用,根本是没有差别的,用20、30PF都一样。3、I/O口上拉电阻是用来提高它的带载能力的,编程后让某个I/O口置高电平,不带载应该电位就是5V,因为它的带载能力很弱,尤其这种输出为高电平带载,稍微带点负载(输出电流哪怕不到毫安级),这点电位用万用表量的话,要下降很大,接一电阻并到这个I

31、/O口跟VCC,可以提高它的带载能力,这个电阻就叫上拉电阻。一般这个电阻取值都是1K到10K左右,注意这个电阻也不能太小啊,虽然越小上拉能力越强,但是I/O承受的灌电流越大,太大要烧I/O口的。4、显示电路中数码管的驱动要家限流电阻,但那是限流电阻不能加的太答,一般在200欧就可以使数码管很亮,如果加的电阻太大的话数码管就会很暗。5、矩阵按键系统最好也加上一排上拉电阻以保证气稳定性,一般选取1K 就可以。六、源程序/*说明* 曲谱存贮格式 unsigned char code MusicName音高,音长,音高,音长., 0,0; 末尾:0,0 表示结束(Important) 音高由三位数字组

32、成: 个位是表示 17 这七个音符 十位是表示音符所在的音区:1-低音,2-中音,3-高音; 百位表示这个音符是否要升半音: 0-不升,1-升半音。 音长最多由三位数字组成: 个位表示音符的时值,其对应关系是: |数值(n): |0 |1 |2 |3 | 4 | 5 | 6 |几分音符: |1 |2 |4 |8 |16 |32 |64 音符=2n 十位表示音符的演奏效果(0-2): 0-普通,1-连音,2-顿音 百位是符点位: 0-无符点,1-有符点 调用演奏子程序的格式 Play(乐曲名,调号,升降八度,演奏速度); |乐曲名 : 要播放的乐曲指针,结尾以(0,0)结束; |调号(0-11)

33、 : 是指乐曲升多少个半音演奏; |升降八度(1-3) : 1:降八度, 2:不升不降, 3:升八度; |演奏速度(1-12000): 值越大速度越快; #define SYSTEM_OSC 12000000 /定义晶振频率12000000HZ #define SOUND_SPACE 4/5 /定义普通音符演奏的长度分率,/每4分音符间隔 sbit BeepIO = P10; /定义输出管脚 unsigned int code FreTab12 = 262,277,294,311,330,349,369,392,415,440,466,494 ; /原始频率表 unsigned char co

34、de SignTab7 = 0,2,4,5,7,9,11 ; /17在频率表中的位置 unsigned char code LengthTab7= 1,2,4,8,16,32,64 ; unsigned char Sound_Temp_TH0,Sound_Temp_TL0; /音符定时器初值暂存 unsigned char Sound_Temp_TH1,Sound_Temp_TL1; /音长定时器初值暂存 /* void InitialSound(void) BeepIO = 0; Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; / 计算TL

35、1应装入的初值 (10ms的初装值) Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256; / 计算TH1应装入的初值 TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TMOD |= 0x11; ET0 = 1; ET1 = 0; TR0 = 0; TR1 = 0; EA = 1; void BeepTimer0(void) interrupt 1 /音符发生中断 BeepIO = !BeepIO; TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0; /*void Play

36、(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed) unsigned int NewFreTab12; /新的频率表 unsigned char i,j; unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength; unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD; for(i=0;i 11) j = j-12; NewFreTabi =

37、FreTabj*2; else NewFreTabi = FreTabj; if(Octachord = 1) NewFreTabi=2; else if(Octachord = 3) NewFreTabi=2; SoundLength = 0; while(SoundSoundLength != 0x00) /计算歌曲长度 SoundLength+=2; Point = 0; Tone = SoundPoint; Length = SoundPoint+1; / 读出第一个音符和它时时值 LDiv0 = 12000/Speed; / 算出1分音符的长度(几个10ms) LDiv4 = LDi

38、v0/4; / 算出4分音符的长度 LDiv4 = LDiv4-LDiv4*SOUND_SPACE; / 普通音最长间隔标准 TR0 = 0; TR1 = 1; while(Point = 2; /低音 if (SM=3) CurrentFre = 2; /高音 Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);/计算计数器初值 Sound_Temp_TH0 = Temp_T/256; Sound_Temp_TL0 = Temp_T%256; TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0

39、 + 12; /加12是对中断延时的补偿 SLen=LengthTabLength%10; /算出是几分音符 XG=Length/10%10; /算出音符类型(0普通1连音2顿音) FD=Length/100; LDiv=LDiv0/SLen; /算出连音音符演奏的长度(多少个10ms) if (FD=1) LDiv=LDiv+LDiv/2; if(XG!=1) if(XG=0) /算出普通音符的演奏长度 if (SLen0;i-) /发规定长度的音 while(TF1=0); TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TF1=0; if(LDiv

40、2!=0) TR0=0; BeepIO=0; for(i=LDiv2;i0;i-) /音符间的间隔 while(TF1=0); TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TF1=0; Point+=2; Tone=SoundPoint; Length=SoundPoint+1; BeepIO = 0; #include #include SoundPlay.h /把SoundPlay.h作为一个头文件把条用调用。void Delay1ms(unsigned int count) /延时子程序 unsigned int i,j; for(i=0;ic

41、ount;i+) for(j=0;j120;j+); /*Music* /挥着翅膀的女孩 unsigned char code Music_Girl= 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03, 0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02, 0x10

42、,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03, 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03, 0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 办公文档 > 其他范文


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号