单片机演奏简单的音乐
51单片机蜂鸣器播放单音节音乐

0xFD,0x23,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
// 1_ 3_ 2 .5
0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFA,0x68,0xFF,
{
for (i =0; i < 363; i++)
{;}
}
}
*名称:Init()
*功能:设置计数器0工作方式,16位计数,溢出中断方式
**********************************************************************************/
void Init()
{
TMOD = 0x01; //定时器0处于计时方式,16位
*名称:Count1(void) interrupt 1
*功能:设置计时器0溢出中断,每中断一次改变P2_3引脚电平
*********************************************************************************/
void Count1(void) interrupt 1
void main()
{
uchar time;
Init();
TH0 = high;
TL0 = low;
while (1)
{
if (music[ptr] != 0xFF && music[ptr] != 0x00)//判断是否是正常音符
{
TR0 = 0;
P2_3 = 1;
基于MCS—51单片机简单音乐发生器的设计 精品

湖南工业职业技术学院Hunan Industry Polytechnic毕业实践类别毕业设计题目基于MCS—51单片机简单音乐发生器的设计系名称专业及班级学生姓名学号 10指导教师王皑赵俊完成日期 2009年 4月15日湖南工业职业技术学院毕业实践任务书系名称电气工程系专业及班级电信S06-4学生姓名毛浩学号 10毕业实践题目:毕业设计基于MSC-51单片机简单音乐发生器的设计指导教师(签字):教研室主任(签字):系主任(签字):2009年1月10日毕业实践课题及任务课题简介该课题主要利用单片机技术,采用汇编语言或C语言编程来控制音乐发生器实现弹奏音乐的过程。
其目的是培养学生利用单片机控制技术,汇编语言或C语言编程控制技术解决生产、生活中的实际问题,对提高学生的设计能力动手能力和工程实践技能有较重要的意义。
学生在设计该课题时,应具备电路分析、电子技术、电子CAD 技术、单片机控制技术、C语言程序设计等方面的相关知识,掌握电路设计流程图,电子元器件的选择、电路原理图的设计及连线。
熟悉程序的编写,输入,修改和调试等。
课题任务要求1、选择正确的电子元件…………………………………………………………2、画出电气控制系统原理图及PCB板的布线设计……………………………3、用C语言或汇编语言编写出系统控制程序…………………………………4、系统的安装与调试……………………………………………………………进程安排第3周:根据课题要求,查阅相关理论书籍,设计参考书及相关资料,进一步加深对课题的理解和认识。
第4周:根据控制要求,设计控制电路状态流程图,设计系统控制程序,设计系统电气控制原理图。
第5周:选择电子电器元件。
第6周:开始组装电路,上机开始调试控制程序。
第7周:调试,修改,完善设计,撰写毕业设计说明书。
第8周:设计资料的修改、整理、完善。
毕业设计答辩。
毕业实习(第1周—第2周)地点:湘计算机厂、湖南机床厂、长沙电机厂、曙光电子厂、长沙水泵厂或自找实习单位实习内容及要求:了解企业现状及发展趋势,熟悉生产、装配及加工工艺流程,了解企业的新技术、新工艺的应用情况,调查了解企业对专业技术人员人才需求情况及人才特点,写出实习报告(5000字以上)参考资料1、徐仁贵、廖哲智主编《单片微型计算机应用技术》北京:机械工业出版社20032、刘仁宇、施伟主编.《模拟电子技术》北京:机械工业出版社19983、卢庆林主编《数字电子技术》北京:机械工业出版社20054、龙志文主编《电力电子技术》北京:机械工业出版社20055、邱丽芳主编《单片机原理与应用》人民邮电出版社20076、王廷才主编《电子线路CAD Protel99使用指南》机械工业出版社20067、林志琦主编《基于Proteus的单片机可视化软硬件仿真[M]》北京航天航空大学出版20068、徐仁贵主编《单片微型计算机应用技术[M]》北京:机械工业出版社20009、戴佳戴卫恒主编《51单片机C语言应用程序设计实例精讲[M]》北京:电子工业出版社2007湖南工业职业技术学院毕业实践开题报告书电气工程系电子信息工程专业学生姓名毛浩班级电信S06-4 学号10 课题名称基于MSC-51单片机简单音乐发生器的设计课题准备情况在动手做设计之前,我们在网上查找了一些设计的思路和方法,再与之关联的知识,在图书馆查阅了单片微型计算机应用技术、电力电子技术、电路分析、电子线路CAD、微机原理与应用技术、等与音乐发生器有关书籍资料。
基于单片机的简易音乐播放器的设计说明书

天津天狮学院毕业实践报告题目:基于单片机的简易音乐播放器的设计二级学院电子与计算机学院专业电子信息工程技术学生姓名卫小丽指导教师苗艳华2012年06月01日摘要本文是基于单片机控制的音乐播放器的设计, 它可以实现音乐的播放,可以通过功能键来选择乐曲,播放或暂停。
共有K1到K4四个功能键,K1-K3分别播放三首不同音乐,K4为暂停键。
主控芯片采用AT89C52,辅以必要的电路,采用C语言进行编程,编程后利用KEIL C51来进行编译,再将生成的HEX文件装入芯片中,采用proteus软件来仿真,检验功能得以正常实现。
通过烧写不同的程序,可以实现多首不同音乐的更换。
本文将围绕基于单片机的自动音乐播放器,介绍一些关于单片机的基础知识、模块电路设计、音乐播放器的原理(其中包括了音乐编程原理)、以及仿真软件的使用。
关键词:单片机AT89C52,音乐播放,proteus目录一、功能介绍 (1)1.1功能特点 (1)1.2原理说明 (1)二、硬件电路设计 (1)2.1系统方案设计 (1)2.2模块电路的设计 (2)2.2.1 AT89C52型单片机的介绍 (2)2.2.2单片机最小系统的设计 (4)2.2.3蜂鸣器电路设计 (5)2.2.4按键电路设计 (6)2.2.5 LED显示电路设计 (6)三、软件设计 (7)3.1系统主模块流程图 (7)3.2音乐产生原理 (7)3.2.1音调 (8)3.2.2节拍 (9)四、PROTEUS仿真应用 (10)4.1PROTEUS软件简介 (10)4.2仿真结果 (11)五、结论 (12)参考文献 (13)致谢 (14)附录1 (15)附录2 (16)一、功能介绍1.1 功能特点本设计是一个基于AT89C52系列单片机的音乐播放器,依据单片机技术原理,通过硬件电路设计以及软件编译,设计出一个多功能音乐播放器。
该音乐播放器主要由按键电路、晶振电路、复位电路以及扬声器组成。
基于51单片机的简易音乐播放器

课程目的以及要求用51单片机作为主控电路设廿一个电子琴,实规能通过切换不同的健盘按傩来切换歌曲。
电子琴是现代电子科技与音乐结合的产物,是一种新型的鍵盘乐器。
它在规代音乐扮演着重要的角色,单片机貝有强大的控制功能和灵活的编程实现特性,它已经溶人现代人们的生活中,成为不可替代的一部分。
本文的主要内容是用STC89C52单片机为核心控樹元件, 设廿一个电子琴。
以单片机作为主控核心,与键盘、扬声器等模块组成核心主控制模块。
本文主要对使用单片机设廿简易电子琴进行了分析,并介绍了基于单片机电子琴统硬件组成。
利用单片机产生不同颜率来获得我们要求的音阶,最终可师意强奏想要表达的音乐。
并且本文分别卩、原理图, 主要芯片,各模块原理及各模块的程序的调试来库细阐述。
E:系筑硕件披廿3.1系筑杞图按键键盘3.2 51单片机产生音符原理MCS-5I单片机有两个定时器/廿数器。
系统使用定时器/廿数器0 产生方液。
定时器/廿数器IM用于记录音符的时长,即按键持续的时间。
定时器/计数器0的工作方式是I,即为16 R定时器/计数器。
16位定时器/计数器被US予一个初值,并开始记数。
当记数謚出,产生中断后,中断服务程序将与蜂鸣器连接的引脚电平置反,并且对定时器/廿数器再Kfflfi,重新开始记效。
之后产生中撕,引脚电平再被置反,如此周而复始,在引啣上就能产生一个颐率勺定时初值有关的方波信号。
而定时初值与音符颐率有关,相应频率的确定,可参照12平均律,相邻两个半音A和B的顺率之间的关系为:A= ,1,o定时器/廿数器I的作用为记录音符的时长,工作方式为I, BP 16 位定时器/廿数器。
在12MHZ的晶体振葫器F,单片机的机器周期为I M S O本系统中,定时器/廿数器I以10ms的时长为I定时单位,记录音符持续了多少个定时单位,如此,使用一个unmgnedchar ®变量既可以记录2.55s的时长,这在用于记录—般弹奏的音符时是足昵的。
如何让单片机演奏音乐

88河南科技2011.03 下如何让单片机演奏音乐河南信息工程学校 李 峡分析图2可知,1KHz 的信号周期为1ms ,信号电平每0.5ms 取反1次,因此100ms 内信号电平要变化200次。
同理,500Hz 信号周期为2ms ,信号电平为每1ms 取反1次,200ms 内信号电平也要变化200次。
只要在单片机的I/O 口循环输出1KHz (持续100ms )和500Hz (持续200ms )的信号就可以了,输出信号时的持续时间可以用软件产生,也可以用定时/计数器产生。
以软件延时为例,可编程如下:MAIN: MOV R0, #DATA1 ;R0中存放循环次数DATA1,决定第1种音 频的持续时间LOOP1: CPL P1.0;输出取反,产生第1种音频信号LCALL DELAY1;DELAY1的延时时间决定第一种音频信号频率DJNZ R0, LOOP1;第1种音频信号持续一定时间,直到R0为0MOV R0, #DATA2 ;R0中存放循环次数DATA2,决定第2种音频的持续 时间LOOP2: CPL P1.0;输出取反,产生第2种音频信号LCALL DELAY2;DELAY2的延时时间决定第2种音频信号的频率DJNZ R0, LOOP2;第2种音频信号持续一定时间,直到R0为0LJMP MAIN;依次循环以上程序段中DELAY1、DELAY2为延时子程序,只要让DA-LAY1的延时时间为0.5ms ,让DALAY2的延时时间为1ms ,每次向R0中存放循环次数200,即可得到图2所示的双音频信号。
修改DE-LAY1、DELAY2,可以改变2种音频信号的频率;而改变R0的值,则可以改变每种音频持续的时间。
三、让单片机演奏一首乐曲要想让单片机演奏乐曲,首先要了解一些简单的乐理知识,这样才能进行编程。
所有音乐都由4个基本要素构成,即音的高低、音的长短、音的力度和音质,而其中最重要的是“音的高低”和“音的长短”。
单片机实现电子琴并可播放歌曲

0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8e};
//中音1-7和高音1-7对应频率列表
uint16 code NoteFrequ[] = {
523,587,659,698,784,880,988, //中音1-7
for(i=0;i<4;i++)
{
P2=buff[i];
temp=P2;
temp&=0xf0;//取P2的高四位;
while(temp!=0xf0)
{
delay5ms(5);//延时5ms去除抖动;
temp=P2;
temp&=0xf0;
while(temp!=0xf0)
{
switch(temp)
{
case 0xe0:num=i*4+0;break;//获取键值;
}
if(num==8)
{
T0LoadH = 0xff;
T0LoadL = 0x00;
TR0 = 1;
flag = 0;
ADDR0 = 0;
ADDR1 = 1;
ADDR2 = 1;
P0 = 0x00;
for(i=0;i<10000;i++);//闪烁灯全亮
PlayTwoTiger();
}
}
void PlayTwoTiger()
//计算发生时间,为总时间的0.75
/***********去除抖动********************/
while(temp!=0xf0)
{
temp=P2;
用51单片机播放音乐(附C程序)
用51单片机IO口播放几首音乐(附C程序)以下为51单片机播放音乐简谱的函数库:/*说明************************************************************************曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0}; 末尾:0,0 表示结束(Important)音高由三位数字组成:●个位是表示 1~7 这七个音符;●十位是表示音符所在的音区:1-低音,2-中音,3-高音;●百位表示这个音符是否要升半音: 0-不升,1-升半音。
音长最多由三位数字组成:●个位表示音符的时值,其对应关系是: |数值(n): |0 |1 |2 |3 | 4 | 5 | 6 |几分音符: |1 |2 |4 |8 |16 |32 |64 音符=2^n ;●十位表示音符的演奏效果(0-2): 0-普通,1-连音,2-顿音;●百位是符点位: 0-无符点,1-有符点。
调用演奏子程序的格式:Play(乐曲名,调号,升降八度,演奏速度);|乐曲名 : 要播放的乐曲指针,结尾以(0,0)结束;|调号(0-11) : 是指乐曲升多少个半音演奏;|升降八度(1-3) : 1:降八度, 2:不升不降, 3:升八度;|演奏速度(1-12000): 值越大速度越快;***************************************************************************/#ifndef __SOUNDPLAY_H_REVISION_FIRST__#define __SOUNDPLAY_H_REVISION_FIRST__#include//**************************************************************************#define SYSTEM_OSC 11059200//12000000 //定义晶振频率12000000HZ#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔sbit BeepIO = P2^6; //定义输出管脚unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 }; //1~7在频率表中的位置unsigned char code LengthTab[7]= { 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 = 1;Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值 (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(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed){unsigned int NewFreTab[12]; //新的频率表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<12;i++) // 根据调号及升降八度来生成新的频率表{j = i + Signature;if(j > 11){j = j-12;NewFreTab[i] = FreTab[j]*2;}elseNewFreTab[i] = FreTab[j];if(Octachord == 1)NewFreTab[i]>>=2;else if(Octachord == 3)NewFreTab[i]<<=2;}SoundLength = 0;while(Sound[SoundLength] != 0x00) //计算歌曲长度{SoundLength+=2;}Point = 0;Tone = Sound[Point];Length = Sound[Point+1]; // 读出第一个音符和它时时值LDiv0 = 12000/Speed; // 算出1分音符的长度(几个10ms)LDiv4 = LDiv0/4; // 算出4分音符的长度LDiv4 = LDiv4-LDiv4*SOUND_SPACE; // 普通音最长间隔标准TR0 = 0;TR1 = 1;while(Point < SoundLength){SL=Tone%10; //计算出音符SM=Tone/10%10; //计算出高低音SH=Tone/100; //计算出是否升半CurrentFre = NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率if(SL!=0){if (SM==1) CurrentFre >>= 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 + 12; //加12是对中断延时的补偿}SLen=LengthTab[Length%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 (SLen<=4)LDiv1=LDiv-LDiv4;elseLDiv1=LDiv*SOUND_SPACE;elseLDiv1=LDiv/2; //算出顿音的演奏长度elseLDiv1=LDiv;if(SL==0) LDiv1=0;LDiv2=LDiv-LDiv1; //算出不发音的长度if (SL!=0){TR0=1;for(i=LDiv1;i>0;i--) //发规定长度的音{while(TF1==0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;}}if(LDiv2!=0){TR0=0; BeepIO=1;for(i=LDiv2;i>0;i--) //音符间的间隔{while(TF1==0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;}}Point+=2;Tone=Sound[Point];Length=Sound[Point+1];}BeepIO = 1;}//**************************************************************************#endif附录:以下为曲谱编码文件,自己可以根据规则,对照简谱编写曲谱编码表。
用单片机制作简单音乐播放器代码
if(k==6) return 0xdf; if(k==7) return 0xbf; if(k>=8) return 0x7f; }
uint temp;
uchar jp;//jp 是简谱 //用于产生各种音调 j=0; while(!RI) {
temp=happynewyear[j]; jp=temp/16; //取数的高 4 位 P1=light(jp); if(jp!=0) {
timeh=cuzhi[jp*2]; timel=cuzhi[jp*2+1]; } else {
void main () {
TMOD=0x21; TH1=0xfd; TL1=0xfd; TR1=1; REN=1; SM0=0; SM1=1; while(1) {
if(RI==1) {
RI=0; a=SBUF; if (a==1) {
main1(); EA=0; TR0=0;
} if(a==2) {
ET0=1; song2();
} void song2() {
uint temp;
uchar jp;//jp 是简谱 //用于产生各种音调 j=0; while(!RI) {
temp=wnyhln[k]; jp=temp/16; //取数的高 4 位 P1=light(jp); //LED 灯伴随音调的变化而闪烁 if(jp!=0) {
} void song3() {
uint temp;
uchar jp;//jp 是简谱 //用于产生各种音调 j=0; while(!RI) {
temp=ysysljj[h]; jp=temp/16; //取数的高 4 位 P1=light(jp); if(jp!=0) {
单片机课程设计报告--简易音乐播放器
第一章前言伴随着科技的发展和时代的进步,人们对生活质量的要求也越来越高,由以前简单的追求温饱和物质财富转向更高层面的精神追求!而这一切催生了智能仪器的发展,音乐则是人们娱乐生活的重要组成部分,目前市场上出现了许许多多的音乐播放器,而人们对播放器的功能需求也越来越广泛,本文将设计一个基于单片机的音乐播放器,通过对其全面的介绍与分析,让大家了解音乐播放器的原理!第二章: 简易音乐播放器的功能和原理说明音乐播放器,可以通过单片机板子上的数字按键对音乐播放的曲目进行控制,并且通过LED灯将播放的音乐加以区分,在播放音乐的同时点亮LED灯,让人知道现在正在播放的音乐曲目,从而实现简单的音乐播放功能!表1 需求分析功能说明:这次设计是依据单片机技术原理,通过硬件电路设计以及软件的编译而设计的一个简单的音乐播放器,可以通过按键选择播放四首歌曲(歌曲自选,只要将想要播放的歌曲的乐谱写入程序中即可)同时点亮相应的LED灯,并用它来指示当前播放的歌曲序列,只能实现简单的音乐播放功能。
原理说明:这个音乐播放器主要有晶振电路,复位电路,LED电路,按键电路以及扬声器组成。
它利用单片机产生乐曲音符,再把乐曲音符翻译成计算机音乐语言,接着用单片机进行信息处理,再通过蜂鸣器或喇叭放出音乐。
音乐的产生主要是通过单片机的I/O口输出高低不同的脉冲信号来控制扬声器发音。
通常利用单片机的内部定时器0,工作在方式1下,再改变计数初值TH0和TL0来产生不同频率。
当控制歌曲按键按下时,按照预先存放在单片机中的程序,就会自动判断键值,然后启动计数器,按照程序产生一定频率的脉冲,接着通过uln2003芯片驱动扬声器,播放出乐曲。
该硬件电路中用P3.0,P3.1,P3.2,P3.3控制四个按键,“0”,“1”,“2”,“3”分别控制四首音乐。
P1.0,P1.1,P1.2,P1.3控制四个LED灯,它们分别对应四个按键,用来显示正在播放的歌曲,并用P2.3 来控制扬声器,电路为12MHz晶振频率工作,起振电路中C1 和C2为22pf。
单片机音乐播放器应用 实现简单的音乐播放功能
单片机音乐播放器应用实现简单的音乐播放功能单片机音乐播放器应用音乐是人们生活中不可或缺的一部分,而在现代科技的不断发展下,单片机音乐播放器应用已经成为许多人追求的目标。
本文将介绍如何实现一个简单的单片机音乐播放器功能,让您能够轻松享受音乐的魅力。
一、硬件准备在开始之前,我们需要准备一些硬件设备,以确保音乐播放器能够正常工作。
首先,我们需要一块单片机开发板,例如STC89C52,这是一款常用的单片机开发板;其次,我们需要一个音频解码模块,例如DFPlayer Mini,他可以轻松解码并播放存储卡上的音乐文件;最后,我们还需要一个音箱或者耳机,用于输出音乐。
二、软件编程1. 搭建开发环境首先,我们需要安装MIDE-51集成开发环境,它是STC89C52单片机所使用的开发工具。
安装完成后,可以通过打开MIDE-51来创建一个新的工程。
2. 编写代码首先,我们需要在代码中包含一些必要的库文件,以便使用一些功能函数。
例如,我们可以通过以下代码片段引入DFPlayer Mini音频库文件:```c#include <DFPlayer_Mini_Mp3.h>```接下来,我们可以通过定义一些常量或变量来控制音乐的播放,例如:```cconst int playButton = 2; // 播放按钮连接到单片机的2号引脚const int nextButton = 3; // 下一首按钮连接到单片机的3号引脚const int previousButton = 4; // 上一首按钮连接到单片机的4号引脚```然后,我们可以在主循环中不断检测按钮的状态,并根据按钮的状态来控制音乐的播放:```cvoid loop() {if (digitalRead(playButton) == HIGH) { // 如果播放按钮被按下DFPlayer_Mini_Mp3.play(); // 播放音乐}if (digitalRead(nextButton) == HIGH) { // 如果下一首按钮被按下 DFPlayer_Mini_Mp3.next(); // 播放下一首音乐}if (digitalRead(previousButton) == HIGH) { // 如果上一首按钮被按下DFPlayer_Mini_Mp3.previous(); // 播放上一首音乐}}```通过上述代码,我们可以实现简单的音乐播放功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为了让单片机演奏音乐,看了不少的资料,现在整理了相关的资料,让你一次看懂音调、节拍的确定方法,看懂简谱,懂得编写用来演奏音乐的程序。
单片机不能像其他的专业的乐器一样能奏出多种音色的声音,即不包含相应幅度的谐波频率。
单片机演奏的音乐基本都是点单音频率。
因此单片机演奏音乐比较简单,只需弄清楚“音调”和“节拍”两个概念即可。
音调表示一个音符唱的多高的频率。
节拍表示一个音符唱多长的时间。
那么音调、节拍该怎样确定呢?首先来看音调的确定:不同音高的乐音是用C、D、E、F、G、A、B来表示,这7个字母就是音乐的音名,它们一般依次唱成DO、RE、MI、FA、SO、LA、SI,即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”,即Tone。
在音乐中常把五线谱中央C 上方的A 音定为标准音高,其频率f=440Hz。
当两个声音信号的频率相差一倍时,也即f2=2*f1时,则称f2比f1 高一个倍频程, 例如高音DO的频率(1046Hz)刚好是中音DO的频率(523Hz)的一倍,中音DO的频率(523Hz)刚好是低音DO频率(266 Hz)的一倍;同样的,高音RE的频率(1175Hz)刚好是中音RE 的频率(587Hz)的一倍,中音RE的频率(587Hz)刚好是低音RE频率(294 Hz)的一倍。
在音乐学中称它相差一个八度音。
在一个八度音内,有12个半音。
以1—i 八音区为例,12 个半音是:1—#1、#1—2、2—#2、#2—3、3—4、4—#4,#4—5、5 一#5、#5—6、6—#6、#6—7、7—i。
那些在它们的左上角加上﹟号或者b号的叫变化音。
﹟叫升记号,表示把音在原来的基础上升高半音,b叫降记音,表示在原来的基础上降低半音。
这12 个音阶的分度基本上是以对数关系来划分的。
如果我们只要知道了这十二个音符的音高,也就是其基本音调的频率,我们就可根据倍频程的关系得到其他音符基本音调的频率。
基本频率看下表:低音频率中音频率高音频率Do262Do523Do1046Do﹟277Do﹟554Do﹟1109Re294Re587Re1175Re﹟311Re﹟622Re﹟1245Mi330Mi659Mi1318Fa349Fa698Fa1397Fa﹟370Fa﹟740Fa﹟1480So392So784So1568So﹟415So﹟831So﹟1661La440La880La1760La﹟464La﹟932La﹟1865Si494Si988Si1976知道了一个音符的频率后,采用的方法就是通过一个延时程序,延时对应频率周期的二分之一周期(即t=1/2T)后,将单片机上连接蜂鸣器的I/O口来回取反,或者说来回清零,置位,从而让蜂鸣器发出声音,为了让单片机发出不同频率的声音,我们只需将不同的延时时间值t赋给延时程序即可实现。
一般说来,常采用的方法就是通过单片机的定时器定时中断,将单片机上对应蜂鸣器的I/O口来回取反,或者说来回清零,置位,从而让蜂鸣器发出声音,为了让单片机发出不同频率的声音,我们只需将定时器予置不同的定时值就可实现。
那么怎样确定一个频率所对应的定时器的定时值呢?以标准音高A为例:A的频率f = 440 Hz,其对应的周期为:T = 1/ f = 1/440 =2272μs由上图可知,单片机上对应蜂鸣器的I/O口来回取反的时间应为:t = T/2 = 2272/2 = 1136μs这个时间t也就是单片机上定时器应有的中断触发时间。
一般情况下,单片机奏乐时,其定时器为工作方式1,它以振荡器的十二分频信号为计数脉冲。
设振荡器频率为f0,则定时器的予置初值由下式来确定:t = 12 *(TALL – THL)/ f0式中TALL = 2^16 = 65536,THL为定时器待确定的计数初值。
因此定时器的高低计数器的初值为:TH = THL / 256 = ( TALL – t* f0/12) / 256TL = THL % 256 = ( TALL – t* f0/12) %256将t=1136μs代入上面两式(注意:计算时应将时间和频率的单位换算一致),即可求出标准音高A在单片机晶振频率f0=12Mhz,定时器在工作方式1下的定时器高低计数器的予置初值为:TH 440Hz = (65536 – 1136 * 12/12) /256 = FBHTL 440Hz = (65536 – 1136 * 12/12)%256 = 90H根据上面的求解方法,我们就可求出其他音调相应的计数器的予置初值。
如下表:(12MHz的单片机晶振)音调对应的计数器预置值:低音频率TH TL中音频率TH TL高音频率TH TL1262F88B1523FC4311046FB211﹟277F8F21﹟554FC781﹟1109FE3C2294F95B2587FCAB21175FE552﹟311F9B72﹟622FCDB2﹟1245FE6D3330FA143659FD0831318FE844349FA664698FD3341397FE994﹟370FAB94﹟740FD5B4﹟1480FEAD5392FB035784FD8151568FEC05﹟415FB4A5﹟831FDA55﹟1661FE026440FB8F6880FDC761760FEE36﹟464FBCF6﹟932FDE76﹟1865FEF37494FC0B7988FE0571976FF02知道了音调的确定方法,那就再来看看节拍的确定吧:若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快满度。
确定节拍的方法如下1.在一张乐谱中,我们经常会看到这样的表达式,等等,这里1=C,1=G表示乐谱的曲调,和我们前面所谈的音调有很大的关联(呵呵,其关联就是升或降音调),就是用来表示节拍的。
以为例加以说明,它表示乐谱中以四分音符为节拍,每一小结有三拍。
比如:其中1 、2 为一拍,3、4、5 为一拍,6为一拍共三拍。
1 、2的时长为四分音符的一半,即为八分音符长,3、4的时长为八分音符的一半,即为十六分音符长,5 的时长为四分音符的一半,即为八分音符长,6的时长为四分音符长。
那么一拍到底该唱多长呢?一般说来,如果乐曲没有特殊说明,一拍的时长大约为400—500ms 。
如果我们以一拍的时长为400ms 为例,则当以四分音符为一节拍时,四分音符的时长就为400ms,八分音符(即1/2拍)的时长就为200ms,十六分音符(1/4拍)的时长就为100ms。
只要设定延迟时间就可求得节拍的时间。
假设1/4拍为1DELAY,则1拍应为4DELAY,以此类推。
所以只要求得1/4拍的DELAY时间,其余的节拍就是它的倍数。
2.若知道了一首歌曲的每分钟的节拍数,也可求出每一节拍的时间。
以每分钟94拍为例:一拍的时间=60/94=0.64s=640ms关于音符长短的知识:在简谱中,1、2、3、4、5、6、7这七个基本音符,不仅表示音的高低,而且还是表示时值长短的基本单位,称为四分音符,其他音符均是在四分音符的基础上,用加记短横线"-"和附点"·"表示。
1.单纯音符在简谱中,如果音符时值的长短用短横线" -"表示,就称为单纯音符。
单纯音符除四分音符外,有以下两种形式:⑴ 在基本音符右侧加记一条短横线,表示增长一个四分音符的时值。
这类加记在音符右侧、使音符时值增长的短横线,称为增时线。
增时线越多,音符的时值越长。
⑵ 在基本音符下方加记一条短横线,表示缩短原音符时值的一半。
这类加记在音符下方、使音符时值缩短的短横线,称为减时线。
减时线越多,音符的时值越短。
单纯音符的名称以全音符为标准而定。
如:全音符的二分之一称为二分音符,全音符的四分之一称为四分音符,其余类推。
常见的单纯音符的名称、写法及时值长短列表如下:2.附点音符在简谱中,加记在单纯音符的右侧的.使音符时值增长的小圆点·,称为附点.加记附点的音符称为附点音符。
附点本身并无一定的长短,其长短由前面的单纯音符来决定。
附点的意义在于增长原音符时值的一半,常用于四分音符和小于四分音符的各种音符之后。
例如:附点四分音符:附点八分音符:附点十六分音符:在简谱中,大于四分音符的单纯音符通常不加记附点,而用增时线来表示。
例如;附点二分音符:不用表示。
带有两个附点的单纯音符称为复附点音符,第二个附点表示增长第一个附点时值的一半,即音符时值的四分之-。
例如:复附点常用于器乐曲中,在歌曲中很少使用。
通过上面关于一个音符音调和节拍的确定方法,我们就可以在单片机上实现演奏音乐了。
具体的实现方法为:将乐谱中的每个音符的音调及节拍变换成相应的音调参数和节拍参数,将他们做成数据表格,存放在存储器中,通过程序取出一个音符的相关参数,播放该音符,该音符唱完后,接着取出下一个音符的相关参数……,如此直到播放完毕最后一个音符,根据需要也可循环不停地播放整个乐曲。
另外,对于乐曲中的休止符,一般用00H表示,乐曲结束音符用FFH来表示。
说到这里看看你能不能够看懂简谱了呢,来对照着简谱看看为了方便编程下面再来看看编码吧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位,得到延时时间,接着调用软件延时。
简谱对应的音调简码、节拍简码发音音调音调简码节拍数音符长度节拍简码停顿00中音DO111/4拍十六分音符1中音RE221/2拍八分音符2中音MI333/4拍3中音FA441拍四分音符4中音SO555/4拍1又1/4拍全分音符5中音LA666/4拍1又1/2拍6中音SI778/4拍2拍二分音符8高音DO1810/4拍2又1/2拍A高音RE2912/4拍3拍C高音MI3A15/4拍3又3/4拍E高音FA4B4拍全分音符F高音SO5C高音LA6D高音SI7E结束F例子:#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit buzzer=P3^7;//蜂鸣器连续的IO口uchar timeH,timeL,i;//---------------------------简谱---------------------------------------//编程规则://字节高四位是音调(1-7代表中央C调,8-E代表高八度,0代表停顿),//低四位是节拍//最后的FF是结束标志uchar code xiaoPingGuo[] = { //小苹果简谱0x62, 0x62, 0x62, 0x31, 0x81, 0x82, 0x72, 0x62, 0x32, 0x01,0xa2, 0x92, 0x82, 0x62, 0x52, 0x64, 0x01,0xc2, 0xa2, 0x92, 0x81, 0x91, 0x92, 0xa2, 0x92, 0x52,0x62, 0xa2, 0x92, 0x82, 0x82, 0x52, 0x62,0x62, 0x61, 0x71, 0x82, 0x92, 0xc2, 0xb2, 0xa2, 0x82,0x82, 0x32, 0x52, 0x62, 0x02, 0x52, 0x64,0xa2, 0x92, 0x82, 0x61, 0x91, 0x92, 0x82, 0x62, 0x32,0x52, 0xa2, 0x92, 0x82, 0x82, 0xc2, 0x64, 0x08,//前奏0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x64,//我种下一颗种子0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x54,//终于长出了果实0x52, 0x52, 0x52, 0x52, 0x52, 0x62, 0x52, 0x62, 0x6f, //今天是个伟大日子0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x64,//摘下星星送给你0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x54,//拽下月亮送给你0x52, 0x52, 0x52, 0x52, 0x52, 0x62, 0x52, 0x62, 0x6f, //让太阳每天为你升起0x62, 0x62, 0x62, 0x72, 0x82, 0xa2, 0x92, 0x82,//变成蜡烛燃烧自己0x72, 0x62, 0x72, 0x62, 0x78,//只为照亮你0x52, 0x52, 0x52, 0x62, 0x72, 0x92, 0x82, 0x72,//把我一切都献给你0x62, 0x52, 0x62, 0x52, 0x68,//只要你欢喜0x62, 0x62, 0x62, 0x72, 0x82, 0xa2, 0x92, 0x82,//你让我每个明天都0x72, 0x62, 0x72, 0x62, 0x78,//变得有意义0x52, 0x52, 0x52, 0x62, 0x72, 0x92, 0x82, 0x72,//生命虽短爱你永远0x14, 0x14, 0x14, 0x14,//不离不弃0xa4, 0x84, 0x94, 0x64,//你是我的0xa2, 0x92, 0x82, 0x92, 0x68,//小呀小苹果儿0xa4, 0x84, 0x94, 0x94,//怎么爱你0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,//都不嫌多,红红0x64, 0x72, 0x82, 0x94, 0x54,//的小脸儿温暖0xd2, 0xc2, 0xa4, 0xa4, 0xa2, 0x92,//我的心窝0x84, 0x92, 0xa2, 0x92, 0xa2, 0x92, 0xc2, 0xcf,//点亮我生命的火火火火火0xa4, 0x84, 0x94, 0x64,//你是我的0xa2, 0x92, 0x82, 0x92, 0x68,//小呀小苹果儿0xa4, 0x84, 0x94, 0x92, 0x92,//就像天边0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,//最美的云朵0x64, 0x72, 0x82, 0x94, 0x54,//春天又来到了0xd2, 0xc2, 0xa4, 0xa4, 0xa2, 0x92,//花开满山坡0x84, 0x92, 0xa2, 0x94, 0x52,//种下希望0x64, 0x62, 0x82, 0x68,//就会收获0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0xc2, 0xd2, 0x82, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0x82, 0xe2, 0x82, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0xc2, 0xd2, 0xc2, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0x82, 0xe2, 0x82, 0xd2, 0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x64,//从不觉得你讨厌0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x54,//你的一切都喜欢0x52, 0x52, 0x52, 0x52, 0x52, 0x62, 0x52, 0x62, 0x6f,//有你的每天都新鲜0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x64,//有你阳光更灿烂0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x54,//有你黑夜不黑暗0x52, 0x52, 0x52, 0x52, 0x52, 0x62, 0x52, 0x62, 0x6f,//你是白云我是蓝天0x62, 0x62, 0x62, 0x72, 0x82, 0xa2, 0x92, 0x82,//春天和你漫步在0x72, 0x62, 0x72, 0x62, 0x78,//盛开的花丛间0x52, 0x52, 0x52, 0x62, 0x72, 0x92, 0x82, 0x72,//夏天夜晚陪你一起0x62, 0x52, 0x62, 0x52, 0x68,//看星星眨眼0x62, 0x62, 0x62, 0x72, 0x82, 0xa2, 0x92, 0x82,//秋天黄昏与你徜徉0x72, 0x62, 0x72, 0x62, 0x78,//在金色麦田0x52, 0x52, 0x52, 0x62, 0x72, 0x92, 0x82, 0x72,//冬天雪花飞舞有你0x14, 0x14, 0x14, 0x14,//更加温暖0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0xc2, 0xd2, 0x82, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0x82, 0xe2, 0x82, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0xc2, 0xd2, 0xc2, 0xd2, 0xa2, 0xd1, 0xd1, 0xc2, 0xd2, 0x82, 0xe2, 0x82, 0xd2, 0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,0xa4, 0x84, 0x94, 0x64,//你是我的0xa2, 0x92, 0x82, 0x92, 0x68,//小呀小苹果儿0xa4, 0x84, 0x94, 0x94,//怎么爱你0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,//都不嫌多,红红0x64, 0x72, 0x82, 0x94, 0x54,//的小脸儿温暖0xd2, 0xc2, 0xa4, 0xa4, 0xa2, 0x92,//我的心窝0x84, 0x92, 0xa2, 0x92, 0xa2, 0x92, 0xc2, 0xcf,//点亮我生命的火火火火火0xa4, 0x84, 0x94, 0x64,//你是我的0xa2, 0x92, 0x82, 0x92, 0x68,//小呀小苹果儿0xa4, 0x84, 0x94, 0x92, 0x92,//就像天边0xc2, 0xa2, 0x74, 0x84, 0x82, 0x72,//最美的云朵0x64, 0x72, 0x82, 0x94, 0x54,//春天又来到了0xd2, 0xc2, 0xa4, 0xa4, 0xa2, 0x92,//花开满山坡0x84, 0x92, 0xa2, 0x94, 0x52,//种下希望0x64, 0x62, 0x82, 0x68,//就会收获0x64, 0x72, 0x82, 0x94, 0x54,0xd2, 0xc2, 0xa4, 0xa4, 0xa2, 0x92,0x84, 0x92, 0xa2, 0x94, 0x52,0x64, 0x62, 0x82, 0x68,0xff};//----------------------------简谱音调对应的定时器初值---------------------------//适合11.0592M的晶振uchar code pinLvChuZi[]={0xff,0xff,//占位0xFC,0x8E,//中央C调1-70xFC,0xED,0xFD,0x43,0xFD,0x6A,0xFD,0xB3,0xFD,0xF3,0xFE,0x2D,0xFE,0x47, //高八度1-70xFE,0x76,0xFE,0xA1,0xFE,0xC7,0xFE,0xD9,0xFE,0xF9,0xFF,0x16};void delayms(uint z); //延时1MSvoid delay(uint z); //延时,十六分音符void song(void);void timer0Init(void);void main(void){timer0Init();while(1){song();delayms(1000);}}void timer0Init(void){TMOD=0x01;//定时器0工作在方式1TH0=0;TL0=0;ET0=1;EA=1;//开总中断}void song(void){uint temp;uchar yinDiao;//yinDiao是简谱i=0;while(1){temp=xiaoPingGuo[i];if(temp==0xff){ break;}yinDiao=temp/16; //取数的高4位if(yinDiao!=0){timeH=pinLvChuZi[yinDiao*2]; //取频率初值timeL=pinLvChuZi[yinDiao*2+1];}else{TR0=0;buzzer=1;//关蜂鸣器}delay(temp%16); //取数的低4位TR0=0; //唱完一个音停10MSbuzzer=1;delayms(10);TR0=1;i++;}TR0=0;buzzer=1;}void delay(uint z) //延时,十六分音符{ uint x,y;for(x=z;x>0;x--)for(y=11000;y>0;y--);}void delayms(uint z) //延时1MS{ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void timer0() interrupt 1 //产生各种音调{TH0=timeH;TL0=timeL;buzzer=~buzzer;}再附上一个可以变音调的演奏音乐的程序实验程序/*===================================================== ====== *//* ----------------------------------------------------------- *//* 曲谱存贮格式uchar code 数组名{音高,音长,音高,音长....} *//* 音高由三位数字组成:*//* 个位是表示1~7 这七个音符. *//* 十位是表示音符所在的音区,1-低音,2-中音,3-高音;*//* 百位表示这个音符是否要升半音0(不写)-不升,1-升半音。