基于51单片机Proteus仿真的音乐播放器和函数发生器

发布时间:2023-01-30  

音乐播放器:

实际运行效果:

51单片机Proteus仿真音乐播放器

音乐播放器原理图

音乐播放器代码链接:https://pan.baidu.com/s/1Yrjb2BtYoAcUZDdtUpbyMw

提取码:vhth

代码:

#include

#include


typedef unsigned char uchar;

typedef unsigned int  uint;


sbit K1   = P3^2;

sbit Beep = P3^7;

uchar i;


uchar song_Index,Tone_Index=0;

uchar * song_Tone, *song_Time;


const LED_tab[] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,

                    0x82,0xF8,0x80,0x90,0x88,0x83,

                    0xC6,0xA1,0x86,0x81,0xBF,0xFF };


const Tone_tab[] = { 62018,62401,62491,62895,63184,63441,63506,

                    63773,63965,64137,64215,64360,64488,64603,

                    64654,64751,64836,64876,64948,65012,65067,65535};

/* 《送别》 */

uchar code song1_Tone[] = { 11,9,11,14,12,14,12,11,11,7,8,9,8,7,8,

                            11,9,11,14,13,12,14,11,11,7,8,9,6,7,

                            12,14,14,13,12,13,14,12,13,14,12,12,11,10,7,8,

                            11,9,11,14,13,12,14,11,11,8,9,10,6,7,0xff};

uchar code song1_Time[] = { 4,2,2,8,4,2,2,8,4,2,2,4,2,2,12,

                            4,2,2,4,2,4,4,8,4,2,2,4,2,12,

                            4,4,8,4,2,2,8,2,2,2,2,2,2,2,2,16,

                            4,2,2,4,2,4,4,8,4,2,2,4,2,12,0xff};


/* 《两只老虎》 */

uchar code song2_Tone[] = { 7,8,9,7,7,8,9,7,9,10,11,9,10,11,

                            11,12,11,10,9,7,11,12,11,10,9,7,7,4,7,7,4,7,0xff};

uchar code song2_Time[] = { 4,4,4,4,4,4,4,4,4,4,8,4,4,8,

                            2,2,2,2,2,2,2,2,2,2,4,4,4,4,8,4,4,8,0xff};


/* 《哈巴狗》 */

uchar code song3_Tone[] = { 7,7,7,8,9,9,9,9,10,11,12,12,11,10,9,11,11,8,9,7,

                            7,7,7,8,11,9,9,9,10,11,12,12,11,10,9,11,8,9,7,0xff};

uchar code song3_Time[] = { 2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,

                            2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,0xff};


/* 《兰花草》 */

uchar code song4_Tone[] = { 5,9,9,9,9,8,7,8,7,6,5,12,12,12,12,12,11,

                            2,11,11,10,9,9,12,12,11,9,8,7,8,7,6,5,9,

                            2,7,7,6,5,9,8,7,6,4,6,0xff};

uchar code song4_Time[] = { 2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,4,2,

                            2,2,2,8,2,2,2,2,4,2,2,2,2,2,4,2,

                            2,2,2,2,4,2,2,2,2,2,8,0xff};


/* 《不倒翁》 */

uchar code song5_Tone[] = { 11,12,11,9,8,9,11,9,8,7,9,11,7,9,8,

                            11,12,11,9,8,9,11,9,8,7,8,7,8,9,7,0xff};

uchar code song5_Time[] = { 4,4,8,4,4,8,4,4,4,4,2,2,2,2,8,

                            4,4,8,4,4,8,4,4,4,4,2,2,2,2,8,0xff};


void delayms( uint ms )

{

    uchar a;

    while (ms--)

    {

        for (a=230; a>0; a--);

    }   

}


void int0() interrupt 0

{

   delayms(100);

   if (INT0==0)

   {

       TR0 = 0;

       song_Index++;

   }

   if (song_Index==1)

   {

       song_Tone = song2_Tone;

       song_Time = song2_Time;

   }


    if (song_Index==2)

   {

       song_Tone = song3_Tone;

       song_Time = song3_Time;

   }

   

    if (song_Index==3)

   {

       song_Tone = song4_Tone;

       song_Time = song4_Time;

   }


    if (song_Index==4)

   {

       song_Tone = song5_Tone;

       song_Time = song5_Time;

   }


      if (song_Index==5)

   {

       song_Tone = song1_Tone;

       song_Time = song1_Time;

   }

    

}


void Timer0() interrupt 1

{

    TH0 = Tone_tab[Tone_Index]/256;

    TL0 = Tone_tab[Tone_Index]%256;

    Beep = ~Beep;

}


void display( void )

{

    P0 = LED_tab[song_Index];

}


void Init( void )

{

    TMOD = 0x01;

    ET0  = 1;

    EX0  = 1;

    IT0  = 1;

    EA   = 1;

    TR0  = 0;

}

void main()

{

    Init();

    song_Tone = song1_Tone;

    song_Time = song1_Time;


    while (1)

    {

        display();

        Tone_Index = song_Tone[i];

        if (Tone_Index==0xFF)

        {

            i = 0;

            TR0 = 0;

        }

        TR0 = 1;

        delayms(song_Time[Tone_Index]+100);

        TR0 = 0;

        i++;

    }

    

}

代码及原理解释:

人耳在空气中能听得到声音是因为声源带动空气震动,达到人耳所能听到的范围(20~20Khz);当然通过其它介质也是可以传播的,这里就不做讨论了。

那么,要想产生声音,只要震动推动空气达到人耳听到的范围即可,常用的扬声器就是典型的转换设备,这里整个代码的核心思想是使用51单片机的定时器0中断产生音乐的音调,然后加上每个音调的发声长短就可以组成一首完整的音乐。

为了切换不同的音乐,我们可以事先对不同音乐的音调和实际演奏程中的音调发声时长进行编码。

音调和每个音符延时数组编码

定时器0中断,用于产生音调

每个音调延时长短处理部分

函数发生器:

实际运行效果:

51单片机Proteus函数发生器仿真

函数发生器原理图

函数发生器代码链接:https://pan.baidu.com/s/1izoD5KOfXFZP2sgXjLin0g

提取码:1lbq

函数发生器代码:

#include


sbit UPKEY = P3^3;

sbit DOWNKEY = P3^4;

sbit SHKEY = P3^5;

sbit FOUT = P3^2;


unsigned char fun = 0;

unsigned char th0_reg,tl0_reg;


void delay_ms( unsigned int dt );


void main()

{

    unsigned int f = 500;

    TMOD = 0x01;

    th0_reg = (unsigned int)(65539.0-(19531.25/f))>>8;

    tl0_reg = (unsigned int)(65539.0-(19531.25/f))&0x00ff;


    TH0 = th0_reg;

    TL0 = tl0_reg;

    TR0 = 1;

    IE = 0x82;

    P3 = 0xff;


    while (1)

    {

        if((UPKEY==0)&&(f<1000))

        {

            f += (f/10)?(f/10):1;

            th0_reg = (unsigned int)(65539.0-(19531.25/f))>>8;

            tl0_reg = (unsigned int)(65539.0-(19531.25/f))&0x00ff;

            delay_ms(100);

        }


        if((DOWNKEY==0)&&(f>1))

        {

            f -= (f/10)?(f/10):1;

            th0_reg = (unsigned int)(65539.0-(19531.25/f))>>8;

            tl0_reg = (unsigned int)(65539.0-(19531.25/f))&0x00ff;

            delay_ms(100);

        }


        if(SHKEY==0)

        {

            fun = !fun;

            delay_ms(100);

        }

    }

    

}


void delay_ms( unsigned int dt )

{

    register unsigned char bt,ct;

    for(;dt;dt--)

        for(ct=2; ct; ct--)

            for(bt=248; --bt;);

}


void intt0(void) interrupt 1

{

    unsigned char code sin_table[]={

    0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,4,4,5,5,6,6,6,7,8,8,9,9,

    10,10,11,12,12,13,14,14,15,16,17,17,18,19,20,21,22,23,23,24,25,

    26,27,28,29,30,31,32,33,34,35,37,38,39,40,41,42,43,45,46,47,48,

    49,51,52,53,54,56,57,58,60,61,62,64,65,66,68,69,71,72,73,75,76,

    78,79,81,82,84,85,87,88,90,91,93,94,96,97,99,100,102,103,105,106,

    108,109,111,113,114,116,117,119,120,122,124,125,127,128,130,131,

    133,135,136,138,139,141,142,144,146,147,149,150,152,153,155,156,

    158,159,161,162,164,165,167,168,170,171,173,174,176,177,179,180,

    182,183,184,186,187,189,190,191,193,194,195,197,198,199,201,202,

    203,204,206,207,208,209,210,212,213,214,215,216,217,218,220,221,

    222,223,224,225,226,227,228,229,230,231,232,232,233,234,235,236,

    237,238,238,239,240,241,241,242,243,243,244,245,245,246,246,247,

    247,248,249,249,249,250,250,251,251,252,252,252,253,253,253,253,

    254,254,254,254,254,255,255,255,255,255,255,255,255

    };


    static unsigned char wave_index = 0;

    static bit index_sign = 1;

    TH0 = th0_reg;

    TL0 = tl0_reg;

    if(fun){ P2 = sin_table[wave_index]; }

    else   { P2 = wave_index; }


    FOUT = !FOUT;

    if (index_sign==1){ if(++wave_index==255) index_sign = 0; }

    else              { if(--wave_index==0)   index_sign = 1; }


}

代码及原理解释:

整个代码的核心部分是使用定时器0中断来完成的

其中方波产生部分相对比较简单,直接通过改变定时器的延时长度来控制P3.2引脚的方波产生。

方波引脚定义

方波产生引脚

三角波和正弦波发生部分使用DAC0832来产生,通过给P2端口加载不同数值,从而产生不同电压。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>