7851|20

466

帖子

0

TA的资源

版主

楼主
 

音乐盒其实就是这么简单!!! [复制链接]

 
本帖最后由 weizhongc 于 2015-9-13 00:12 编辑

                小时候我们都有听过那些音乐卡片的歌吧,现在要是听起来还是一样的熟悉,好听。
                这几天来了个朋友,就想着人家大老远过来,想给她个礼物。那就音乐盒吧,做起来也简单啊。
                想好后开始动手,手头上只有stm8L的单片机小板,网上又没有比较合适的例程可以参考,找啊找啊,找了挺久的,复制,粘贴出来的发音始终有问题。还是自己从头原理慢慢弄通吧。
                我们现在只要知道音调,跟时长(节拍)就行。对于音调我在网上找到了相应的频率表,也就是每个音调对应的频率。



我举一个栗子吧,《明天,你好 》这首歌,


对应音符的频率就在下面了,至于时长呢,在play中也有了,至于多久就不管了,因为我也不知道啊,我们就用软件点击出相应的音符 什么高低音啊,1/2拍之类的,然后生成数组就行了,在播放的时候,会从数组的第一个元素开始往下播放的, 就是对应着频率,时长这样了。


超高音的几个掉我们就不用了,就只要 低 中 高 这三个调就好了。
写程序的第一步:我们利用stm8的PWM 分别发出 以上相应的频率  262hz,294hz,330hz。。。。。
这样音调我们就有了,如果你手上只有其他单片机也可是试试,做一个相应音调的频率数字就行了。
stm8 在2m主频下运行,对应的频率表
const u16 FREQH[]={
        3823,3404,3034,2865,2551,2271,2024,
        1912,1702,1517,1433,1276,1137,1012,
        956,851,759,717,638,569,506
};(这频率还是有些偏差,发音不太对)


/**  PWM  初始化
  * @brief  Configure TIM2 peripheral
  * @param  None
  * @retval None
  */
static void TIM3_Config(void)
{
  /* Enable TIM2 clock */
  CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);

  /* Config TIM2 Channel 1 and channel 2 pins */
  GPIO_Init(GPIOD, GPIO_Pin_0 , GPIO_Mode_Out_PP_High_Fast);

  /* Time base configuration */
  TIM3_TimeBaseInit(TIM3_Prescaler_2, TIM3_CounterMode_Up, 65000);

  /* PWM1 Mode configuration: Channel1 */
  TIM3_OC2Init(TIM3_OCMode_PWM1, TIM3_OutputState_Enable, CCR1_Val, TIM3_OCPolarity_High,    TIM3_OCIdleState_Set);
        
  TIM3_OC2PreloadConfig(ENABLE);

  /* PWM1 Mode configuration: Channel2 */
/* TIM3_OC2Init(TIM2_OCMode_PWM1, TIM2_OutputState_Enable,CCR2_Val, TIM2_OCPolarity_High, TIM3_OCIdleState_Set);
  TIM2_OC2PreloadConfig(ENABLE);*/

  TIM3_ARRPreloadConfig(ENABLE);

  /* Enable TIM2 outputs */
  TIM3_CtrlPWMOutputs(ENABLE);

  /* TIM2 enable counter */
  TIM3_Cmd(ENABLE);
}


void delay_ms(u16 ms)
{               
                u16 i;
                while(ms--)
                {
                        for(i=0;i<380;i++);
                }               
}





const u8 LengthTab[7]= { 1,2,4,8,16,32,64 };
#define SOUND_SPACE         4/5         

//**************************************************************************
void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
        unsigned int NewFreTab[12];               
        unsigned char i,j;
        unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
        unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
                                                               
        
        SoundLength = 0;
        while(Sound[SoundLength] != 0x00)        
        {
                SoundLength+=2;
        }

        Point = 0;
        //---------获取歌曲数组中的数据
        Tone   = Sound[Point];               
        Length = Sound[Point+1];         // 读出第一个音符和它时时值
        
        LDiv0 = 12000/Speed;                 // 算出1分音符的长度(几个10ms)                                 
        LDiv4 = LDiv0/4;                         // 算出4分音符的长度               
        LDiv4 = LDiv4-LDiv4*SOUND_SPACE;

        while(Point < SoundLength)
        {
               
                if(Sound[Point]<=17)
                {
                        CurrentFre=Sound[Point]-11;//查出对应音符的频率         低音
                 }
                else if(Sound[Point]>20&&Sound[Point]<=27)
                {
                        CurrentFre=Sound[Point]-14;////查出对应音符的频率         中音
                }
                else if(Sound[Point]<=37&&Sound[Point]>30)
                {
                        CurrentFre=Sound[Point]-17;////查出对应音符的频率         高音
                }
               
                SL=Tone%10;                         // 普通音最长间隔标准                                       
                SM=Tone/10%10;                 //计算出高低音                                                
                SH=Tone/100;                 //计算出是否升半                                                

                if(SL!=0)
                {
                        
                        TIM3->CR1 &= (uint8_t)(~TIM_CR1_CEN);//disable tim3

                        TIM3->ARRH=FREQH[CurrentFre]/256;//修改对应音调的频率
                        TIM3->ARRL=FREQH[CurrentFre]%256;
                        
                        PWM=FREQH[CurrentFre]/8;
                        TIM3->CCR2H=PWM/256;                   //PWM占空比为%12.5
                        TIM3->CCR2L=PWM%256;
                        TIM3->CR1 |= TIM_CR1_CEN;   //enable  tim3
                }
                SLen=LengthTab[Length%10];         //算出音符类型(0普通1连音2顿音)
                XG=Length/10%10;                        
                FD=Length/100;
                LDiv=LDiv0/SLen;                         //算出连音音符演奏的长度(多少个10ms)
                if (FD==1)
                        LDiv=LDiv+LDiv/2;
                if(XG!=1)        
                        if(XG==0)                                 //算出普通音符的演奏长度
                                if (SLen<=4)        
                                        LDiv1=LDiv-LDiv4;
                                else
                                        LDiv1=LDiv*SOUND_SPACE;
                        else
                                LDiv1=LDiv/2;                 //算出顿音的演奏长度
                else
                        LDiv1=LDiv;
                if(SL==0) LDiv1=0;
                        LDiv2=LDiv-LDiv1;                 //算出不发音的长度
                        
                if (SL!=0)
                {
                        delay_ms(LDiv1*10);
                }
                if(LDiv2!=0)
                {
                        delay_ms(LDiv2*10);
                }
                Point+=2;
                Tone=Sound[Point];
                Length=Sound[Point+1];
                GPIO_ToggleBits(GPIOB, GPIO_Pin_4);
        }
}


哈哈,感觉自己还是复制别人的东西来用的,只是会用而已,大家就将就看看吧 ,不懂的就跟帖。。 huangq.7z (4.59 MB, 下载次数: 119, 售价: 1 分芯积分)


此帖出自stm32/stm8论坛

最新回复

不错,打个标记,说不定哪天用得上。  详情 回复 发表于 2019-3-9 12:43
点赞 关注(4)
 

回复
举报

994

帖子

3

TA的资源

一粒金砂(高级)

沙发
 
曾经51单片机的实验作业
此帖出自stm32/stm8论坛
 
 

回复

4008

帖子

0

TA的资源

版主

板凳
 
补充一下,其实音调和频率没有特定的关系,不同的乐器发出的频率和波形不一样
但是有个关系,每个8度频率差一倍,把这个一倍分成12分其中1234567之间还有5个半音,每个音符频率与之对应,说简单点定了一个音符的频率则其它音符就定了。
此帖出自stm32/stm8论坛

点评

有什么简单一点的软件吗?不想弄的太麻烦,因为对音乐的音调这些的不懂啊  详情 回复 发表于 2015-9-10 15:23
 
 

回复

2万

帖子

341

TA的资源

版主

4
 
用的是stm8
超高音不好整,楼主搞的是低中高音
此帖出自stm32/stm8论坛
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

5
 
谢谢楼主分析,其实我懂音乐,最麻烦的就是怎么让音调跟频率这些的转换。有什么软件吗还是怎样
此帖出自stm32/stm8论坛
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

6
 
huo_hu 发表于 2015-9-10 11:37
补充一下,其实音调和频率没有特定的关系,不同的乐器发出的频率和波形不一样
但是有个关系,每个8度频率 ...

有什么简单一点的软件吗?不想弄的太麻烦,因为对音乐的音调这些的不懂啊
此帖出自stm32/stm8论坛

点评

都说完了,啥不懂? 简单一点就是变频率,再复杂一点加节拍渐弱,这样你才可以区分出两个相同的音符,原理上没有更复杂的了.  详情 回复 发表于 2015-9-10 22:11
附件里面有软件的  详情 回复 发表于 2015-9-10 17:41
 
 
 

回复

466

帖子

0

TA的资源

版主

7
 
huaiqiao 发表于 2015-9-10 15:23
有什么简单一点的软件吗?不想弄的太麻烦,因为对音乐的音调这些的不懂啊

附件里面有软件的
此帖出自stm32/stm8论坛

点评

好的,我下载下来学习下。  详情 回复 发表于 2015-9-10 19:12
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

8
 
weizhongc 发表于 2015-9-10 17:41
附件里面有软件的

好的,我下载下来学习下。
此帖出自stm32/stm8论坛
 
 
 

回复

710

帖子

5

TA的资源

一粒金砂(高级)

9
 
以前用蜂鸣器弄过猪八戒背媳妇,,哈哈不过是复制别人的,
此帖出自stm32/stm8论坛
 
 
 

回复

4008

帖子

0

TA的资源

版主

10
 
huaiqiao 发表于 2015-9-10 15:23
有什么简单一点的软件吗?不想弄的太麻烦,因为对音乐的音调这些的不懂啊

都说完了,啥不懂?
简单一点就是变频率,再复杂一点加节拍渐弱,这样你才可以区分出两个相同的音符,原理上没有更复杂的了.
此帖出自stm32/stm8论坛

点评

我看到 楼主的附件里有个软件了,我学习下。哈哈  详情 回复 发表于 2015-9-10 22:24
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

11
 
huo_hu 发表于 2015-9-10 22:11
都说完了,啥不懂?
简单一点就是变频率,再复杂一点加节拍渐弱,这样你才可以区分出两个相同的音符,原理上 ...

我看到 楼主的附件里有个软件了,我学习下。哈哈
此帖出自stm32/stm8论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

12
 
用32该怎么做呢
此帖出自stm32/stm8论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

13
 
下载下来看看
此帖出自stm32/stm8论坛
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

14
 
下载下来看看
此帖出自stm32/stm8论坛
 
 
 

回复

106

帖子

0

TA的资源

一粒金砂(中级)

15
 
楼主,输出设备用什么啊?
此帖出自stm32/stm8论坛

点评

弄个蜂鸣器啊  详情 回复 发表于 2019-3-6 13:27
 
 
 

回复

466

帖子

0

TA的资源

版主

16
 
inkinessray 发表于 2019-3-5 11:11
楼主,输出设备用什么啊?

弄个蜂鸣器啊
此帖出自stm32/stm8论坛
 
 
 

回复

869

帖子

0

TA的资源

禁止发言

17
 
谢谢楼主,支持分享
此帖出自stm32/stm8论坛
 
 
 

回复

106

帖子

0

TA的资源

一粒金砂(中级)

18
 

哦,明白,多谢!
此帖出自stm32/stm8论坛
 
 
 

回复

4008

帖子

0

TA的资源

版主

19
 
耳机或喇叭也行,加个电阻限流,最好用两个io互反输出,这样比较接近正弦波
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(中级)

20
 
现在有乐谱小软件了吧
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表