» 您尚未 [登录 - 注册] ┆ 帮助 ┆ Archiver ┆ ┆ 
--> 标题: 发一个用蜂鸣器唱歌的程序
您是本帖第2869个阅读者。
性别:男<br>状态:离线<br>积时:1 小时 39 分 8 秒
好好学习


小学生

头衔:未定义
等级:小学生
帖数:15
金钱:185
S币:3
收藏 举报 1F 资料 | 留言 | 编辑 | 引用 | 评帖 | 主页
发一个用蜂鸣器唱歌的程序

#include <reg52.h>

#define        uchar        unsigned char

#define        uint        unsigned int

sbit        BUZZ = P1^1;

uchar        Time_H = 0;

uchar        Time_L = 0;

#define        YF_YF  160

#define        SFYF_JG 4/5// 原始频率表,低音。

uint        code         FreTab[12]=


        262,

        277,

        293,

        311,

        329,

        349,

        370,

        392,

        415,

        440,

        466,

        494

};

// 1-7.

uchar        code         XY_Tab[7]=

{0,2,4,5,7,9,11};

uint        New_FreTab[12];

uchar        YC_Tab[]=

{1,2,4,8,16,32,64};

//同一首歌

uchar code MusicSame[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,

                                  0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,

                                  0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,

                                  0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,

                                  0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,

                                  0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,

                                  0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,

                                  0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,

                                  0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,

                                  0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,

                                  0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,

                                  0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,

                                  0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,

                                  0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,

                                  0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,

                                  0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,

                                  0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,

                                  0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,

                                  0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,

                                  0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,

                                  0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,

                                  0x00,0x00 };

//两只蝴蝶                                 

uchar code MusicHappyBirthday[]={ 0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02, 0x15,0x02,

                                  0x11,0x01, 0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02,

                                  0x16,0x02, 0x15,0x01, 0x0F,0x03, 0x0F,0x03, 0x19,0x02,

                                  0x17,0x02, 0x15,0x02, 0x11,0x0C, 0x10,0x02, 0x18,0x03,

                                  0x18,0x03, 0x17,0x02, 0x15,0x02, 0x16,0x02, 0x17,0x01,

                                  0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02, 0x15,0x02,

                                  0x11,0x01, 0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02,

                                  0x16,0x02, 0x15,0x01, 0x0F,0x03, 0x0F,0x03, 0x19,0x02,

                                  0x17,0x02, 0x15,0x02, 0x11,0x0C, 0x10,0x02, 0x18,0x03,

                                  0x18,0x03, 0x17,0x02, 0x15,0x02, 0x16,0x02, 0x10,0x01,

                                  0x00,0x00 };

void Delay_10MS(void);

void        JX_New_Few_FerTab(uchar QSD,uchar SYD);

void        Play_Music(uchar        *Sound,uchar QSD,uchar SYD);

void Delay(uchar i);

void main(void)


        TMOD = 0x01;

        TH0 = 0xFF;

        TL0 = 0xFF;

        ET0 =1;

        TR0 = 0;

        EA = 1;

        while(1)

                {

Play_Music(MusicGirl,0,0);

                        Delay(200);

                        Play_Music(MusicSame,0,0);

                        Delay(200);

                        }


void Delay(uchar i)


        while(i--)

                {

                        Delay_10MS();

                }


void Time_INT() interrupt 1


        BUZZ = ~BUZZ;

        TH0 = Time_H;

        TL0 = Time_L;


// QSD 0-11        // SYD 1-3        1降8度 2不变,3升8度

void        JX_New_Few_FerTab(uchar QSD,uchar SYD)


        uchar i = 0;

        uchar j = 0;

for(i = 0 ;i <12;i++)                                // 12次循环

                {

                        j = i +QSD;                                //根据起始调判断起始音符位置

                        if(j >11)                                        //如果起始调不是最低

                                {

                                        j = j - 12;                // 0-11

                                        New_FreTab[i] = FreTab[j]*2;// 频率*2

                                }

                        else                                                                //频率不变

                                {

                                        New_FreTab[i] = FreTab[j];

                                }

                        if(SYD == 1)                                                //判断升降调。1降调,2不变,3升调。

                                {

                                        New_FreTab[i] >>= 1;//频率减一半

                                }

                        else

                                {

                                        if(SYD == 3)

                                                {

                                                        New_FreTab[i] <<= 1;

                                                }

                                }

                }


void        Play_Music(uchar        *Sound,uchar QSD,uchar SYD)


        uint        GQ_CD = 0;                                        //歌曲长度

        uint        GQ_WZ = 0;

        uchar GQ_YG = 0;

        uchar GQ_YC = 0;

        uint                YP_PL = 0;

        uchar        YG_Bai = 0;

        uchar        YG_Shi = 0;

        uchar         YG_Ge = 0;

        uchar        YC_Bai = 0;

        uchar        YC_Shi = 0;

        uchar         YC_Ge = 0;

        uint                DSD_PL = 0;

        uint                YF0 = 0;        // 1分音符变量

        uint                YF1 = 0; // 发音长度时间

        uint                YF2 = 0;        //不发音长度时间

        uint                YF4 = 0;        // 4分音符时间

        uint                FY_JG = 0;

        uint                YZ_TC = 0;

        uint                JF_YF = 0;

        uchar i =0;

       

         JX_New_Few_FerTab( QSD,  SYD);

         while(Sound[GQ_CD] != 0)                        //判断歌曲长度

                {

                        GQ_CD += 2;                                //指向下一位音符数据

                }

while(GQ_WZ < GQ_CD)

                {

                        GQ_YG = Sound[GQ_WZ];

                        YG_Bai = GQ_YG/100;                // 1升半音,0不升

                        YG_Shi = GQ_YG/10%10;        // 1低音,2为中音,3为高音

                        YG_Ge = GQ_YG%10;                // 1-7 音符位;

                        YP_PL = New_FreTab[XY_Tab[YG_Ge -1] + YG_Bai];// yg_ge -1 1-7 0-6

                        if(YG_Ge != 0)

                                {

                                        switch(YG_Shi)

                                                {

                                                        case 2: YP_PL <<=1;break;

                                                        case 3: YP_PL <<=2;break;

                                                }

                                        DSD_PL = 65536-(50000/YP_PL)*10;

                                        Time_H = DSD_PL >>8;

                                        Time_L = DSD_PL & 0x00FF;

                                        TH0 = Time_H;

                                        TL0 = Time_L;

                                }

GQ_YC = Sound[GQ_WZ +1];

                        YC_Bai = GQ_YC/100;                // 1有符点,0无符点

                        YC_Shi = GQ_YC/10%10;        // 演奏效果0普通,1连音,2顿音

                        YC_Ge = GQ_YC%10;                // 几分音符。

                        YF0 = YF_YF;

                        YF4 = YF0 /4;

                        FY_JG =YF4- YF4 *SFYF_JG;

                        JF_YF = YC_Tab[YC_Ge];// 几分音符;

                        YZ_TC = YF0 /JF_YF;          // 算出对应延时长度多少个10MS

                       

                        if(YC_Bai == 1)                 //判断是否有符点

                                {

                                        YZ_TC = YZ_TC+YZ_TC/2;//有符点

                                }

                        if(YC_Shi != 1)                        //不是连音

                                {

                                        if(YC_Shi == 0)        //是否为普通音

                                                {

                                                        if(JF_YF <= 4)        // 是否小于16分音

                                                                {

                                                                        YF1 = YZ_TC -FY_JG;        // 发音有间隔

                                                                }

                                                        else                        // 不小于16分音

                                                                {

                                                                        YF1 = YZ_TC * SFYF_JG;//发音无音隔

                                                                }

                                                }

                                        else                                        //是顿音,演奏时间为原来的一半

                                                {

                                                        YF1 = YZ_TC /2;

                                                }

                                }

                        else                                                        //是连音,发音无音隔

                                {

                                        YF1 = YZ_TC;

                                }

                        if(YG_Ge == 0)                                //没有音符数据

                                {

                                        YF1 = 0;                                //演奏时间 = 0

                                }

                        else                                                        //有音符数据

                                {

                                        YF2 = YZ_TC - YF1;

                                        TR0 =1;

                                        for(i = YF1; i >0;i --)

                                                {

                                                        Delay_10MS();

                                                }

                                        BUZZ = 1;

                                        TR0 = 0;

                                        for(i = YF2; i >0;i --)

                                                {

                                                        Delay_10MS();

                                                }                                       

                                }

                        GQ_WZ += 2;                                        //指向下一个音符       

                       

                }

//延时函数 10MS。

void Delay_10MS(void)


        uchar a = 0;

        uchar b = 0;

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

                {

                        for(b = 300;b>0;b--);

                }

本帖评分记录
  • 奖!感谢无私贡献     金钱:10     aj8714523    2011-05-17 15:30:33






  • ----签名档 --------------------------------------------------------
    好好学习,天天向上!

    Posted:2011-05-17 15:25:59
    性别:男<br>状态:离线<br>积时:1 小时 39 分 8 秒
    好好学习


    小学生

    头衔:未定义
    等级:小学生
    帖数:15
    金钱:185
    S币:3
    2F 资料 | 留言 | 编辑 | 引用 | 评帖 | 主页


    有点长啊,哈!






    ----签名档 --------------------------------------------------------
    好好学习,天天向上!

    Posted:2011-05-17 15:26:33
    ×
    性别:男<br>状态:离线<br>积时:10 个月 0 天 2 小时 24 分 46 秒
    aj8714523


    管理员

    头衔:眼镜蛇管理员
    等级:管理员
    帖数:1402
    金钱:1017
    S币:74

    3F 资料 | 留言 | 编辑 | 引用 | 评帖 | 主页


    虽然有点长,但是是一篇不错的帖子!






    ----签名档 --------------------------------------------------------
    世界上比毒品更容易成瘾的,是装逼时的感觉。。。。

    Posted:2011-05-17 15:31:37
    ×
     每页10条,共1页,合计3条记录
    9  1  :
    转到  


    Powered By:Discuz! 6.0 Processed in:0.109375s,22 queries.
    眼镜蛇论坛|单片机论坛| 技术支持:【QQ】1522066584

    免 责 声 明 本站提供网上自由讨论使用,所有个人言论并不代表本站立场,与本站立场无关,本站不会对其內容负上任何责任。
    假若內容有涉及侵权,请立即联络我们。我们将立刻从网站上刪除,并向所有持版权者致最深的歉意。