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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 13780|回复: 5

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

[复制链接]
发表于 2019-3-7 11:33 | 显示全部楼层 |阅读模式
硬件:使用arduino uno板子与步进电机驱动器TB6600实物图
2.png
因为我这里用的是方波,才用步进电机振动与地座产生共振来达到播放音乐的效果,所以这里板子接线只需要将13口与驱动器的脉冲口相接,方向使能可以不接,其它可以用共阴或者共阳。
接线.png
播放音乐,首先得知道do,re,mi,fa,suo,la,xi等这些对应的频率,这里就需要用的示波器,将脉冲线接到示波器,通过调整方波频率来找到这些频率,记下来。
[mw_shl_code=arduino,true]比如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[/mw_shl_code]
};还有很多,这里就不一一叙说了,原理很简单,有示波器就可以了,具体请看我上传的源代码。
有了上述这些东西之后,还需要了解arduino的定时器,我这里用的UNO板,我都板子晶振频率是16M,所以TCNT1=0Xffff - 定时时间/(分频数* (1/晶振频率)),分频数是调整计数的,越大计数越慢,一般有1、8、64、256、1024分频。定时器初始化与中断代码如下:

[mw_shl_code=arduino,true]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();            //播放结束,关中断
}[/mw_shl_code]

播放效果视频如下:





全部代码如下:
[mw_shl_code=arduino,true]#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(){

}
[/mw_shl_code]链接:https://pan.baidu.com/s/1OEe7TSm58zX87jilmajOIw
提取码:jqxh






发表于 2021-6-10 23:26 | 显示全部楼层
链接失效了,能麻烦再发一次吗
发表于 2019-7-6 13:27 | 显示全部楼层
好听,好厉害,顶
发表于 2020-10-1 17:08 | 显示全部楼层
#include <interrupt.h>
#include <i o m 3 2 8 p.h>
这两个库函数能发一下么
 楼主| 发表于 2021-6-12 22:48 | 显示全部楼层
wangyirun 发表于 2019-7-6 13:27
好听,好厉害,顶

感谢支持
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-9-20 20:47 , Processed in 0.106880 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表