0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何用鸿蒙OS在蜂鸣器播放音乐

鸿蒙系统HarmonyOS 来源:oschina 作者:osc_2wq8ft8d 2020-11-11 12:04 次阅读

本文介绍如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系统的PWM接口 驱动蜂鸣器 播放音乐。

用PWM输出方波

PWM输出的方波频率

通过PwmStart接口的注释,可以知道freq参数是分频倍数,PWM实际输出的方波频率等于 PWM时钟源频率 除以 分频倍数,即

f = Fcs / freq

其中,Fcs是PWM时钟源频率;

PWM输出方波的占空比

通过PwmStart接口的duty参数可以控制输出方波的占空比,占空比是指PWM输出的方波波形的高电平时间占整个方波周期的比例,具体占空比值是 duty 和 freq的比值,例如想要输出占空比 50%的方波信号,那么duty填的值就要是 freq/2;

音符-频率对应关系

参考:https://liam.page/2018/04/09/pitch-interval-and-harmonic/

开发板可以输出的最低频率

通过前面的公式,我们知道:

PWM输出的方波频率和freq成反比,freq越大,输出的方波频率越小;

freq是unsinged short类型,最大值为65535;
因此,输出频率的最小值取决于时钟源,PWM的默认时钟源为160M:

unsignedintHalPwmInit(HalWifiIotPwmPortport){if(hi_pwm_set_clock(PWM_CLK_160M)!=HI_ERR_SUCCESS){return(unsignedint)HAL_WIFI_IOT_FAILURE;
}returnhi_pwm_init((hi_pwm_port)port);
}

我们通过直接调用hi_pwm_set_clock接口,可以修改时钟源:

/**
*@ingroupiot_pwm
*
*EnumeratesthePWMclocksources.CNcomment:PWM时钟源枚举。CNend
*/typedefenum{
PWM_CLK_160M,/**< 160M APB clock.CNcomment:160M 工作时钟 CNend */
    PWM_CLK_XTAL, /**< 24M/40M crystal clock.CNcomment:24M或40M 晶体时钟 CNend */
    PWM_CLK_MAX   /**< Maximum value, which cannot be used.CNcomment:最大值,不可使用CNend */} hi_pwm_clk_source;hi_u32 hi_pwm_set_clock(hi_pwm_clk_source clk_type);

通过注释我们知道hi_pwm_set_clock(PWM_CLK_XTAL);可以将时钟源设置为晶体时钟,晶体时钟可能为24M或40M;
那么问题来了——晶体时钟到底是多少?

晶体时钟频率是多少?

我们可以通过通过实验,测算出晶体时钟频率,具体步骤如下:

使用hi_pwm_set_clock(PWM_CLK_XTAL);设置时钟源为晶体时钟;

使用PwmStart(WIFI_IOT_PWM_PORT_PWM0, 20*1000, 40*1000);输出方波信号;

使用示波器测量方波频率;
经实际测量,方波评率为1000Hz,因此,时钟频率为1000 * 40 * 1000也就是 40 MHz;

可以输出的方波最低频率

因此,方波最低频率就是 40M / 65535 ,也就是:

>>>40*1000*1000/65535
610.3608758678569

对照上面的频率表,可以知道,能够输出E♭以上的所有音符;

准备曲谱

为了代码实现起来简单,我选择了《两只老虎》的曲谱作为素材,很快找到了简谱:

简谱说明

对于缺乏音乐基础的同学,简谱上的一些记号可能不太清楚是什么意思,这里简单说明一下:

左上角的1=C是表示调式(可以不用关心),1是唱名,C是音名,1=C是正调(就是常规的对应关系: 1-C,2-D, 3-E, 4-F, 5-G, 6-A, 7-B);

左上角的 4/4 是四四拍,是指 四分音符为一拍, 每小节有四拍;

下面谱子上的竖线就是每个小节分隔符,和4/4对应;

“跑得快”上面5后面的横线表示延时一拍;

“一直没有眼睛”一句,5后面的点表示顺延半拍,一条下划线表示二分之一时间,两条下划线表示四分之一时间;

编写代码

有了以上知识,我们就可以编写代码了,关键部分代码如下:

staticvolatileintg_buttonPressed=0;staticconstuint16_tg_tuneFreqs[]={0,//40MHz对应的分频系数:
38223,//11046.5
34052,//21174.7
30338,//31318.5
28635,//41396.9
25511,//51568
22728,//61760
20249,//71975.5
51021//5_783.99//第一个八度的5};//曲谱音符staticconstuint8_tg_scoreNotes[]={//《两只老虎》简谱:http://www.jianpu.cn/pu/33/33945.htm
1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1,1,8,1,1,8,1,//最后两个5应该是低八度的,链接图片中的曲谱不对,声音到最后听起来不太对劲};//曲谱时值,根据简谱记谱方法转写,4/4拍中下面划一条线是半拍,划两条线是四分之一拍,点是顺延半拍staticconstuint8_tg_scoreDurations[]={4,4,4,4,4,4,4,4,4,4,8,4,4,8,3,1,3,1,4,4,3,1,3,1,4,4,4,4,8,4,4,8,
};staticvoid*BeeperMusicTask(constchar*arg){
(void)arg;printf("BeeperMusicTaskstart!\r\n");

hi_pwm_set_clock(PWM_CLK_XTAL);//设置时钟源为晶体时钟(40MHz,默认时钟源160MHz)

for(size_ti=0;i< sizeof(g_scoreNotes)/sizeof(g_scoreNotes[0]); i++) {        uint32_t tune = g_scoreNotes[i]; // 音符
        uint16_t freqDivisor = g_tuneFreqs[tune];        uint32_t tuneInterval = g_scoreDurations[i] * (125*1000); // 音符时间
        printf("%d %d %d %d\r\n", tune, (40*1000*1000) / freqDivisor, freqDivisor, tuneInterval);
        PwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor/2, freqDivisor);
        usleep(tuneInterval);
        PwmStop(WIFI_IOT_PWM_PORT_PWM0);
    }    return NULL;
}

其中谱子最后两个5是谱子的错误,应该是低八度的5,也就是5下面应该打一个点;我修改了代码,让整个曲子听起来更自然;

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 有源无源蜂鸣器

    关注

    0

    文章

    2

    浏览量

    1158
  • 鸿蒙
    +关注

    关注

    57

    文章

    2358

    浏览量

    42876
收藏 人收藏

    评论

    相关推荐

    使用TLV320AIC3254EVM-U用PPS控制时候播放音乐,突然中断,然后又恢复,为什么?

    我使用TLV320AIC3254EVM-U 用PPS 控制时候播放音乐,突然中断,然后又恢复。出现频率很高。用TI的固件并用CS软件播放时候没有出现这个问题。 请问大家我需要做什么部分参数设置?power tune or 其他?
    发表于 11-01 07:15

    TPA3116加了MUTE电路后播放音乐音量开到最大喇叭出现杂音怎么解决?

    TPA3116加了MUTE电路后播放音乐音量开到最大喇叭出现杂音(低音最明显)
    发表于 10-24 07:23

    用freescale的CPU做host连接tlv320aic3254,播放音乐时,i2s上Wclk,Bclk都没有信号怎么解决?

    目前我们的项目是:用freescale的 CPU做host连接tlv320aic3254,是通过i2s连接传输信号的;the sampling rate 设置是44.1KHz,Mclk是24M; 目前问题是:播放音乐时,i2s上Wclk,Bclk都没有信号;
    发表于 10-22 07:40

    TAS5733L按照初始化的寄存器配置,播放音乐无声是怎么回事?

    按照贵司提供的初始化的寄存器配置(如附件)设置,读取0x05,0x06也是设定的值。播放音乐此时仍然无声。 请问,是否还有额外的寄存器需要配置? 谢谢!
    发表于 10-21 07:41

    TAS5805BYPASS状态下小音量播放音乐遇到低频大动态时会有“POPO”的爆音,怎么解决?

    TAS5805测试电路的失真1%以下。但在BYPASS状态下小音量播放音乐遇到低频大动态时会有“POPO”的爆音。请问怎么解决。
    发表于 10-12 06:37

    TAS2521播放音乐的时,将音量调到最大,喇叭就会自动mute,这种情况是不是输出功率过大导致过流保护?

    你好,想请教以下几个问题 1.播放音乐的时候,只要将音量调到最大,喇叭就会自动mute。这种情况的是不是输出功率过大导致的过流保护? 2.为什么播放单频或者粉噪声的时候,就算
    发表于 10-10 08:16

    设计的TPA3116D2功放电路,播放音乐最大输出时部分IC出现断音的原因?

    我设计的TPA3116D2功放电路,供电24V,输出电感33uH,IC顶部加了散热器,双声道2个4欧喇叭,3.3UF接2个高音喇叭,播放音乐最大输出时部分IC出现断音(保护),重新更换TPA3116就好了,请教是可能什么原因会导致3116损害,有什么对策吗,
    发表于 08-16 11:25

    TPA3116播放音乐时,声音非常大时会啪啪响,请问有办法解决吗?

    TPA3116播放音乐时,声音非常大时(已出现截止失真)会啪啪响,请问有办法解决么? 用TCD-781曲目测试发现,当播放曲目3,4,5时(17hz/0db正弦波),推挽输出幅度只要超过最大
    发表于 08-13 08:32

    wifi的STA模式下无法播放sdcard音乐是什么原因?

    pipeline_sdcard_mp3_control的基础上加了一个wifi的sta,本来想一边连接热点一边播放音乐。后来运行之后按play就没法正常播放了。刚开始还以为要用线程。后来创建了一
    发表于 06-28 06:55

    如何通过BLE播放音频?

    现在是我有一个android app,有一块esp32板子上面有喇叭,板子刷了a2dp_sink例子的固件。如果用bluetooth 和板子pair之后,可以播放音乐。 现在要求不用bluetooth,而是用ble连接,然后播放音乐,请问可以实现吗?求指点迷津,谢谢。
    发表于 06-26 06:36

    请问用蜂鸣器播放音乐的时候如何同时播放两段音乐

    我用 PWM 控制的音乐播放,可以按照乐谱播放音符 但现在有个需求,是播放背景音乐的时候同时叠
    发表于 06-14 08:23

    HarmonyOS实战开发-如何实现音频低时延录制和播放,AudioVivid音乐播放的相关功能

    介绍 本示例主要展示了音频低时延录制和播放,AudioVivid音乐播放的相关功能: 低时延录制。 低时延播放。 AudioVivid播放.
    发表于 05-11 20:26

    KT148A语音芯片串口版本播放音乐的时候,直接导致单片机工作异常

    使用你们KT148A串口版本播放音乐的时候,直接导致单片机工作异常,测了一下供电发现每次播放音乐的时候,供电会有很大波动。看了一下你们的手册,说是带载能力不够,但是我把供电接出来,接到你们的测试板上时,单片机又正常工作了
    的头像 发表于 05-07 10:50 503次阅读
    KT148A语音芯片串口版本<b class='flag-5'>播放音乐</b>的时候,直接导致单片机工作异常

    蓝牙连接手机播放音乐的同时传输少量数据,那些蓝牙芯片可以实现呢

    蓝牙连接手机播放音乐的同时连接另一蓝牙芯片传输少量数据,那些蓝牙芯片可以实现呢? 这个需求,其实就是双模的需求 简单描述就是:播放音乐的同时,还可以连接ble,进行数据的传输。二者同时进行,互不
    的头像 发表于 04-30 11:26 718次阅读
    蓝牙连接手机<b class='flag-5'>播放音乐</b>的同时传输少量数据,那些蓝牙芯片可以实现呢

    鸿蒙HarmonyOS开发实战:【分布式音乐播放

    本示例使用fileIo获取指定音频文件,并通过AudioPlayer完成了音乐播放完成了基本的音乐播放、暂停、上一曲、下一曲功能;并使用DeviceManager完成了分布式设备列表
    的头像 发表于 04-10 17:51 879次阅读
    <b class='flag-5'>鸿蒙</b>HarmonyOS开发实战:【分布式<b class='flag-5'>音乐</b><b class='flag-5'>播放</b>】