用龙芯1c库实现无源蜂鸣器唱歌《送别》

本文介绍了如何利用龙芯1c库控制无源蜂鸣器唱歌,详细讲解了音调和节拍的基本原理,并通过《送别》的简谱展示了具体的实现过程,包括源码清单和实物图。
摘要由CSDN通过智能技术生成

龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,可用于裸机编程和实时系统,类似于STM32库。Git地址:http://git.oschina.NET/caogos/OpenLoongsonLib1c

无源蜂鸣器唱歌的原理

基本原理

一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能象电子琴那样能奏出多种音色的声音。因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和“节拍”。音调表示一个音符唱多高的频率,节拍表示一个音符唱多长的时间。 

音调

音调简介

一个音调对应一个频率。即do re mi fa so la xi。乐谱中有高音,中音和低音,每个都有do re mi fa so la xi。即总共3*7=21个频率。

// do re mi fa so la xi的低音频率(单位hz)
#define BUZZER_LOW_DO_1         (262)
#define BUZZER_LOW_RE_2         (294)
#define BUZZER_LOW_MI_3         (330)
#define BUZZER_LOW_FA_4         (349)
#define BUZZER_LOW_SO_5         (392)
#define BUZZER_LOW_LA_6         (440)
#define BUZZER_LOW_XI_7         (494)
// 中音
#define BUZZER_MIDDLE_DO_1      (523)
#define BUZZER_MIDDLE_RE_2      (587)
#define BUZZER_MIDDLE_MI_3      (659)
#define BUZZER_MIDDLE_FA_4      (698)
#define BUZZER_MIDDLE_SO_5      (784)
#define BUZZER_MIDDLE_LA_6      (880)
#define BUZZER_MIDDLE_XI_7      (988)
// 高音
#define BUZZER_HIGH_DO_1        (1047)
#define BUZZER_HIGH_RE_2        (1175)
#define BUZZER_HIGH_MI_3        (1319)
#define BUZZER_HIGH_FA_4        (1397)
#define BUZZER_HIGH_SO_5        (1568)
#define BUZZER_HIGH_LA_6        (1760)
#define BUZZER_HIGH_XI_7        (1976)

识别乐谱中的高低音

5351中的1是高音,音符1的上方有个小圆点;
615中的1也是高音;
其它的都是中音。
和高音相反,低音是在音符的底下有个小圆点。

无源蜂鸣器和有缘蜂鸣器的区别

注意,这里的“源”不是指电源。而是指震荡源。
无源蜂鸣器的特点是:
1 无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它
2 声音频率可控,可以做出“多来米发索拉西”的效果。
3 在一些特例中,可以和LED复用一个控制口
有源蜂鸣器的特点是:
1 有源蜂鸣器内部带震荡源,所以只要一通电就会叫
2 程序控制方便,单片机一个高低电平就可以让其发出声音,而无源蜂鸣器却做不到。

音调的软件实现

经过前面介绍,已经知道一个音调对应一个频率,给无源蜂鸣器不同频率的方波可以唱出do re mi fa so la xi。
通常,使用硬件PWM产生占空比为50%的不同频率的方波来实现。
龙芯1c库中已经有现成的PWM接口可供使用,接口中PWM周期的时间单位为ns,即PWM周期T = 1000000000 / freq。另外,目前(2017年7月)龙芯1c库中浮点功能还未完善,所以需要把占空比(浮点数)手动换算为高低电平的时间长度,占空比为50%,即周期T / 2就是一个PWM波形内高低电平的时间长度。虽然,我坚信使用浮点功能早晚会调通的,龙芯1C库中的PWM接口用占空比来表示也更符合人们的习惯,但这里还是需要稍微变通一下。

// 播放指定音高
void buzzer_sound(unsigned int freq)
{
    buzzer_pwm.period_ns = 1000000000 / freq;
    buzzer_pwm.low_ns = buzzer_pwm.period_ns / 2;
    pwm_init(&buzzer_pwm);
    return ;
}

节拍

节拍简介

节拍表示一个音符唱多长的时间,即一个频率的PWM波形的持续时间。

识别乐谱中的节拍

参考百度文库的《简谱中常用的音乐记号》

在一张乐谱中,我们经常会看到这样的表达式,如1=C (4/4) 、1=G(3/4) ……  等等,这里1=C (4/4),1=G(3/4) 表示乐谱的曲调,和我们前面所谈的音调有很大的关联,4/4、3/4  就是用来表示节拍的。以3/4 为例加以说明,它表示乐谱中以四分音符为节拍,每一小结有三拍。 

其中1 、2 为一拍,3、4、5为一拍,6为一拍共三拍。1 、2的时长为四分音符的一半,即为八分音符长,3、4的时长为八分音符的一半,即为十六分音符长,5的时长为四分音符的一半,即为八分音符长,6的时长为四分音符长。
一般说来,如果乐曲没有特殊说明,一拍的时长大约为400—500ms。

节拍的软件实现

根据前面介绍已经知道,节拍就是频率持续的时间。并且一拍的时间为四五百ms,这里选择一拍为400ms,那么十六分音符长为400ms / 16 = 25ms,毫秒级的延时用“龙芯1c库”中的函数delay_ms(n)实现是没问题的。

// 测试无源蜂鸣器--依次播放do re mi fa so la xi
void buzzer_test(void)
{
    buzzer_init();
    
    buzzer_sound(BUZZER_LOW_DO_1);
    delay_ms(BUZZER_DELAY_ONE_NOTE);
    
    buzzer_sound(BUZZER_LOW_RE_2);
    delay_ms(BUZZER_DELAY_ONE_NOTE);
    
    buzzer_sound(BUZZER_LOW_MI_3);
    delay_ms(BUZZER_DELAY_ONE_NOTE);
    
    buzzer_sound(BUZZER_LOW_FA_4);
    delay_ms(BUZZER_DELAY_ONE_NOTE);

    buzzer_sound(BUZZER_LOW_SO_5);
    delay_
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值