打印
[MM32软件]

【MM33 eMiniBoard测评报告】+播放背景音乐的尝试

[复制链接]
2989|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hu9jj|  楼主 | 2020-6-8 15:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hu9jj 于 2020-6-11 13:30 编辑

    评测告一段落之后,我又开始了播放背景音乐的尝试,传统做法是通过改变延时来翻转引脚达到改变频率的目的,通常是在播放音乐时,单片机就不能做其他的事情。我则设想通过两个定时器来完成,一个毫秒定时器来控制节拍,一个微秒定时器来控制引脚的翻转。这样在主循环中只要在节拍结束时取下一个音符的频率和节拍数据,控制引脚翻转就交给定时器中断完成,如此便可以达到播放背景音乐的目的。
    测试程序用song变量表示当前音乐数组的下标序号,当song=0时停止播放,用cycle,space两个变量分别表示当前的音阶(频率)和节拍,然后用cycle_n,space_n两个变量供定时器计数,在主循环中判断,若space_n>space,则表示当前节拍完成了,取下一个音阶和节拍数据。在微秒定时器中断中一方面给cycle_n加1,另一方面判断cycle_n是否大于cycle,如果大于,则翻转引脚并清零cycle_n继续计数。在音乐数据二维数组中,下标0的数据不会被使用,数组最后必须添加两个0表示结束,以便在循环中结束播放。
    毫秒定时器就利用了delay.c里面的systic中断,只负责space_n加1,代码如下:
static void TimingDelayDecrement(void)
{
    if (TimingDelay != 0x00) {
        TimingDelay--;
    }
        ms++;
        space_n++;        //音乐节拍计时
}

    微秒定时器是启用了tim2,在定时器中断里,我开始用引脚置位后再复位的办法,也许是时间太短,喇叭无反映,尝试加__NOP()延时也不起作用,而且延时太多会引起单片机假死,只有使用引脚翻转命令才有效,但输出的频率太低,效果很差。尝试缩短定时器延时时间,受主频影响无法继续缩短,最后只好采取降低音符频率数值的办法才达到目的。下面是定时器2的配置代码:
Tim2_UPCount_test(2,47);         //控制扬声器

    在定时器2的中断处理中代码如下:
void TIM2_IRQHandler(void)
{

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

//    ucTim2Flag++;
    if(space > 0){
                cycle_n++;
                if(cycle_n > cycle){
                        SBK_TOGGLE();          //翻转引脚
                        cycle_n = 0;           //重新计数
                }
        }
}

    在主循环中的代码如下:
        //轮询按键状态
                keys[0] = GPIO_ReadInputDataBit(SW1_GPIO_Port,SW1_Pin);
                keys[1] = GPIO_ReadInputDataBit(SW2_GPIO_Port,SW2_Pin);
                keys[2] = GPIO_ReadInputDataBit(SW3_GPIO_Port,SW3_Pin);
                keys[3] = GPIO_ReadInputDataBit(SW4_GPIO_Port,SW4_Pin);
               
                if(0 == keys[3]){
                        LED4_ON();
                        song = 1;           //启动音乐
                        LED3_ON();
                        space = 1;
                }
                else
                        LED4_OFF();
               
                if(0 == keys[2]){       //中断播放
                        song = 0;
                        cycle = 0;
                    LED3_OFF();
                }
               
                if(song > 0){           //音乐播放控制
                        if((space > 0) & (space_n > space)){
                                LED4_ON();
                cycle = SONG1[song][0]>>4;//取当前的音阶cycle及节拍space
                                space = SONG1[song][1]<<1;
                                cycle_n = 0;    //音符及节拍计数清零
                                space_n = 0;

                LCD_write_value(25,3,4,0,0,cycle);
                LCD_write_value(25,4,4,0,0,space);

                            song++;         //准备取下一音符
                LCD_write_value(60,3,3,0,0,song);

                                if(space == 0){
                                        song = 0;   //取得末尾的0时结束播放
                                    LED3_OFF();
                                }
                                LED4_OFF();
                        }
                }

    经过三天时间的反复测试,程序基本上达到了预期,只是休止符的节拍延时不正确,尚未找到原因。


    下面是【城南旧事】主题歌【送别】的音乐数据:
uint16_t SONG1[][2] =   //数据表,音阶(微秒)、节拍(毫秒)
{
        0,0,
        
        1276,250,    //5   
        1517,125,    //3
        1276,125,    //5
        956, 500,    //1^
        1137,250,    //6
        956, 125,    //1^
        1137,125,    //6
        1276,500,    //5
        
        1276,250,    //5
        1912,125,    //1
        1703,125,    //2
        1517,250,    //3
        1703,125,    //2
        1912,125,    //1
        1703,750,    //2
        0,50,       //0
        
        1276,250,    //5
        1517,125,    //3
        1276,125,    //5
        956, 375,    //1^
        1013,125,    //7
        1137,250,    //6
        956, 250,    //1^
        1276,500,    //5
        
        1276,250,    //5
        1703,125,    //2
        1517,125,    //3
        1432,375,    //4
        2026,125,    //7_
        1912,750,    //1
    0,50,       //0

        1137,250,    //6
        956, 250,    //1^
        956,500,    //1^
        1013,250,    //7
        1137,125,    //6
        1013,125,    //7
        956,500,    //1^
        
        1137,125,    //6
        1013,125,    //7
        956, 125,    //1^
        1137,125,    //6
        1137,125,    //6
        1276,125,    //5
        1517,125,    //3
        1912,125,    //1
        1703,750,    //2
        0,50,       //0
        
        1276,250,    //5
        1517,125,    //3
        1276,125,    //5
        956,375,     //1^
        1013,125,    //7
        1137,250,    //6
        956, 250,    //1^
        1276,500,    //5
        
        1276,250,    //5
        1703,125,    //2
        1517,125,    //3
        1432,375,    //4
        2026,125,    //7_
        1912,1000,   //1
        
        0,0,
        0,0,
        
};




使用特权

评论回复
沙发
hu9jj|  楼主 | 2020-6-8 16:00 | 只看该作者
    下面是本次测试项目的压缩文件包,我已经将其中的I2C读取DS1307日历模块的代码注释了,对LCD5110操作的代码不会影响到程序运行,所以此压缩包下载解压后便可运行。
test33.rar (4.99 MB)



使用特权

评论回复
板凳
hu9jj|  楼主 | 2020-6-8 16:12 | 只看该作者
本帖最后由 hu9jj 于 2020-6-8 16:16 编辑

    程序运行时,按K4键启动播放,播放时绿色LED会亮起,直到播放结束或中断停止,每次取音符和节拍数据时红色LED会闪亮一下,在播放过程中可以按K3键提前结束播放。
    修改下面的移位值可以改变音调高低:
     cycle = SONG1[song][0]>>3;//取当前的音阶cycle及节拍space

    修改下面的移位值可以改变音乐节拍(速度):

    space = SONG1[song][1]<<1;

使用特权

评论回复
地板
hu9jj|  楼主 | 2020-6-9 10:01 | 只看该作者
找到休止符延时不正确的原因了,原来是在定时器中断中判断的变量错用成space了,改为cycle就行。程序完美完成。

使用特权

评论回复
5
huangzushuimd| | 2020-6-9 11:08 | 只看该作者
试用了一下, 非常棒!

使用特权

评论回复
6
hu9jj|  楼主 | 2020-6-9 14:27 | 只看该作者
huangzushuimd 发表于 2020-6-9 11:08
试用了一下, 非常棒!

声音单调了些,还可以手动改变不同音部(右移不同位数)测试。

使用特权

评论回复
7
zeshoufx| | 2020-7-1 08:38 | 只看该作者
谢谢分享【播放背景音乐的尝试】测试,,,,

使用特权

评论回复
8
usysm| | 2020-7-9 07:56 | 只看该作者
播放背景音乐牛啊

使用特权

评论回复
9
typeof| | 2020-7-9 07:56 | 只看该作者
定时器开发的吗   

使用特权

评论回复
10
typeof| | 2020-7-9 07:57 | 只看该作者
这个给力呢。   

使用特权

评论回复
11
yujielun| | 2020-7-9 07:58 | 只看该作者
这个调是怎么确定的   

使用特权

评论回复
12
htmlme| | 2020-7-9 07:58 | 只看该作者
            

使用特权

评论回复
13
pklong| | 2020-7-9 07:58 | 只看该作者
不知道效果怎么样   

使用特权

评论回复
14
touser| | 2020-7-9 07:58 | 只看该作者
hu9jj 发表于 2020-6-8 16:00
下面是本次测试项目的压缩文件包,我已经将其中的I2C读取DS1307日历模块的代码注释了,对LCD5110操作的 ...

         

使用特权

评论回复
15
myiclife| | 2020-7-9 07:59 | 只看该作者
hu9jj 发表于 2020-6-8 16:12
程序运行时,按K4键启动播放,播放时绿色LED会亮起,直到播放结束或中断停止,每次取音符和节拍数据时 ...

这个节拍是怎么确定的   

使用特权

评论回复
16
uytyu| | 2020-7-9 07:59 | 只看该作者
都么有看懂其中的原理呢   

使用特权

评论回复
17
jkl21| | 2020-7-9 08:00 | 只看该作者
播放背景音乐是所有的音乐吗  

使用特权

评论回复
18
iyoum| | 2020-7-9 08:00 | 只看该作者
做个mp3播放器吗   

使用特权

评论回复
19
pklong| | 2020-7-9 08:00 | 只看该作者
有演示的视频资料吗   

使用特权

评论回复
20
htmlme| | 2020-7-9 08:00 | 只看该作者
谢谢版主分享的资料了。   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:Microchip
简介:让我们来为您提供帮助。我们可提供各种资源来帮助您解决一切问题。是否需要与我们的客户支持团队联系?您可以通过电话、在线聊天功能或电子邮件与他们联系。

151

主题

1059

帖子

11

粉丝