简易的单片机音乐控制.docx

上传人:b****4 文档编号:4156352 上传时间:2022-11-28 格式:DOCX 页数:11 大小:55.90KB
下载 相关 举报
简易的单片机音乐控制.docx_第1页
第1页 / 共11页
简易的单片机音乐控制.docx_第2页
第2页 / 共11页
简易的单片机音乐控制.docx_第3页
第3页 / 共11页
简易的单片机音乐控制.docx_第4页
第4页 / 共11页
简易的单片机音乐控制.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

简易的单片机音乐控制.docx

《简易的单片机音乐控制.docx》由会员分享,可在线阅读,更多相关《简易的单片机音乐控制.docx(11页珍藏版)》请在冰豆网上搜索。

简易的单片机音乐控制.docx

简易的单片机音乐控制

简易的单片机音乐控制

                  作者:

侯静

  针对以前转贴的那篇单片机音乐控制,其算法对初学者不是很容易弄懂

此,我根据网上提供的资料。

用C语言写了一个《八月桂花香》的音乐控制。

    音调是由不同的频率产生的,而每一个音调都是由一个音符和一个节拍组成,音符决定该音调的高低,节拍则决定了该音调是多少拍。

因此,一个音调是由两个字节组成的。

根据音符字节产生该大小次数的延时,声音输出口取反,就可以得到该音调的高低音。

根据设置单位节拍的延时大小,可以控制音乐演唱速度。

    因此算法很简单:

定义单片机的一个I/O端脚为声音输出口,在规定的节拍内,根据音符字节的大小产生延时,将声音输出口不断的置高置低(即取反),就可以得到该音调。

只要选取合适的单位节拍延时,就可以输出动听的音乐。

 

算法流程图如下:

 

 

//**********主程序*********

#include

#include"SoundPlay.h"

uchardatacount=0;

voidinit_com()

{

 TMOD=0x01;

 TH0=0xff;

 TL0=0xff;

 EA=1;

 ET0=1;

}

        

voidtimer0(void)interrupt1using3

{

 counter=counter+1;//节拍次数计数 

 TH0=0xd8;//定义单位节拍的延时大小 

 TL0=0xef;

}

voiddelay(ucharn)

{

 uchari;

 while(n--)

  for(i=0;i<125;i++);//延时1毫秒

}

voidsound_delay(ucharn)

{

 uchari;

 while(n--)

 {

  for(i=0;i<2;i++);

 }

}

voidmain()

{

 uinti;

 ucharsound_signal;//定义音符大小 

 ucharsound_pace;//定义节拍大小 

 init_com()

 

 //array[i]=0x00代表歌曲演唱完毕

 //array[i]=0xff代表是休止符

 while

(1)

 {

 i=0;

 while(array[i]!

=0x00)

 {

 //如果是休止符,延时100ms,并终止本次循环,进入下一个循环

  if(array[i]==0xff)

  {

    TR0=0;

    i++;

    delay(100);

    continue;

   }

  //从表中取得音符大小

 sound_signal=array[i];

  i=i+1;

  //从表中取得节拍大小

 sound_pace=array[i];

  TR0=1;

 //当节拍数未达到时候,继续循环,产生该音调的声音

 while(counter!

=sound_pace)

 {

    sound=~sound;

    sound_delay(sound_signal);

 }

   i++;

  counter=0;//节拍计数器置0,进入下一个音调

 }

 delay(10);//歌曲演唱完毕后,延时一段时间

 } 

}

 

 

//*******soundplay.h**********

#ifndef__SOUNDPLAY_H_REVISION_FIRST__

#define__SOUNDPLAY_H_REVISION_FIRST__

#defineucharunsignedchar

#defineuintunsignedint

sbitsound=P1^2;

uintcounter=0;

ucharcodearray[]=

{

             0x18,0x30,0x1C,0x10,

             0x20,0x40,0x1C,0x10,

             0x18,0x10,0x20,0x10,

             0x1C,0x10,0x18,0x40,

             0x1C,0x20,0x20,0x20,

             0x1C,0x20,0x18,0x20,

             0x20,0x80,0xFF,0x20,

             0x30,0x1C,0x10,0x18,

             0x20,0x15,0x20,0x1C,

             0x20,0x20,0x20,0x26,

             0x40,0x20,0x20,0x2B,

             0x20,0x26,0x20,0x20,

             0x20,0x30,0x80,0xFF,

             0x20,0x20,0x1C,0x10,

             0x18,0x10,0x20,0x20,

             0x26,0x20,0x2B,0x20,

             0x30,0x20,0x2B,0x40,

             0x20,0x20,0x1C,0x10,

             0x18,0x10,0x20,0x20,

             0x26,0x20,0x2B,0x20,

             0x30,0x20,0x2B,0x40,

             0x20,0x30,0x1C,0x10,

             0x18,0x20,0x15,0x20,

             0x1C,0x20,0x20,0x20,

             0x26,0x40,0x20,0x20,

             0x2B,0x20,0x26,0x20,

             0x20,0x20,0x30,0x80,

             0x20,0x30,0x1C,0x10,

             0x20,0x10,0x1C,0x10,

             0x20,0x20,0x26,0x20,

             0x2B,0x20,0x30,0x20,

             0x2B,0x40,0x20,0x15,

             0x1F,0x05,0x20,0x10,

             0x1C,0x10,0x20,0x20,

             0x26,0x20,0x2B,0x20,

             0x30,0x20,0x2B,0x40,

             0x20,0x30,0x1C,0x10,

             0x18,0x20,0x15,0x20,

             0x1C,0x20,0x20,0x20,

             0x26,0x40,0x20,0x20,

             0x2B,0x20,0x26,0x20,

             0x20,0x20,0x30,0x30,

             0x20,0x30,0x1C,0x10,

             0x18,0x40,0x1C,0x20,

             0x20,0x20,0x26,0x40,

             0x13,0x60,0x18,0x20,

             0x15,0x40,0x13,0x40,

             0x18,0x80,0x00

};

#endif

用单片机控制蜂鸣器放音乐

悬赏分:

0-解决时间:

2008-11-2514:

44

下面的程序怎么理解,数组是怎么得到的

#include"reg51.h"

unsignedcharCount;

sbitFMQ=P3^5;//蜂鸣器控制脚

unsignedcharcodeSONG[]={

0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,

0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,

0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,

0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,

0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,

0x39,0x10,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,

0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,0x20,0x30,0x10,

0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,

0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,

0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,

0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x1c,0x20,

0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,

0x10,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,

0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,

0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,

0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,

0x20,0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,

0x10,0x40,0x10,0x20,0x10,

0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,};

voidTime0_Init()//定时器0初始化函数

{

TMOD=0x01;//工作模式选择

IE=0x82;//中断设置

TH0=0xD8;//装初值

TL0=0xEF;//12MZ晶振,10ms

}

voidTime0_Int()interrupt1//定时器0中断子函数

{

TH0=0xD8;

TL0=0xEF;

Count++;//长度加1

}

voidPlay_Song(unsignedchari)

{

unsignedcharTemp1,Temp2;

unsignedintAddr;

Count=0;//中断计数器清0

Addr=i*217;

while

(1)

{

Temp1=SONG[Addr++];

if(Temp1==0xFF)//休止符

{

TR0=0;

Delay_xMs(100);

}

elseif(Temp1==0x00)//歌曲结束符

{

return;

}

else

{

Temp2=SONG[Addr++];

TR0=1;

while

(1)

{

FMQ=~FMQ;

Delay_xMs(Temp1);

if(Temp2==Count)

{

Count=0;

break;

}

}

}

}

}

问题补充:

谢谢你,我已经自己编出来了,恩,你说的问题确实是延时定义有问题。

提问者:

guduyishuai-二级

最佳答案

看起来数组应该是音乐数据,其中包括四种数据,就是休止符(每个100毫秒)、歌曲结束符、音阶(给出的是蜂鸣器的震荡周期)、一个音阶持续的时间长度。

如果你的晶振是12MHz,按照定时器中断给Count加一来看,音阶持续的时间应该是以10毫秒为单位。

Play_Song函数要求给出参数i,我的看法是这个i是指要播放第几段乐曲,i*217表示每段乐曲都是217个字节。

本例中,数组只给出217个字节,所以只有一段乐曲,播放时需要给出参数i=0.

if(Temp1==0xFF)//休止符

{

TR0=0;

Delay_xMs(100);

}

所以休止符每个固定是100毫秒。

如果读到第一个不是休止符或者结束符的字节,那就是音阶,而下一个字节就是这个音阶的长度或者说节拍

while

(1)

{

FMQ=~FMQ;

Delay_xMs(Temp1);

if(Temp2==Count)

{

Count=0;

break;

}

}

这一段是说,如果当前音阶的时间(Temp2次定时器中断,由Count计时)还没完,就每隔Temp1毫秒震动一次蜂鸣器,就形成一个震动频率,这段时间就发出一定音调的乐音。

不过我也有疑惑,震荡周期如果以毫秒为单位恐怕只能发出次声波,所以以上对有关Delay_xMs函数时间的估算都可能有问题,还得看Delay_xMs函数的具体定义才行。

一个简单的单片机音乐播放程序

电子工程师之路2010-04-2017:

59:

56阅读8评论0字号:

大中小

#include       //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

sbit     speaker=P1^2; //定义音乐输出端口,需要连接到对应的喇叭

unsignedchartimer0h,timer0l,time;

                        //《挥剑问情》数据表

codeunsignedcharhjwq[]={       3,2,2,     3,2,1,     2,2,1,3,2,2,3,2,1,2,2,1,3,2,1,

                                                   6,2,1,     5,2,1,     3,2,1,2,2,2,1,2,1,2,2,1,3,2,2,

                                                    3,2,1,     2,2,1,     3,2,2,3,2,1,2,2,1,3,2,1,1,3,1,

                                                    6,2,1,     5,2,1,     3,2,2,3,2,1,3,2,1,5,2,1,6,2,2,

                                                    6,2,1,     1,3,1,     6,2,2,5,2,1,3,2,1,2,2,5,1,2,1,

                                                    2,2,1,     3,2,2,     3,2,1,5,2,1,3,2,2,3,2,1,1,2,1,

                                                    2,2,5,     3,2,1,     2,2,1,3,2,2,3,2,1,2,2,1,3,2,2,

                                                    3,2,1,     2,2,1,     3,2,1,6,2,1,5,2,1,3,2,1,2,2,2,

                                                    3,2,1,     5,2,1,     6,2,3,1,3,1,6,2,3,1,3,1,5,2,1,

                                                    6,2,1,     1,3,1,     7,2,1,6,2,1,5,2,1,3,2,1,5,2,1,

                                                    6,2,5,     3,2,1,     5,2,1,6,2,5,3,2,1,5,2,1,6,2,1,

                                                    1,3,1,     6,2,5,     5,2,4,3,2,2,5,2,2,6,2,3,1,3,1,

                                                     5,2,2,     3,2,2,     2,2,4,5,2,2,2,2,2,3,2,3,6,2,1,

                                                    5,2,2,     2,2,2,     3,2,4,2,2,2,3,2,1,2,2,1,1,2,6,

                                                     2,2,1,     1,2,1,     6,1,2,1,2,2,2,2,2,3,2,2,5,2,2,

                                                     6,2,2,     3,2,3,     1,2,1,2,2,4,3,2,2,5,2,2,6,2,3,

                                                    1,3,1,     5,2,2,     3,2,2,2,2,4,5,2,2,2,2,2,3,2,3,

          6,2,1,     5,2,2,     3,2,2,5,2,4,6,2,2,1,3,2,2,3,4,

          6,2,4,     5,2,4,     6,2,4,1,3,2,3,3,2,2,3,2,1,3,2,

          5,2,2,     6,2,10

          

                                     };

                        //音阶频率表高八位

codeunsignedcharFREQH[]={

                               0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

                               0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC,//1,2,3,4,5,6,7,8,i

                               0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

                               0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,

                              };

                        //音阶频率表低八位

codeunsignedcharFREQL[]={

                                0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,

                                0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,//1,2,3,4,5,6,7,8,i

                                0xEE,0x44,0x6B,0xB4,0xF4,0x2D,

                                0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,

                               };

/******************************************************************/

/*                   延时函数                                   */

/******************************************************************/

voiddelay(unsignedchart)

  {

  unsignedchart1;

  unsignedlongt2;

  for(t1=0;t1

  {

   for(t2=0;t2<8000;t2++)

      {

       ;

       }

  }

  TR0=0;

 }

/******************************************************************/

/*                   定时器中断函数                             */

/*****************************

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

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1