单片机原理课程设计报告
题目:音乐盒的设计
课程设计任务书
班级:11数控二班 学号:[1**********]33 姓名:刘波 指导教师:邹琦
漯河职业技术学院
2013.1
摘要
第一章 绪论 1.1课程设计目的 1.2课程设计任务 1.3课程设计要求 1.4课程设计意义 第二章 设计原理 2.1基本原理简述 2.2设计方案
第三章 音乐播放器的硬件电路 3.1 AT89C51单片机 3.2 单片机CPU 结构 3.3引脚介绍 3.4 电路连线 第四章 软件编程设计 4.1编程方案 第五章 心得体会
第一章 绪论
1.1课程设计目的
应用单片机,利用它的原理组成一个音乐播放器。本课程设计是主干实践课。课程的任
务在于提高学生综合运用所学知识理论、分析解决问题的能力。
1.2课程设计任务
1)以单片机为核心部件组成一个音乐播放器;
2)利用单片机的定时器产生乐谱的各种频率方波,由蜂鸣器发出声音; 3)定义按键,能相应的播放出歌曲;
1.3课程设计要求
能用键盘选择不同的歌曲,至少两首以上,并写出课程设计报告。
1.4课程设计的意义
通过自己动手设计单片及组成的器件,在软件及硬件上进一步了解单片机的原理,深入了解了单片机C51语言的实际应用,能更深地理解课堂上所学的内容,巩固C 语言程序编写,体会作为一名设计人员所需要具备的各种能力,学会理论知识联系实际,提高我们发现问题,分析问题,解决问题和实践动手的能力。
第二章 设计原理及总体方案选择
2.1 设计原理
音调的确定
不同音高的乐音是用C 、D 、E 、F 、G 、A 、B 来表示,这7个字母就是音乐的音名,它们一般依次唱成DO 、RE 、MI 、FA 、SO 、LA 、SI, 即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”,即Tone 。把C 、D 、E 、F 、G 、A 、B 这一组音的距离分成12个等份,每一个等份叫一个“半音”。两个音之间的距离有两个“半音”,就叫“全音”。在钢琴等键盘乐器上,C –D 、D –E 、F –G 、G –A 、A –B 两音之间隔着一个黑键,他们之间的距离就是全音;E –F 、B –C 两音之间没有黑键相隔,它们之间的距离就是半音。通常唱成1、2、3、4、5、6、7的音叫自然音,那些在它们的左上角加上﹟号或者b 号的叫变化音。﹟叫升记号,表示把音在原来的基础上升高半音,b 叫降记音,表示在原来的基础上降低半音。例如高音DO 的频率(1046Hz )刚好是中音DO 的频率(523Hz )的一倍,中音DO 的频率(523Hz )刚好是低音DO 频率(266 Hz )的一倍;同样的,高音RE 的频率(1175Hz )刚好是中音RE 的频率(587Hz )的一倍,中音RE 的频率(587Hz )刚好是低音RE 频率(294 Hz)的一倍。
1)要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,
然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。
2)利用AT89C51的内部定时器使其工作在计数器模式MODE1下,改变计数值TH0及TL0以产生不同频率的方法。
此外结束符和休止符可以分别用代码00H 和FFH 来表示,若查表结果为00H ,则表示曲子终了;若查表结果为FFH ,则产生相应的停顿效果。
3)例如频率为523Hz ,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,在每次技术956次时将I/O反相,就可得到中音DO (523Hz )。
计数脉冲值与频率的关系公式如下: N=Fi÷2÷Fr
N :计算值; Fi :内部计时一次为1us ,故其频率为1MHz ; 4)其计数值的求法如下: T=65536-N=65536-Fi÷2÷Fr
例如:设K=65536,F=1000000=Fi=1MHz,球低音DO (261Hz )。中音DO (523Hz )。高音的DO (1046Hz )的计算值
T=65536-N=65536-Fi÷2÷Fr=65536-1000000÷2÷Fr=65536-500000/Fr 低音DO 的T=65536-500000/262=63627 低音DO 的T=65536-500000/523=64580 低音DO 的T=65536-500000/1047=65059
5)C 调各音符频率与计数值T 的对照表如下表所示。 C调各音符频率与计数值T 的对照表
低音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 262 277 294 311 330 349 370 392 415 440 464 494
T 1908 1805 1701 1608 1515 1433 1351 1276 1205 1136 1078 1012
参数 229 217 204 193 182 172 162 153 145 136 129 121
中音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 523 554 587 622 659 698 740 784 831 880 932 988
T 956 903 852 804 759 716 676 638 602 568 536 506
参数 115 108 102 97 91 86 81 77 72 68 64 61
高音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 1046 1109 1175 1245 1318 1397 1480 1568 1661 1760 1865 1976
T 57 54 51 48 45 43 41 38 36 34 32 30
参数 57 54 51 48 45 43 41 38 36 34 32 30
节拍的确定
若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快满度。“节拍”, 即Beat ,简单说就是打拍子,就像我们听音乐不自主的随之拍手或跺脚。若1拍实0.5s ,则1/4 拍为0.125s 。至于1拍多少s ,并没有严格规定,就像人的心跳一样,大部分人的心跳是每分钟72下,有些人快一点,有些人慢一点,只要听的悦耳就好。音持续时间的长短即时值,一般用拍数表示。休止符表示暂停发音。
一首音乐是由许多不同的音符组成的,而每个音符对应着不同频率,这样就可以利用不同的频率的组合,加以与拍数对应的延时,构成音乐。了解音乐的一些基础知识,我们可知产生不同频率的音频脉冲即能产生音乐。对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。因此,需要弄清楚音乐中的音符
和对应的频率,以及单片机定时计数的关系。
表4.2节拍与节拍码对照
节拍码 节拍数 1 1/4拍 2 2/4拍 3 3/4拍 4 1拍 5 1又1/4拍 6 1又1/2拍 8 2拍 A 2又1/2拍
节拍码
1 2 3 4 5 6 8 A 节拍数 1/8拍 1/4拍 3/8拍 2/1拍 5/8拍 3/4拍 1拍 1又1/4拍
C 3拍 C 1又1/2拍 F 3又3/4拍
每个音符使用1个字节,字节的高4位代表音符的高低,低4位代表音符的节拍,图5.2为节拍码的对照。如果1拍为0.4秒,1/4拍实0.1秒,只要设定延迟时间就可求得节拍的时间。假设1/4拍为1DELAY ,则1拍应为4DELAY ,以此类推。所以只要求得1/4拍的DELAY 时间,其余的节拍就是它的倍数,如图5.3为1/4和1/8节拍的时间设定。
表4.3 1/4和1/8节拍的时间设定
曲调值 DELAY 曲调值 DELAY 调4/4 125毫秒 调4/4 62毫秒 调3/4 187毫秒 调3/4 94毫秒 调2/4 250毫秒 调2/4 125毫秒
编码
do re mi fa so la si分别编码为1~7,重音do 编为8, 重音re 编为9,停顿编为0。播放长度以十六分音符为单位(在本程序中为165ms ),一拍即四分音符等于4个十六分音符,编为4, 其它的播放时间以此类推。音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。以0xff 作为曲谱的结束标志。
举例1:音调do, 发音长度为两拍,即二分音符,将其编码为0x18。 举例2:音调re, 发音长度为半拍,即八分音符,将其编码为0x22
歌曲播放的设计。先将歌曲的简谱进行编码,储存在一个数据类型为unsigned char 的数组中。程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。
表4.4 简谱对应的简谱码、T 值、节拍数
简谱 5 6 7 1 2 3 4 5 6 7
发音 低音SO 低音LA 低音TI 中音DO 中音RE 中音MI 中音FA 中音SO 中音LA 中音TI
简谱码 1 2 3 4 5 6 7 8 9 A
T 值 64260 64400 64524 64580 64684 64777 64820 64898 64968 65030
节拍码 1 2 3 4 5 6 8 A C F
节拍数 1/4拍 2/4拍 3/4拍 1拍 1又1/4拍 1又1/2拍
2拍 2又1/2拍
3拍 3又3/4拍
1 2 3 4 5
高音DO 高音RE 高音MI 高音FA 高音SO
B C D E F
65058 65110 65157 65178 65217
为简便起见,以一定的频率方波产生的音在其每个周期内高低幅值得时间各占一半因此,输出引脚在每个方波周期内要动作两次:一次升高,一次降低。即输出引脚的频率是原音频率的两倍。
方波的产生由定时器控制。定时器T0工作在定时方式1,改变TH0及TL0,产生不同的音频频率。必须考虑到中断响应时间的影响,尤其在高音部分,若忽略中断响应时间,会使音频频率比标准值低几十Hz ,相当于1/4音程,很容易听出来,对低音部分影响不大。一般中断响应时间为3~6个机器周期,经过反复试验取5个机器周期作为校正最为恰当,表1中所给的定时初值就是考虑中断响应后的定时常数。另外,为避免T1中断可能引起杂音,应将定时器T0中断设为高优先级。这样编写出来的程序播放的音与标准音叉进行差频校音,非常准确和谐。
音乐播放器的基本硬件电路有六部分组成:单片机、时钟与复位电路、选择按键输入电路、音频发生器、音频放大器和扬声器。音乐播放器硬件电路设计框图如图2.1所示。
图2.1 音乐播放器硬件电路设计框图
利用单片机内部定时器/计数器T0与P1.1引脚配合,构成音频发生器,驱动扬声器输出。
2.2 设计方案
实现4个按键选择4首歌曲,能够实现音乐播放。
简单说明:控制键盘,使其IRQ 引脚接单片机的外部中断0,一旦有键按下就对应一首曲播放目。停止按键可以使用外部中断1来实现。
各音调对应的定时器初始装载表也以数组的形式按升调顺序存储,并按前面所述将各歌曲的对应音调和节拍存储在数组中,有按键按下时,将对应歌曲的数组首地址传给全局指针,利用相应的处理函数调出音调对应的定时器装载值表,给定时器装载初值并启动,产生控制扬声器的方波,根据低半字节控制延时时间,即音调的发音长短。
第三章 音乐播放器的硬件电路
3.1 AT89C51单片机
AT89C51是美国ATMEL 公司推出的系列单片机,将多种功能的8位CPU 与FPEROM (快闪可编程/擦除只读存储器)结合在一个芯片上,是一种低功耗、高性能的CMOS 控制器,为很多嵌入式控制应用提供了非常灵活而又价格适宜的方案,其性能价格比远高于同类芯片。它与MCS-51指令系统兼容,片内FPEROM 允许对程序存储器在线重复编程,也可用常规的EPROM 编程器编程,可循环写入/擦除1000次。89C51内含4KB 的FPEROM ,一般的EEPROM 的字节擦除时间和写入时间基本上均为10ms ,对于任一个实时控制系统来说,这样长的时间是不可能在线修改程序的。
3.2 AT89C51用户系统
● CPU 为Atmel 公司生产的89C51/89C52/89C55等。出厂所配晶振频率为11.0592MH, 每个
机器周期为1.085us, 用户更换晶振以提高速度;
● 存贮器为64K, 前4K/8K20K在CPU 内部, 其它程序在EPR0M27512中; ● 数据存贮器为32K(62256),地址为8000—FFFFH ; ● Ⅰ/O扩展8155, 片内RAM 地址∶200O-20FFH ; ● 8155命令口地址为∶2100H ;
● A 口地址∶21O1H B口地址:2102H C口地址:2103H ; ● T 低八位∶2104H T高八位∶2105H ; ● 多路模拟开关的使用∶
IN0∶P1=0F8H IN4:P1=0FCH IN1∶P1=0F9H IN5:P1=OFDH IN2∶P1=0FAH IN5:P1=0FEH IN3∶P1=0FBH IN7:P1=0FFH ● 不掉电数据存贮器为∶500EH-507FH ;
● 控制板∶160x1O9(mm) 供电∶+5V300mA +12V100mA -12V100mA ;
● AT89C51是一种低功耗、高性能的片内含有4KB 快闪可编程/擦除只读存储器
(FPEROM-Flash Programmable and Eraseable Read Only Memory)的8位CMOS 微控制器,使用高密度、非易失存储技术制造,并且与80C51引脚和指令系统完全兼容; ● 主要性能:
与MCS-51 微控制器产品系列兼容;
片内有4KB 可在线重复编程的快闪擦写存储器 。
3.3 引脚介绍
A T89C51是一种带4K 字节闪存可编程可擦除只读存储器(FPEROM —Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。A T89C2051是一种带2K 字节闪存可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用A TMEL 高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,A TMEL 的A T89C51是一种高效微控制器,A T89C2051是它的一种精简版本。A T89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。外形及引脚排列如图3.2所示
图3.7 89C51引脚图
3.4 电路连线
利用wave6000仿真软件电路连线较为简单:
1) 电路内置为12MHZ 晶振频率工作
2) P1.0控制蜂鸣器。
3) 键盘接口KEY 与CS0连接
第四章 软件编程设计
4.1 编程方案
#include #define LEDLen 6
#define uint unsigned int
#define uchar unsigned char
xdata unsigned char OUTBIT _at_ 0x8002; // 位控制口 xdata unsigned char OUTSEG _at_ 0x8004; // 段控制口 xdata unsigned char IN _at_ 0x8001; // 键盘读入口 sbit speaker=P1^0;//接喇叭或蜂鸣器的接口 uint h,i,j; uint hz; uchar jiep; bit flag;
uint
fre[]={ 64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217}; uchar code sing1[]={6,9, 6,3, 7,12, 6,12, 9,12, 8,24, 6,9, 6,3, 7,12,6,12, 10,12, 9,24,
code
6,9, 6,3, 13,12, 11,12, 8,12, 7,12, 12,9, 12,3, 11,12, 9,12, 10,12, 9,24};
//歌谱 2个一组(0,0)(音调, 节拍)(生日歌)
uchar code sing2[]={4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 4,4,3,2,3,6, 4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 3,4,2,2,2,6, 3,3,3,3,4,3,2,3,3,3,4,1,5,2,4,3,2,3,3,3,4,1,5,2,4,3,2,3,2,3,3,3,6,6, 4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 3,4,2,2,2,6, };
//歌谱 2个一组(0,0)(音调, 节拍)(欢乐颂)
void Delay(unsigned char CNT) {
unsigned char i;
while (CNT-- !=0)
for (i=100; i !=0; i--); }
code unsigned char KeyTable[] = { // 键码定义 0x16, 0x15, 0x14, 0xff, 0x13, 0x12, 0x11, 0x10, 0x0d, 0x0c, 0x0b, 0x0a, 0x0e, 0x03, 0x06, 0x09, 0x0f, 0x02, 0x05, 0x08, 0x00, 0x01, 0x04, 0x07 };
unsigned char TestKey() {
OUTBIT = 0; // 输出线置为0
return (~IN & 0x0f); // 读入键状态(高四位不用) }
unsigned char GetKey() {
unsigned char Pos; unsigned char i; unsigned char k;
i = 6;
Pos = 0x20; // 找出键所在列 do {
OUTBIT = ~ Pos; Pos >>= 1;
k = ~IN & 0x0f;
} while ((--i != 0) && (k == 0));
if (k != 0) // 键值 = 列 x 4 + 行 {
i *= 4; if (k & 2) i += 1; else if (k & 4) i += 2; else if (k & 8) i += 3;
OUTBIT = 0;
do Delay(10); while (TestKey()); // 等键释放
return(KeyTable[i]); // 取出键码 } else return(0xff); }
void init () //初始化 { EA=1; //中断允许总开关打开
TMOD=0x11; //定时器0、1都工作在方式1 ET0=1; //定时器T0中断允许 ET1=1; //定时器T1中断允许
i=0;j=0;
flag=1; }
void sing() { if(flag==1) { h=sing1[j]; //取音符 jiep=sing1[j+1]; //取节拍 j=j+2; //下一个音符 if(j>166) j=0;
hz=fre[h];
TH0=(hz)/256;
TL0=(hz)%256; //置定时器初值 flag=0;
TR0=1;
TR1=1; //开定时器
}
}
void sang()
if(flag==1)
{
h=sing2[j];
jiep=sing2[j+1];
j=j+2;
if(j>166) j=0;
hz=fre[h];
TH0=(hz)/256;
TL0=(hz)%256;
flag=0;
TR0=1;
TR1=1;
}
}
void main()
{uchar temp;
init();
while (1)
{
if (TestKey()) //查看是否有键按下
temp= (GetKey() & 0x0f); //取出键值
if(temp==1) //如果按下的是1,则播放第一首歌曲
{
sing(); //播放第一首歌曲
Delay(1); //延时
}
else if(temp==2) //如果按下的是2,则播放第二首歌曲
{
sang(); //播放第一首歌曲
Delay(1); //延时
}
}
}
void time0() interrupt 1 //定时器0
{
TH0=(hz)/256;
TL0=(hz)%256;
if(!flag) speaker=!speaker;
else TR0=0; //节拍未结束则继续翻转形成脉冲,结束则关定时器
}
void time1() interrupt 3
}
TH1=(15536)/256; TL1=(15536)%256; --jiep; if(jiep==0) flag=1; //本节拍结束,另flog 等于1,即关定时器0
第五章 心得体会
课程设计结束了,我收获了很多在课堂上无法学到的知识,不仅是硬件发设计能力,软件的编程能力也得到了大幅度的提高。本次课程设计的题目是音乐播放器,其要求是运用C51语言进行编程,实现可以播放多首歌曲,通过数字键进行控制播放歌曲的曲目。
刚拿到这个题目时,我们觉得挺简单,但当我们着手做的时候,却毫无头绪。我们在网络上下载了一些关于用单片机设计音乐播发器的内容。对课题有了大体的了解。之后就开始设计理图,程序流程图,并尝试编写程序慢慢有了点进展。
在课程实习过程中,硬件使用的都是实验箱,没有太大的问题存在,自己只需明白硬件功能,清楚实现方法,连好需要的几根线就可以了。软件设计一直困扰着我们,很难找到突破口。程序调试过程是一个需要细心和毅力的过程,当它脱离正常轨迹不按照应该的步骤进行时,我们就要一步一步的调试,找错误,找漏洞。老天不负有心人,当第一次整个系统成功实现预设功能。我们体会到艰辛和磨难后的喜悦。
虽然我们完成的还不够完美,但我们已经尽力了,相信老师也看到了在本次的设计中,我们一起构思、设计、编程、调试,这不仅巩固了我们的基础知识,也进一步培养了我们亲身实践动手的能力,这对我们将来的工作和研究都是大有好处的。团队合作真的很重要。最后还要感谢老师的耐心教导。
单片机原理课程设计报告
题目:音乐盒的设计
课程设计任务书
班级:11数控二班 学号:[1**********]33 姓名:刘波 指导教师:邹琦
漯河职业技术学院
2013.1
摘要
第一章 绪论 1.1课程设计目的 1.2课程设计任务 1.3课程设计要求 1.4课程设计意义 第二章 设计原理 2.1基本原理简述 2.2设计方案
第三章 音乐播放器的硬件电路 3.1 AT89C51单片机 3.2 单片机CPU 结构 3.3引脚介绍 3.4 电路连线 第四章 软件编程设计 4.1编程方案 第五章 心得体会
第一章 绪论
1.1课程设计目的
应用单片机,利用它的原理组成一个音乐播放器。本课程设计是主干实践课。课程的任
务在于提高学生综合运用所学知识理论、分析解决问题的能力。
1.2课程设计任务
1)以单片机为核心部件组成一个音乐播放器;
2)利用单片机的定时器产生乐谱的各种频率方波,由蜂鸣器发出声音; 3)定义按键,能相应的播放出歌曲;
1.3课程设计要求
能用键盘选择不同的歌曲,至少两首以上,并写出课程设计报告。
1.4课程设计的意义
通过自己动手设计单片及组成的器件,在软件及硬件上进一步了解单片机的原理,深入了解了单片机C51语言的实际应用,能更深地理解课堂上所学的内容,巩固C 语言程序编写,体会作为一名设计人员所需要具备的各种能力,学会理论知识联系实际,提高我们发现问题,分析问题,解决问题和实践动手的能力。
第二章 设计原理及总体方案选择
2.1 设计原理
音调的确定
不同音高的乐音是用C 、D 、E 、F 、G 、A 、B 来表示,这7个字母就是音乐的音名,它们一般依次唱成DO 、RE 、MI 、FA 、SO 、LA 、SI, 即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”,即Tone 。把C 、D 、E 、F 、G 、A 、B 这一组音的距离分成12个等份,每一个等份叫一个“半音”。两个音之间的距离有两个“半音”,就叫“全音”。在钢琴等键盘乐器上,C –D 、D –E 、F –G 、G –A 、A –B 两音之间隔着一个黑键,他们之间的距离就是全音;E –F 、B –C 两音之间没有黑键相隔,它们之间的距离就是半音。通常唱成1、2、3、4、5、6、7的音叫自然音,那些在它们的左上角加上﹟号或者b 号的叫变化音。﹟叫升记号,表示把音在原来的基础上升高半音,b 叫降记音,表示在原来的基础上降低半音。例如高音DO 的频率(1046Hz )刚好是中音DO 的频率(523Hz )的一倍,中音DO 的频率(523Hz )刚好是低音DO 频率(266 Hz )的一倍;同样的,高音RE 的频率(1175Hz )刚好是中音RE 的频率(587Hz )的一倍,中音RE 的频率(587Hz )刚好是低音RE 频率(294 Hz)的一倍。
1)要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,
然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。
2)利用AT89C51的内部定时器使其工作在计数器模式MODE1下,改变计数值TH0及TL0以产生不同频率的方法。
此外结束符和休止符可以分别用代码00H 和FFH 来表示,若查表结果为00H ,则表示曲子终了;若查表结果为FFH ,则产生相应的停顿效果。
3)例如频率为523Hz ,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,在每次技术956次时将I/O反相,就可得到中音DO (523Hz )。
计数脉冲值与频率的关系公式如下: N=Fi÷2÷Fr
N :计算值; Fi :内部计时一次为1us ,故其频率为1MHz ; 4)其计数值的求法如下: T=65536-N=65536-Fi÷2÷Fr
例如:设K=65536,F=1000000=Fi=1MHz,球低音DO (261Hz )。中音DO (523Hz )。高音的DO (1046Hz )的计算值
T=65536-N=65536-Fi÷2÷Fr=65536-1000000÷2÷Fr=65536-500000/Fr 低音DO 的T=65536-500000/262=63627 低音DO 的T=65536-500000/523=64580 低音DO 的T=65536-500000/1047=65059
5)C 调各音符频率与计数值T 的对照表如下表所示。 C调各音符频率与计数值T 的对照表
低音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 262 277 294 311 330 349 370 392 415 440 464 494
T 1908 1805 1701 1608 1515 1433 1351 1276 1205 1136 1078 1012
参数 229 217 204 193 182 172 162 153 145 136 129 121
中音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 523 554 587 622 659 698 740 784 831 880 932 988
T 956 903 852 804 759 716 676 638 602 568 536 506
参数 115 108 102 97 91 86 81 77 72 68 64 61
高音 Do Do ﹟ Re Re ﹟ Mi Fa Fa ﹟ So So ﹟ La La ﹟ Si
频率 1046 1109 1175 1245 1318 1397 1480 1568 1661 1760 1865 1976
T 57 54 51 48 45 43 41 38 36 34 32 30
参数 57 54 51 48 45 43 41 38 36 34 32 30
节拍的确定
若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快满度。“节拍”, 即Beat ,简单说就是打拍子,就像我们听音乐不自主的随之拍手或跺脚。若1拍实0.5s ,则1/4 拍为0.125s 。至于1拍多少s ,并没有严格规定,就像人的心跳一样,大部分人的心跳是每分钟72下,有些人快一点,有些人慢一点,只要听的悦耳就好。音持续时间的长短即时值,一般用拍数表示。休止符表示暂停发音。
一首音乐是由许多不同的音符组成的,而每个音符对应着不同频率,这样就可以利用不同的频率的组合,加以与拍数对应的延时,构成音乐。了解音乐的一些基础知识,我们可知产生不同频率的音频脉冲即能产生音乐。对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。因此,需要弄清楚音乐中的音符
和对应的频率,以及单片机定时计数的关系。
表4.2节拍与节拍码对照
节拍码 节拍数 1 1/4拍 2 2/4拍 3 3/4拍 4 1拍 5 1又1/4拍 6 1又1/2拍 8 2拍 A 2又1/2拍
节拍码
1 2 3 4 5 6 8 A 节拍数 1/8拍 1/4拍 3/8拍 2/1拍 5/8拍 3/4拍 1拍 1又1/4拍
C 3拍 C 1又1/2拍 F 3又3/4拍
每个音符使用1个字节,字节的高4位代表音符的高低,低4位代表音符的节拍,图5.2为节拍码的对照。如果1拍为0.4秒,1/4拍实0.1秒,只要设定延迟时间就可求得节拍的时间。假设1/4拍为1DELAY ,则1拍应为4DELAY ,以此类推。所以只要求得1/4拍的DELAY 时间,其余的节拍就是它的倍数,如图5.3为1/4和1/8节拍的时间设定。
表4.3 1/4和1/8节拍的时间设定
曲调值 DELAY 曲调值 DELAY 调4/4 125毫秒 调4/4 62毫秒 调3/4 187毫秒 调3/4 94毫秒 调2/4 250毫秒 调2/4 125毫秒
编码
do re mi fa so la si分别编码为1~7,重音do 编为8, 重音re 编为9,停顿编为0。播放长度以十六分音符为单位(在本程序中为165ms ),一拍即四分音符等于4个十六分音符,编为4, 其它的播放时间以此类推。音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。以0xff 作为曲谱的结束标志。
举例1:音调do, 发音长度为两拍,即二分音符,将其编码为0x18。 举例2:音调re, 发音长度为半拍,即八分音符,将其编码为0x22
歌曲播放的设计。先将歌曲的简谱进行编码,储存在一个数据类型为unsigned char 的数组中。程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。
表4.4 简谱对应的简谱码、T 值、节拍数
简谱 5 6 7 1 2 3 4 5 6 7
发音 低音SO 低音LA 低音TI 中音DO 中音RE 中音MI 中音FA 中音SO 中音LA 中音TI
简谱码 1 2 3 4 5 6 7 8 9 A
T 值 64260 64400 64524 64580 64684 64777 64820 64898 64968 65030
节拍码 1 2 3 4 5 6 8 A C F
节拍数 1/4拍 2/4拍 3/4拍 1拍 1又1/4拍 1又1/2拍
2拍 2又1/2拍
3拍 3又3/4拍
1 2 3 4 5
高音DO 高音RE 高音MI 高音FA 高音SO
B C D E F
65058 65110 65157 65178 65217
为简便起见,以一定的频率方波产生的音在其每个周期内高低幅值得时间各占一半因此,输出引脚在每个方波周期内要动作两次:一次升高,一次降低。即输出引脚的频率是原音频率的两倍。
方波的产生由定时器控制。定时器T0工作在定时方式1,改变TH0及TL0,产生不同的音频频率。必须考虑到中断响应时间的影响,尤其在高音部分,若忽略中断响应时间,会使音频频率比标准值低几十Hz ,相当于1/4音程,很容易听出来,对低音部分影响不大。一般中断响应时间为3~6个机器周期,经过反复试验取5个机器周期作为校正最为恰当,表1中所给的定时初值就是考虑中断响应后的定时常数。另外,为避免T1中断可能引起杂音,应将定时器T0中断设为高优先级。这样编写出来的程序播放的音与标准音叉进行差频校音,非常准确和谐。
音乐播放器的基本硬件电路有六部分组成:单片机、时钟与复位电路、选择按键输入电路、音频发生器、音频放大器和扬声器。音乐播放器硬件电路设计框图如图2.1所示。
图2.1 音乐播放器硬件电路设计框图
利用单片机内部定时器/计数器T0与P1.1引脚配合,构成音频发生器,驱动扬声器输出。
2.2 设计方案
实现4个按键选择4首歌曲,能够实现音乐播放。
简单说明:控制键盘,使其IRQ 引脚接单片机的外部中断0,一旦有键按下就对应一首曲播放目。停止按键可以使用外部中断1来实现。
各音调对应的定时器初始装载表也以数组的形式按升调顺序存储,并按前面所述将各歌曲的对应音调和节拍存储在数组中,有按键按下时,将对应歌曲的数组首地址传给全局指针,利用相应的处理函数调出音调对应的定时器装载值表,给定时器装载初值并启动,产生控制扬声器的方波,根据低半字节控制延时时间,即音调的发音长短。
第三章 音乐播放器的硬件电路
3.1 AT89C51单片机
AT89C51是美国ATMEL 公司推出的系列单片机,将多种功能的8位CPU 与FPEROM (快闪可编程/擦除只读存储器)结合在一个芯片上,是一种低功耗、高性能的CMOS 控制器,为很多嵌入式控制应用提供了非常灵活而又价格适宜的方案,其性能价格比远高于同类芯片。它与MCS-51指令系统兼容,片内FPEROM 允许对程序存储器在线重复编程,也可用常规的EPROM 编程器编程,可循环写入/擦除1000次。89C51内含4KB 的FPEROM ,一般的EEPROM 的字节擦除时间和写入时间基本上均为10ms ,对于任一个实时控制系统来说,这样长的时间是不可能在线修改程序的。
3.2 AT89C51用户系统
● CPU 为Atmel 公司生产的89C51/89C52/89C55等。出厂所配晶振频率为11.0592MH, 每个
机器周期为1.085us, 用户更换晶振以提高速度;
● 存贮器为64K, 前4K/8K20K在CPU 内部, 其它程序在EPR0M27512中; ● 数据存贮器为32K(62256),地址为8000—FFFFH ; ● Ⅰ/O扩展8155, 片内RAM 地址∶200O-20FFH ; ● 8155命令口地址为∶2100H ;
● A 口地址∶21O1H B口地址:2102H C口地址:2103H ; ● T 低八位∶2104H T高八位∶2105H ; ● 多路模拟开关的使用∶
IN0∶P1=0F8H IN4:P1=0FCH IN1∶P1=0F9H IN5:P1=OFDH IN2∶P1=0FAH IN5:P1=0FEH IN3∶P1=0FBH IN7:P1=0FFH ● 不掉电数据存贮器为∶500EH-507FH ;
● 控制板∶160x1O9(mm) 供电∶+5V300mA +12V100mA -12V100mA ;
● AT89C51是一种低功耗、高性能的片内含有4KB 快闪可编程/擦除只读存储器
(FPEROM-Flash Programmable and Eraseable Read Only Memory)的8位CMOS 微控制器,使用高密度、非易失存储技术制造,并且与80C51引脚和指令系统完全兼容; ● 主要性能:
与MCS-51 微控制器产品系列兼容;
片内有4KB 可在线重复编程的快闪擦写存储器 。
3.3 引脚介绍
A T89C51是一种带4K 字节闪存可编程可擦除只读存储器(FPEROM —Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。A T89C2051是一种带2K 字节闪存可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用A TMEL 高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,A TMEL 的A T89C51是一种高效微控制器,A T89C2051是它的一种精简版本。A T89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。外形及引脚排列如图3.2所示
图3.7 89C51引脚图
3.4 电路连线
利用wave6000仿真软件电路连线较为简单:
1) 电路内置为12MHZ 晶振频率工作
2) P1.0控制蜂鸣器。
3) 键盘接口KEY 与CS0连接
第四章 软件编程设计
4.1 编程方案
#include #define LEDLen 6
#define uint unsigned int
#define uchar unsigned char
xdata unsigned char OUTBIT _at_ 0x8002; // 位控制口 xdata unsigned char OUTSEG _at_ 0x8004; // 段控制口 xdata unsigned char IN _at_ 0x8001; // 键盘读入口 sbit speaker=P1^0;//接喇叭或蜂鸣器的接口 uint h,i,j; uint hz; uchar jiep; bit flag;
uint
fre[]={ 64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217}; uchar code sing1[]={6,9, 6,3, 7,12, 6,12, 9,12, 8,24, 6,9, 6,3, 7,12,6,12, 10,12, 9,24,
code
6,9, 6,3, 13,12, 11,12, 8,12, 7,12, 12,9, 12,3, 11,12, 9,12, 10,12, 9,24};
//歌谱 2个一组(0,0)(音调, 节拍)(生日歌)
uchar code sing2[]={4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 4,4,3,2,3,6, 4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 3,4,2,2,2,6, 3,3,3,3,4,3,2,3,3,3,4,1,5,2,4,3,2,3,3,3,4,1,5,2,4,3,2,3,2,3,3,3,6,6, 4,3,4,3,5,3,6,3,6,3,5,3,4,3,3,3, 2,3,2,3,3,3,4,3, 3,4,2,2,2,6, };
//歌谱 2个一组(0,0)(音调, 节拍)(欢乐颂)
void Delay(unsigned char CNT) {
unsigned char i;
while (CNT-- !=0)
for (i=100; i !=0; i--); }
code unsigned char KeyTable[] = { // 键码定义 0x16, 0x15, 0x14, 0xff, 0x13, 0x12, 0x11, 0x10, 0x0d, 0x0c, 0x0b, 0x0a, 0x0e, 0x03, 0x06, 0x09, 0x0f, 0x02, 0x05, 0x08, 0x00, 0x01, 0x04, 0x07 };
unsigned char TestKey() {
OUTBIT = 0; // 输出线置为0
return (~IN & 0x0f); // 读入键状态(高四位不用) }
unsigned char GetKey() {
unsigned char Pos; unsigned char i; unsigned char k;
i = 6;
Pos = 0x20; // 找出键所在列 do {
OUTBIT = ~ Pos; Pos >>= 1;
k = ~IN & 0x0f;
} while ((--i != 0) && (k == 0));
if (k != 0) // 键值 = 列 x 4 + 行 {
i *= 4; if (k & 2) i += 1; else if (k & 4) i += 2; else if (k & 8) i += 3;
OUTBIT = 0;
do Delay(10); while (TestKey()); // 等键释放
return(KeyTable[i]); // 取出键码 } else return(0xff); }
void init () //初始化 { EA=1; //中断允许总开关打开
TMOD=0x11; //定时器0、1都工作在方式1 ET0=1; //定时器T0中断允许 ET1=1; //定时器T1中断允许
i=0;j=0;
flag=1; }
void sing() { if(flag==1) { h=sing1[j]; //取音符 jiep=sing1[j+1]; //取节拍 j=j+2; //下一个音符 if(j>166) j=0;
hz=fre[h];
TH0=(hz)/256;
TL0=(hz)%256; //置定时器初值 flag=0;
TR0=1;
TR1=1; //开定时器
}
}
void sang()
if(flag==1)
{
h=sing2[j];
jiep=sing2[j+1];
j=j+2;
if(j>166) j=0;
hz=fre[h];
TH0=(hz)/256;
TL0=(hz)%256;
flag=0;
TR0=1;
TR1=1;
}
}
void main()
{uchar temp;
init();
while (1)
{
if (TestKey()) //查看是否有键按下
temp= (GetKey() & 0x0f); //取出键值
if(temp==1) //如果按下的是1,则播放第一首歌曲
{
sing(); //播放第一首歌曲
Delay(1); //延时
}
else if(temp==2) //如果按下的是2,则播放第二首歌曲
{
sang(); //播放第一首歌曲
Delay(1); //延时
}
}
}
void time0() interrupt 1 //定时器0
{
TH0=(hz)/256;
TL0=(hz)%256;
if(!flag) speaker=!speaker;
else TR0=0; //节拍未结束则继续翻转形成脉冲,结束则关定时器
}
void time1() interrupt 3
}
TH1=(15536)/256; TL1=(15536)%256; --jiep; if(jiep==0) flag=1; //本节拍结束,另flog 等于1,即关定时器0
第五章 心得体会
课程设计结束了,我收获了很多在课堂上无法学到的知识,不仅是硬件发设计能力,软件的编程能力也得到了大幅度的提高。本次课程设计的题目是音乐播放器,其要求是运用C51语言进行编程,实现可以播放多首歌曲,通过数字键进行控制播放歌曲的曲目。
刚拿到这个题目时,我们觉得挺简单,但当我们着手做的时候,却毫无头绪。我们在网络上下载了一些关于用单片机设计音乐播发器的内容。对课题有了大体的了解。之后就开始设计理图,程序流程图,并尝试编写程序慢慢有了点进展。
在课程实习过程中,硬件使用的都是实验箱,没有太大的问题存在,自己只需明白硬件功能,清楚实现方法,连好需要的几根线就可以了。软件设计一直困扰着我们,很难找到突破口。程序调试过程是一个需要细心和毅力的过程,当它脱离正常轨迹不按照应该的步骤进行时,我们就要一步一步的调试,找错误,找漏洞。老天不负有心人,当第一次整个系统成功实现预设功能。我们体会到艰辛和磨难后的喜悦。
虽然我们完成的还不够完美,但我们已经尽力了,相信老师也看到了在本次的设计中,我们一起构思、设计、编程、调试,这不仅巩固了我们的基础知识,也进一步培养了我们亲身实践动手的能力,这对我们将来的工作和研究都是大有好处的。团队合作真的很重要。最后还要感谢老师的耐心教导。