本文介绍如何在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:

unsigned int HalPwmInit(HalWifiIotPwmPort port)

{

if (hi_pwm_set_clock(PWM_CLK_160M) != HI_ERR_SUCCESS) {

return (unsigned int)HAL_WIFI_IOT_FAILURE;

}

return hi_pwm_init((hi_pwm_port)port);

}

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

/**

* @ingroup iot_pwm

*

* Enumerates the PWM clock sources.CNcomment:PWM时钟源枚举。CNend

*/

typedef enum {

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后面的点表示顺延半拍,一条下划线表示二分之一时间,两条下划线表示四分之一时间;

编写代码

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

static volatile int g_buttonPressed = 0;

static const uint16_t g_tuneFreqs[] = {

0, // 40M Hz 对应的分频系数:

38223, // 1 1046.5

34052, // 2 1174.7

30338, // 3 1318.5

28635, // 4 1396.9

25511, // 5 1568

22728, // 6 1760

20249, // 7 1975.5

51021 // 5_ 783.99 // 第一个八度的 5

};

// 曲谱音符

static const uint8_t g_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拍中下面划一条线是半拍,划两条线是四分之一拍,点是顺延半拍

static const uint8_t g_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,

};

static void *BeeperMusicTask(const char *arg)

{

(void)arg;

printf("BeeperMusicTask start!rn");

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

for (size_t i = 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 %drn", 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下面应该打一个点;我修改了代码,让整个曲子听起来更自然;

完整代码:https://gitee.com/hihopeorg/HarmonyOS-IoT-Application-Development/blob/master/02_device_control/beeper_music_demo.c

鸿蒙二部曲关系,用鸿蒙OS在蜂鸣器上放一曲《两只老虎》相关推荐

  1. 鸿蒙二部曲之一,网文封神之作,“鸿蒙二部曲”和“斗罗四部曲”你选择站哪边?...

    谈到网络小说,绕不过的就是辰东的"遮天三部曲".酒徒的"隋唐三部曲".西红柿的"鸿蒙二部曲".冰清玉洁唐三少的"斗罗四部曲&quo ...

  2. 用鸿蒙OS在蜂鸣器上播放一曲《两只老虎》

    本文介绍如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系统的PWM接口 驱动蜂鸣器 播放音乐. 用PWM输出方波的API 鸿蒙系统IoT硬件子系统提供了PWM相 ...

  3. 鸿蒙3部曲先看哪部,“斗罗”有四作,那当年齐名的“鸿蒙”系列到底有“几部曲”?...

    说到<斗罗大陆>相信很多人都很熟悉了.同时也相信大家都知道<斗罗大陆>一共有四部作品.但不知道大家还记不记得曾经和<斗罗大陆>名气不相上下的"鸿蒙&quo ...

  4. 鸿蒙3部曲先看哪部,星辰变是“鸿蒙”系列的作品,那“鸿蒙”系列到底有多少部曲?...

    说到<星辰变>,相信很多人都知道他的作者就是番茄吧?而番茄笔下最出名系列的小说,无疑就是"鸿蒙"系列了,其中<星辰变>就是"鸿蒙"系列中 ...

  5. 鸿蒙3部曲先看哪部,讨论雪鹰与鸿蒙三部曲的关系

    1.相信番茄的每部小说出来,心里都在想这会不会是鸿蒙三部曲的最后一部呢,鸿蒙金榜最后一位掌控者呢. 2.但是隔了这么多部,番茄依旧未写,第三部,让人不禁思考,会不会第三部是番茄的封山之作呢. 3.如果 ...

  6. 鸿蒙3部曲先看哪部,“隋唐三部曲”“鸿蒙三部曲”“斗罗四部曲”谁才是网文巅峰之作...

    原标题:"隋唐三部曲""鸿蒙三部曲""斗罗四部曲"谁才是网文巅峰之作 从网络小说诞生的那一刻起,续集就是一个绕不过去的话题,如同电视剧一样. ...

  7. 华为鸿蒙二个重大失误,华为鸿蒙系统曝光后,比尔盖茨遗憾表示:最大失误是让安卓崛起了...

    说起比尔盖茨大家都很熟悉,作为全球PC行业霸主微软的创始人,比尔盖茨在很长一段时间都位居于全球首富,不夸张的说,比尔盖茨已经成为了许多小伙伴心中财富的象征,也正是因为如此,比尔盖茨的谈话往往也会引起许 ...

  8. 题目:保护区里面有两只熊……,那么,在熊大熊二都不犯傻的前提下,都希望吃到最多的蜂蜜,请分析一下熊大熊二的行动逻辑,最优方案。

    题目: 保护区里面有两只熊,熊大.熊二一起住在一个山洞里.山洞东侧有管理员看护,西侧有提供蜂蜜的小屋,只要有熊跑到东侧向管理员吼一下,管理员就会通知西边的小屋向山洞摆放10瓶蜂蜜,但是谁去东侧吼管理员 ...

  9. 安卓 鸿蒙 emui之间的关系,Android、鸿蒙 OS 和 EMUI 是什么关系?

    Android 11已在 9 月 9 日发布,据华为官方消息,9月10日开始的 HDC 2020 大会上,也会发布 EMUI 11 和鸿蒙 2.0.在三者被拿来做比较之前,先来看看他们之间的关系. E ...

  10. 华为那个手机是鸿蒙,EMUI 11就是鸿蒙前奏 华为手机全面升级鸿蒙OS稳了

    曾几何时,在那个特殊的背景下,华为鸿蒙系统的呼声何等之高.网友苦等许久不禁要问,鸿蒙究竟何时出世?其实随着EMUI每一次版本的更新,鸿蒙都离我们更近了一步.华为消费者BG软件部总裁王成录正式解答:自E ...

最新文章

  1. 云计算技术 — OpenStack v.s. Kubernetes
  2. 如何开始DDD(完)
  3. jenkins+k8s实现持续集成
  4. 销售额分布直方图和茎叶图
  5. Vue中使用echarts图表插件
  6. Python中字符串反转的一个简单操作
  7. 使用自定义条件触发Nintex workflow
  8. clion opencv安装_Mac 下搭建 Clion + OpenCV4.x 的开发环境
  9. 《30天学习30种新技术》-Day 15:Meteor —— 从零开始创建一个 Web 应用
  10. 教师国培计算机计划,教师国培计划大全
  11. Gantt - attachEvent事件监听 - 一个参数事件
  12. 根据IP获取国家代码
  13. lenovo启动热键_联想电脑如何进入U盘启动,按哪个快捷键?
  14. 【优先队列】Toda 2
  15. 项目轮播图功能实现和导航栏的实现
  16. 手机投屏到电脑显示屏
  17. 《夏洛特烦恼》观后感
  18. 前端如何实现一个滚动的文本字幕
  19. 口袋理财:“来了就是深圳人?”全国均价最高的房租了解一下
  20. flume的sink测试赫赫有名

热门文章

  1. Verilog学习日志(2021.7.31)
  2. 【线性代数笔记】矩阵的合同关系
  3. 数据库系统的简单结构图
  4. linux mint五笔输入法,Linux Mint安装ibus五笔和拼音输入法简明教程
  5. cross product or vector product - 叉积或向量积
  6. 如何实现批量截取整个网页完整长截图?内容很多很高浏览器看不全Chrome插件崩溃无需安FireShot,优爱酷批量长网页整页截图系统,设计师推荐的必备好工具好方法web2pic,html2jpeg
  7. 【最全的】BAT 批处理脚本教程
  8. 魏尔斯特拉斯函数 matlab,Applied Numerical Linear Algebra - James W. Demmel
  9. android_x86安装arm转译
  10. Siamese系列跟踪网络之SiamFC、SiamRPN、DaSiamRPN、SiamRPN++、SiamMask