基于AT89C51单片机的电子音乐制作

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于AT89C51单片机的电子音乐制作

【摘要】本文以AT89C51单片机为核心,利用C语言设计制作了《祝你生日快乐》歌曲的电子音乐。并在播放音乐的同时伴随发光二极管的闪烁。

【关键词】单片机;电子音乐

1.引言

以单片机为核心制作的电子音乐结构简单、成本经济、工作效果好,在儿童玩具、礼物等很多场合都能得到大规模的应用。而利用单片机设计制作电子音乐对于高校学生理解、掌握单片机结构与原理,熟悉编写、调试程序,搭建硬件电路都有很大帮助。

2.单片机产生音乐的原理

声音是通过物体的振动产生的。如果单片机通过某一I/O口以一定的频率输出高电平、低电平,这一引脚便产生了一定频率的方波。该方波经放大电路放大,加到扬声器便会产生一定频率的声音。若方波频率发生变化,则声音频率也随之变化。通过控制输出方波时间的长短,声音的长短就会得到相应控制。因此根据乐谱,单片机就可以产生电子音乐。

3.方波的产生

8051单片机产生固定频率方波可以使用定时器/计数器T0或T1的溢出中断。在中断发生时,将P口引脚的电压取反使其输出方波。本文采用T1溢出中断。在T1的溢出中断服务程序中,执行重新装入计数初值,然后将输出引脚电压取反,在下次T1中断时,P口引脚再取反,即可输出方波。音乐节拍也可以利用延时程序来控制。

4.音符频率与定时器初始值

本文单片机采用12MHZ脉冲,则一个几周为1us,所以需要多长的时间(频率),就可以个定时器装入一个对应的初始值。

5.音符节拍选择

节拍就是音符演奏时间段长短。设一拍的十年为0.4秒,则其余拍数均可以此节拍推算出。而节拍的时间也可以通过延时实现。

6.音符代码

程序中使用一个字节来表示音符和该音符的节拍,音符代码的高4位是简

码,由它可以找到对应的定时器T1初始值;低4位代表音符节拍,其也可以通过查找节拍代码表获得。所以,我们只要找到《祝你生日快乐》这首乐曲的乐谱,找到其所对应的“简谱码”做高4位,再找到对应的节拍码做低4位,把高4位和低4位合成一个音符代码即可。

现将根据《祝你生日快乐》乐曲简谱转换后的音符代码表示如下:0x42,0x01,0x41,0x54,0x44,0x74,0x64,0x42,x01,0x41,0x54,0x44,0x84,0x74,0x74,0x42,0x01,0x41,0xB4,0x84,0x74,0x64,0xC4,0xA2,0x01,0xA1,x94,0x74,0x84,0x74,0x74。

将此代码存入程序存储器,程序执行时将音符代码按字节逐一读出,高4位是简谱码,低4为是音符节拍码,并根据T1计数器的初始值来设置时间,由此控制每一个音符的演奏时间,最终行动一段乐曲。

7.电子音乐电路设计

如图1所示,电路中使用20脚的AT80C2051为音乐电路核心。Q1、Q2组成复合管电路。P3.5端是音频信号的输出端,输出的方波信号经复合管电路驱动后驱动扬声器发声;发光二极管DS1~DS7和三极管Q3~Q9等元件组成音符显示电路,分别显示1、2、~7音符;P1.0~P1.6端经过R4~R10电阻分别连接Q3~Q9基极。当P1.0~P1.6端有输出低电平时,三极管饱和导通,对应的发光二极管点亮。S2与R3构成启动电路,按下S2给P3.7引脚送入低电平,启动放音。

图1 电子音乐电路图

8.源程序设计

#include<reg51.h>

sbit sp=P3 ;sbit sw=P3 ;unsigned char i=0;

un,signed char hi_note=0;unsigned char low_note=0;

code unsigned song[ ]={0x42,0x01,0x41,0x54,0x44,0x74,0x64,0x42,x01,0x41,0x54,0x44,0x84,0x74,0x74,0x42,0x01,0x41,0xB4,0x84,0x74,0x64,0xC4,0xA2,0x01,0xA1,x94,0x74,0x84,0x74,0x74,0x42,0x01,0x41,0x54,0x44,0x74,0x64,0x42,x01,0x41,0x54,0x44,0x84,0x74,0x74,0x42,0x01,0x41,0xB4,0x84,0x74,0x64,0xC4,0xA2,0x01,0xA1,x94,0x74,0x84,0x74,0x74,0x00};

code int note[ ]={0x0000,0xFB03,0xFB83,0xFC0B,0xFC43,0xFCAB,0xFD08,0xFD32,0xFD81,0xFDC7,0xFE05,0xFE21,0xFE55,0xFE83,0xFE99,0xFEC0}

code unsigned char led[ ]={0xFF,0xEF,0xDF,0xBF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF};

void delay(unsigned int n)

{

unsigned int I,j;

for(i=0;i<1000*n;i++)

for(j=0;j<120;j++);

}

static void timer1_isr(void)interrupt TF1_vector using 2

{

TR1=0;

TL1=low_note;

TH1=hi_note;

TR1=1;

sp=~sp;

}

static void timer1_initialize(void)

{

EA=0;

TR1=0;

TMOD=0X10;

ET1=1;

相关文档
最新文档