步进电机播放音乐-Arduino中文社区 - Powered by Discuz! Archiver

AimHigh 发表于 2019-3-7 11:33

步进电机播放音乐

硬件:使用arduino uno板子与步进电机驱动器TB6600实物图

因为我这里用的是方波,才用步进电机振动与地座产生共振来达到播放音乐的效果,所以这里板子接线只需要将13口与驱动器的脉冲口相接,方向使能可以不接,其它可以用共阴或者共阳。

播放音乐,首先得知道do,re,mi,fa,suo,la,xi等这些对应的频率,这里就需要用的示波器,将脉冲线接到示波器,通过调整方波频率来找到这些频率,记下来。
比如charmusic_freq_tab={             //音符定时器值表
    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分频。定时器初始化与中断代码如下:

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-1);
                ly_TH0=0xff;
                ly_TL0=0xea;
                music_delay(1);
            }
            else                      //连奏
                music_delay(music_l_tab);
      }
      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();            //播放结束,关中断
}

播放效果视频如下:

https://v.youku.com/v_show/id_XNDExNDU3MTE1Mg==.html?spm=a2hzp.8244740.0.0


全部代码如下:
#include <interrupt.h>
#include <iom328p.h>
#defineFREQ 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={0,1,2,3,4,6,8,16};//音乐节拍
charmusic_freq_tab={             //音符定时器值表
    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
};
charmusic_frequp_tab={         //升半音
    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-1);
                ly_TH0=0xff;
                ly_TL0=0xea;
                music_delay(1);
            }
            else                      //连奏
                music_delay(music_l_tab);
      }
      //---------------------------------------------------------
      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






Gan11 发表于 2021-6-10 23:26

链接失效了,能麻烦再发一次吗

wangyirun 发表于 2019-7-6 13:27

好听,好厉害,顶

Y立方 发表于 2020-10-1 17:08

#include <interrupt.h>
#include <i o m 3 2 8 p.h>
这两个库函数能发一下么

AimHigh 发表于 2021-6-12 22:48

wangyirun 发表于 2019-7-6 13:27
好听,好厉害,顶

感谢支持

chaohong100 发表于 2022-5-13 11:39

这是神人。:handshake
页: [1]
查看完整版本: 步进电机播放音乐