查看: 867|回复: 1

[项目] 步进电机播放音乐

[复制链接]
  • TA的每日心情
    擦汗
    2019-8-24 17:30
  • 签到天数: 315 天

    [LV.8]以坛为家I

    发表于 2019-3-7 11:33 | 显示全部楼层 |阅读模式
    硬件:使用arduino uno板子与步进电机驱动器TB6600实物图
    2.png
    因为我这里用的是方波,才用步进电机振动与地座产生共振来达到播放音乐的效果,所以这里板子接线只需要将13口与驱动器的脉冲口相接,方向使能可以不接,其它可以用共阴或者共阳。
    接线.png
    播放音乐,首先得知道do,re,mi,fa,suo,la,xi等这些对应的频率,这里就需要用的示波器,将脉冲线接到示波器,通过调整方波频率来找到这些频率,记下来。

    kittenblock中小学创客名师推荐的图形化编程软件

    比如char  music_freq_tab[64]={             //音符定时器值表
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/131/256,     //256-FREQ/24/x/256    //1 do 高字节
        256-FREQ/24/131%256,     //256-FREQ/24/x%256    //1 do 低字节
        255-FREQ/24/147/256,256-FREQ/24/147%256,        //2 re
        255-FREQ/24/165/256,256-FREQ/24/165%256,        //3 mi
        255-FREQ/24/175/256,256-FREQ/24/175%256,        //4 fa
        255-FREQ/24/196/256,256-FREQ/24/196%256,        //5 suo
        255-FREQ/24/221/256,256-FREQ/24/221%256,        //6 la
        255-FREQ/24/248/256,256-FREQ/24/248%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/262/256,256-FREQ/24/262%256,        //1 do
        255-FREQ/24/294/256,256-FREQ/24/294%256,        //2 re
        255-FREQ/24/330/256,256-FREQ/24/330%256,        //3 mi
        255-FREQ/24/350/256,256-FREQ/24/350%256,        //4 fa
        255-FREQ/24/393/256,256-FREQ/24/393%256,        //5 suo
        255-FREQ/24/441/256,256-FREQ/24/441%256,        //6 la
        255-FREQ/24/495/256,256-FREQ/24/495%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/525/256,256-FREQ/24/525%256,        //1 do
        255-FREQ/24/589/256,256-FREQ/24/589%256,        //2 re
        255-FREQ/24/661/256,256-FREQ/24/661%256,        //3 mi
        255-FREQ/24/700/256,256-FREQ/24/700%256,        //4 fa
        255-FREQ/24/786/256,256-FREQ/24/786%256,        //5 suo
        255-FREQ/24/882/256,256-FREQ/24/882%256,        //6 la
        255-FREQ/24/990/256,256-FREQ/24/990%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/1049/256,256-FREQ/24/1049%256,      //1 do
        255-FREQ/24/1178/256,256-FREQ/24/1178%256,      //2 re
        255-FREQ/24/1322/256,256-FREQ/24/1322%256,      //3 mi
        255-FREQ/24/1400/256,256-FREQ/24/1400%256,      //4 fa
        255-FREQ/24/1572/256,256-FREQ/24/1572%256,      //5 suo
        255-FREQ/24/1665/256,256-FREQ/24/1665%256,      //6 la
        255-FREQ/24/1869/256,256-FREQ/24/1869%256,      //7 xi

    };还有很多,这里就不一一叙说了,原理很简单,有示波器就可以了,具体请看我上传的源代码。
    有了上述这些东西之后,还需要了解arduino的定时器,我这里用的UNO板,我都板子晶振频率是16M,所以TCNT1=0Xffff - 定时时间/(分频数* (1/晶振频率)),分频数是调整计数的,越大计数越慢,一般有1、8、64、256、1024分频。定时器初始化与中断代码如下:

    kittenblock中小学创客名师推荐的图形化编程软件

    void DEVICE_INIT(void){
    cli();
    TCCR1A=0;
    TCCR1B=(1<<CS12)|(1<<CS10);
    TCNT1=344;
    TIMSK1=(1<<TOIE1);
    DDRB|=(1<<DDB5);
    PORTB|=(0<<PORTB5);
    sei();
    }
    
    ISR(TIMER1_OVF_vect)
    {
    TCNT1=65535-((ly_TH0*256+ly_TL0)/1000000)/(1024*(1/16000000));
    PORTB=(~PORTB)&(1<<PORTB5);
    }
    上述东西大家都解决后,就可以播放音乐了,播放音乐的代码如下:(大家也可以根据自己喜欢的调子来改编)
    void music_play( char *pmsc)   //音乐
    {
        char music_freq=32;      //音高 
         char music_long;         //节拍延时
         char music_data=0;       //音符数据
        char music_up=0;                   //升半音
        char music_break=0;                //断奏
        ly_TH0=0xff;
        ly_TL0=0xea;                 
    sei();
        while (*pmsc != 0x00)
            {
            music_data=*pmsc & 0x07;
            music_long=*pmsc>>4;
            //---------------------------------------------------------
            if (music_long != 0){          //是音符,非功能码
                if (*pmsc&0x80){           //需升降调
                    if (((*pmsc) & 0x08) == 0)
                        {if(music_freq >= 16) music_freq -= 16;}   //音高下降 
                    else
                        {if(music_freq < 48) music_freq += 16;}    //音高上升
                 }
                //---------------------------------------------------------
                if (music_up==1){          //升半音
                    ly_TH0=music_frequp_tab[(music_freq  + (music_data <<1))];
                    ly_TL0=music_frequp_tab[(music_freq + (music_data <<1)+1)];
                }
                else{                      //不升半音
                    ly_TH0=music_freq_tab[(music_freq + (music_data <<1))];
                    ly_TL0=music_freq_tab[(music_freq + (music_data <<1)+ 1)];
                }
                if (music_break){          //断奏
                    music_delay(music_l_tab[music_long&0x07]-1);
                    ly_TH0=0xff;
                    ly_TL0=0xea;
                    music_delay(1);
                }
                else                      //连奏
                    music_delay(music_l_tab[music_long&0x07]);
            }
            else                          //是功能码
                {
                switch(music_data){
                case 0x04:
                  music_up=0; break;      //不升半音                    
                case 0x05:
                  music_up=1; break;      //升半音                    
                case 0x06:
                music_break=0; break;   //断奏                    
            case 0x07:
                music_break=1;break;    //连奏                    
                }
            }
            pmsc++;
        }
      cli();            //播放结束,关中断
    }


    播放效果视频如下:





    全部代码如下:

    kittenblock中小学创客名师推荐的图形化编程软件

    #include <interrupt.h>
    #include <iom328p.h>
    #define  FREQ 16000000
    char music1[]={    
        0xcb,                       //示例:0xcb=11001011B,升半调/1/4拍,3Mi低音
        0x35,0x16,0xb9,0x12,0x96,0x99,0xa5,
        0xbd,0x99,0x96,0x15,0x13,0x15,0x62,
        0x32,0x13,0xa7,0x26,0x25,0x16,0xa9,0x22,
        0xa3,0xa9,0x96,0x15,0x16,0x99,0xe5,
        0xbb,0x15,0xa7,0xaa,0x96,0x99,0xd5,
        0x13,0x15,0x23,0x15,0x16,0x17,0x9a,0xd6,0x15,0x16,
        0xb9,0x12,0x25,0x23,0x23,0x22,0x13,0x12,0x21,0x96,0x15,
        0x43,0xc9,0x96,0x99,0x96,0x15,0x13,0x15,0x16,0x99,
        0xd5,                            
        0x00,                        //最后字节为功能码必须==0x00退出
    };
    char music_l_tab[8]={0,1,2,3,4,6,8,16};//音乐节拍
    char  music_freq_tab[64]={             //音符定时器值表
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/131/256,     //256-FREQ/24/x/256    //1 do 高字节
        256-FREQ/24/131%256,     //256-FREQ/24/x%256    //1 do 低字节
        255-FREQ/24/147/256,256-FREQ/24/147%256,        //2 re
        255-FREQ/24/165/256,256-FREQ/24/165%256,        //3 mi
        255-FREQ/24/175/256,256-FREQ/24/175%256,        //4 fa
        255-FREQ/24/196/256,256-FREQ/24/196%256,        //5 suo
        255-FREQ/24/221/256,256-FREQ/24/221%256,        //6 la
        255-FREQ/24/248/256,256-FREQ/24/248%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/262/256,256-FREQ/24/262%256,        //1 do
        255-FREQ/24/294/256,256-FREQ/24/294%256,        //2 re
        255-FREQ/24/330/256,256-FREQ/24/330%256,        //3 mi
        255-FREQ/24/350/256,256-FREQ/24/350%256,        //4 fa
        255-FREQ/24/393/256,256-FREQ/24/393%256,        //5 suo
        255-FREQ/24/441/256,256-FREQ/24/441%256,        //6 la
        255-FREQ/24/495/256,256-FREQ/24/495%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/525/256,256-FREQ/24/525%256,        //1 do
        255-FREQ/24/589/256,256-FREQ/24/589%256,        //2 re
        255-FREQ/24/661/256,256-FREQ/24/661%256,        //3 mi
        255-FREQ/24/700/256,256-FREQ/24/700%256,        //4 fa
        255-FREQ/24/786/256,256-FREQ/24/786%256,        //5 suo
        255-FREQ/24/882/256,256-FREQ/24/882%256,        //6 la
        255-FREQ/24/990/256,256-FREQ/24/990%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/1049/256,256-FREQ/24/1049%256,      //1 do
        255-FREQ/24/1178/256,256-FREQ/24/1178%256,      //2 re
        255-FREQ/24/1322/256,256-FREQ/24/1322%256,      //3 mi
        255-FREQ/24/1400/256,256-FREQ/24/1400%256,      //4 fa
        255-FREQ/24/1572/256,256-FREQ/24/1572%256,      //5 suo
        255-FREQ/24/1665/256,256-FREQ/24/1665%256,      //6 la
        255-FREQ/24/1869/256,256-FREQ/24/1869%256,      //7 xi
    };
     char  music_frequp_tab[64]={           //升半音
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/139/256,        //1 do 高字节 //255-FREQ/24/x/256
        256-FREQ/24/139%256,        //1 do 低字节 //256-FREQ/24/x%256
        255-FREQ/24/156/256,256-FREQ/24/156%256,        //2 re
        255-FREQ/24/175/256,256-FREQ/24/175%256,        //3 mi
        255-FREQ/24/185/256,256-FREQ/24/185%256,        //4 fa
        255-FREQ/24/208/256,256-FREQ/24/208%256,        //5 suo
        255-FREQ/24/234/256,256-FREQ/24/234%256,        //6 la
        255-FREQ/24/262/256,256-FREQ/24/262%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/278/256,256-FREQ/24/278%256,        //1 do
        255-FREQ/24/312/256,256-FREQ/24/312%256,        //2 re
        255-FREQ/24/350/256,256-FREQ/24/350%256,        //3 mi
        255-FREQ/24/371/256,256-FREQ/24/371%256,        //4 fa
        255-FREQ/24/416/256,256-FREQ/24/416%256,        //5 suo
        255-FREQ/24/467/256,256-FREQ/24/467%256,        //6 la
        255-FREQ/24/525/256,256-FREQ/24/525%256,        //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/556/256,256-FREQ/24/556%256,        //1 do
        255-FREQ/24/624/256,256-FREQ/24/624%256,        //2 re
        255-FREQ/24/700/256,256-FREQ/24/700%256,        //3 mi
        255-FREQ/24/742/256,256-FREQ/24/742%256,        //4 fa
        255-FREQ/24/833/256,256-FREQ/24/833%256,        //5 suo
        255-FREQ/24/935/256,256-FREQ/24/935%256,        //6 la
        255-FREQ/24/1049/256,256-FREQ/24/1049%256,      //7 xi
    
        0xff,0xea,                                      //0 休止符
        255-FREQ/24/1112/256,256-FREQ/24/1112%256,      //1 do
        255-FREQ/24/1248/256,256-FREQ/24/1248%256,      //2 re
        255-FREQ/24/1400/256,256-FREQ/24/1400%256,      //3 mi
        255-FREQ/24/1484/256,256-FREQ/24/1484%256,      //4 fa
        255-FREQ/24/1618/256,256-FREQ/24/1618%256,      //5 suo
        255-FREQ/24/1764/256,256-FREQ/24/1764%256,      //6 la
        255-FREQ/24/1968/256,256-FREQ/24/1968%256,      //7 xi
    };
     char ly_TH0;
    char ly_TL0;
    void music_delay(unsigned char timer)     //延时 125*n 毫秒
    {
        unsigned char i=125,j;
        do{
            do{
                for(j=0; j<230; j++)
                  ;
          }while(--i);
        }while(--timer);
    }
    
    //---------------------------------------------------------------------------//
    void music_play( char *pmsc)   //音乐
    {
        char music_freq=32;      //音高 
         char music_long;         //节拍延时
         char music_data=0;       //音符数据
        char music_up=0;                   //升半音
        char music_break=0;                //断奏
        ly_TH0=0xff;
        ly_TL0=0xea;                 
    sei();
    //---------------------------------------------------------
        while (*pmsc != 0x00)
            {
            music_data=*pmsc & 0x07;
            music_long=*pmsc>>4;
            //---------------------------------------------------------
            if (music_long != 0){          //是音符,非功能码
                if (*pmsc&0x80){           //需升降调
                    if (((*pmsc) & 0x08) == 0)
                        {if(music_freq >= 16) music_freq -= 16;}   //音高下降 
                    else
                        {if(music_freq < 48) music_freq += 16;}    //音高上升
                 }
                //---------------------------------------------------------
                if (music_up==1){          //升半音
                    ly_TH0=music_frequp_tab[(music_freq  + (music_data <<1))];
                    ly_TL0=music_frequp_tab[(music_freq + (music_data <<1)+1)];
                }
                else{                      //不升半音
                    ly_TH0=music_freq_tab[(music_freq + (music_data <<1))];
                    ly_TL0=music_freq_tab[(music_freq + (music_data <<1)+ 1)];
                }
                //---------------------------------------------------------
                if (music_break){          //断奏
                    music_delay(music_l_tab[music_long&0x07]-1);
                    ly_TH0=0xff;
                    ly_TL0=0xea;
                    music_delay(1);
                }
                else                      //连奏
                    music_delay(music_l_tab[music_long&0x07]);
            }
            //---------------------------------------------------------
            else                          //是功能码
                {
                switch(music_data){
                case 0x04:
                  music_up=0; break;      //不升半音                    
                case 0x05:
                  music_up=1; break;      //升半音                    
                case 0x06:
                music_break=0; break;   //断奏                    
            case 0x07:
                music_break=1;break;    //连奏                    
                }
            }
            //---------------------------------------------------------
            pmsc++;
        }
      cli();            //播放结束,关中断
    }
    
    void DEVICE_INIT(void){
    cli();
    TCCR1A=0;
    TCCR1B=(1<<CS12)|(1<<CS10);
    TCNT1=344;
    TIMSK1=(1<<TOIE1);
    DDRB|=(1<<DDB5);
    PORTB|=(0<<PORTB5);
    sei();
    }
    
    ISR(TIMER1_OVF_vect)
    {
    TCNT1=65535-((ly_TH0*256+ly_TL0)/1000000)/(1024*(1/16000000));
    PORTB=(~PORTB)&(1<<PORTB5);
    }
    
    void setup()
    {
     DEVICE_INIT();
      while(1)
      music_play(music1); //播放音乐
    
    }
    void loop(){
    
    }
    
    链接:https://pan.baidu.com/s/1OEe7TSm58zX87jilmajOIw
    提取码:jqxh






    大家的支持是我无限的动力
  • TA的每日心情
    难过
    2019-8-24 00:33
  • 签到天数: 68 天

    [LV.6]常住居民II

    发表于 2019-7-6 13:27 | 显示全部楼层
    好听,好厉害,顶
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    Arduino lcd屏幕亮了但是不显示字符
    Arduino lcd屏幕亮了但是
    Arduino的lcd屏亮了但是上面没有字符显示,串进去的滑动变阻器也旋过了,但是还是没有
    【原创】全球最小口袋3D打印机mini one直播教程贴
    【原创】全球最小口袋3D打
    最近闲得蛋疼,没事搞个掌上3D打印机,先放效果图吧。 搞了半天,终于能正常打印,
    [限时福利]5分钟带你快速了解新一代开发板:M5STACK
    [限时福利]5分钟带你快速
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    【Arduino】108种传感器模块系列实验(98)---L298N电机驱动板
    【Arduino】108种传感器模
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    两个ESP8266通过云端实现远程数据交互
    两个ESP8266通过云端实现
    原理简述:利用发布订阅模式。一个ESP8266作为消息发布者,另一个ESP8266作为消息订阅
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表