成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用鴻蒙OS在蜂鳴器上播放一曲《兩只老虎》

開發(fā)
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請(qǐng)前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com/#zz

[[350170]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

本文介紹如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系統(tǒng)的PWM接口 驅(qū)動(dòng)蜂鳴器 播放音樂。

用PWM輸出方波的API

鴻蒙系統(tǒng)IoT硬件子系統(tǒng)提供了PWM相關(guān)接口,接口頭文件為wifiiot_pwm.h,其中開始輸出方波的接口為:

  1. /** 
  2.  
  3.  * @brief Outputs PWM signals based on the input parameters. 
  4.  
  5.  * 
  6.  
  7.  * This function outputs PWM signals from a specified port based on 
  8.  
  9.  * the configured frequency division multiple and duty cycle. 
  10.  
  11.  * 
  12.  
  13.  * @param port Indicates the PWM port number. 
  14.  
  15.  * @param duty Indicates the PWM duty cycle. 
  16.  
  17.  * @param freq Indicates the frequency-division multiple. 
  18.  
  19.  * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; 
  20.  
  21.  * returns an error code defined in {@link wifiiot_errno.h} otherwise. 
  22.  
  23.  * @since 1.0 
  24.  
  25.  * @version 1.0 
  26.  
  27.  */ 
  28. unsigned int PwmStart(WifiIotPwmPort port, unsigned short duty, unsigned short freq); 

PWM輸出的方波頻率

通過PwmStart接口的注釋,可以知道freq參數(shù)是分頻倍數(shù),PWM實(shí)際輸出的方波頻率等于 PWM時(shí)鐘源頻率 除以 分頻倍數(shù),即

f = Fcs / freq

其中,F(xiàn)cs是PWM時(shí)鐘源頻率;

PWM輸出方波的占空比
通過PwmStart接口的duty參數(shù)可以控制輸出方波的占空比,占空比是指PWM輸出的方波波形的高電平時(shí)間占整個(gè)方波周期的比例,具體占空比值是 duty 和 freq的比值,例如想要輸出占空比 50%的方波信號(hào),那么duty填的值就要是 freq/2;

音符-頻率對(duì)應(yīng)關(guān)系
音符-頻率對(duì)照表

這個(gè)表中有一個(gè)規(guī)律——音高升高一個(gè)八度,頻率升高一倍。

表格來自:https://liam.page/2018/04/09/pitch-interval-and-harmonic/

開發(fā)板可以輸出的最低頻率
通過前面的公式,我們知道:

  1. PWM輸出的方波頻率和freq成反比,freq越大,輸出的方波頻率越小;
  2. freq是unsinged short類型,最大值為65535;
    因此,輸出頻率的最小值取決于時(shí)鐘源,而PWM的默認(rèn)時(shí)鐘源為160M:
  1. unsigned int HalPwmInit(HalWifiIotPwmPort port) 
  2.     if (hi_pwm_set_clock(PWM_CLK_160M) != HI_ERR_SUCCESS) { 
  3.         return (unsigned int)HAL_WIFI_IOT_FAILURE; 
  4.     } 
  5.     return hi_pwm_init((hi_pwm_port)port); 

160M時(shí)鐘源條件下,輸出方波的最低頻率是:160M/65535=2441.44...,這個(gè)頻率還是略高,在上面的表格中沒有找到音名。但是我可以用上面表格值繼續(xù)往后推算兩個(gè)八度,就能夠覆蓋這個(gè)頻率(不過通常只使用7個(gè)八度,所以還是有點(diǎn)高)。

如果時(shí)鐘源頻率可以更低,那么輸出頻率也可以更低!
幸運(yùn)的是,通過調(diào)用hi_pwm_set_clock接口,可以修改時(shí)鐘源:

  1. /** 
  2.  * @ingroup iot_pwm 
  3.  * 
  4.  * Enumerates the PWM clock sources.CNcomment:PWM時(shí)鐘源枚舉。CNend 
  5.  */ 
  6. typedef enum { 
  7.     PWM_CLK_160M, /**< 160M APB clock.CNcomment:160M 工作時(shí)鐘 CNend */ 
  8.     PWM_CLK_XTAL, /**< 24M/40M crystal clock.CNcomment:24M或40M 晶體時(shí)鐘 CNend */ 
  9.     PWM_CLK_MAX   /**< Maximum value, which cannot be used.CNcomment:最大值,不可使用CNend */ 
  10. } hi_pwm_clk_source; 
  11.  
  12. hi_u32 hi_pwm_set_clock(hi_pwm_clk_source clk_type); 

通過注釋我們知道hi_pwm_set_clock(PWM_CLK_XTAL);可以將時(shí)鐘源設(shè)置為晶體時(shí)鐘,晶體時(shí)鐘可能為24M或40M;

那么問題來了——晶體時(shí)鐘頻率到底是多少?

晶體時(shí)鐘頻率是多少?
可以通過實(shí)驗(yàn)測(cè)算出晶體時(shí)鐘頻率,具體步驟如下:

  1. 使用 hi_pwm_set_clock(PWM_CLK_XTAL); 設(shè)置時(shí)鐘源為晶體時(shí)鐘;
  2. 使用PwmStart(WIFI_IOT_PWM_PORT_PWM0, 20*1000, 40*1000);輸出方波信號(hào);
  3. 使用示波器測(cè)量方波頻率,根據(jù)測(cè)量的頻率計(jì)算時(shí)鐘源頻率;

經(jīng)實(shí)際測(cè)量,方波頻率為1000Hz,

因此,時(shí)鐘頻率為 1000 * 40 * 1000,即 40 MHz;
可以輸出的方波最低頻率
因此,方波最低頻率就是 40M / 65535 ,也就是:

>>> 40 * 1000 * 1000 / 65535
610.3608758678569
對(duì)照上面的頻率表,可以知道,能夠輸出E5及以上的所有音符;

準(zhǔn)備曲譜
為了代碼實(shí)現(xiàn)起來簡(jiǎn)單,我選擇了《兩只老虎》的曲譜作為素材,在簡(jiǎn)譜網(wǎng)找到了簡(jiǎn)譜:
 兩只老虎 簡(jiǎn)譜

簡(jiǎn)譜說明
簡(jiǎn)譜上的一些記號(hào),有的同學(xué)可能不太清楚是什么意思,這里簡(jiǎn)單說明一下:

  1. 左上角的1=C是表示調(diào)式(可以不用關(guān)心),1是唱名,C是音名,1=C是正調(diào)(就是常規(guī)的對(duì)應(yīng)關(guān)系: 1-C,2-D, 3-E, 4-F, 5-G, 6-A, 7-B);
  2. 左上角的 4/4 是四四拍,是指 四分音符為一拍, 每小節(jié)有四拍;
  3. 下面譜子上的豎線就是每個(gè)小節(jié)分隔符,和4/4對(duì)應(yīng);
  4. “跑得快”上面5后面的橫線表示延時(shí)一拍;
  5. “一只沒有眼睛”一句,5后面的點(diǎn)表示順延半拍,一條下劃線表示二分之一時(shí)間,兩條下劃線表示四分之一時(shí)間;
    編寫代碼
    有了以上知識(shí),我們就可以編寫代碼了,關(guān)鍵代碼如下:
  1. static const uint16_t g_tuneFreqs[] = { // 音符對(duì)應(yīng)的分頻系數(shù) 
  2.     0, // 40M Hz 時(shí)鐘源,C6 ~ B6: 
  3.     38223, // 1 1046.5 
  4.     34052, // 2 1174.7 
  5.     30338, // 3 1318.5 
  6.     28635, // 4 1396.9 
  7.     25511, // 5 1568 
  8.     22728, // 6 1760 
  9.     20249, // 7 1975.5 
  10.     51021 // 5_ 783.99 // 低一個(gè)八度的 5 
  11. }; 
  12.  
  13. // 曲譜音符 
  14. static const uint8_t g_scoreNotes[] = { 
  15.     // 《兩只老虎》簡(jiǎn)譜:http://www.jianpu.cn/pu/33/33945.htm 
  16.     1, 2, 3, 1,        1, 2, 3, 1,        3, 4, 5,  3, 4, 5, 
  17.     5, 6, 5, 4, 3, 1,  5, 6, 5, 4, 3, 1,  1, 8, 1,  1, 8, 1, // 最后兩個(gè) 5 應(yīng)該是低八度的,鏈接圖片中的曲譜不對(duì),聲音到最后聽起來不太對(duì)勁 
  18. }; 
  19.  
  20. // 曲譜時(shí)值,根據(jù)簡(jiǎn)譜記譜方法轉(zhuǎn)寫 
  21. static const uint8_t g_scoreDurations[] = { 
  22.     4, 4, 4, 4,        4, 4, 4, 4,        4, 4, 8,  4, 4, 8, 
  23.     3, 1, 3, 1, 4, 4,  3, 1, 3, 1, 4, 4,  4, 4, 8,  4, 4, 8, 
  24. }; 
  25.  
  26. static void *BeeperMusicTask(const char *arg) 
  27.     (void)arg; 
  28.  
  29.     printf("BeeperMusicTask start!\r\n"); 
  30.  
  31.     hi_pwm_set_clock(PWM_CLK_XTAL); // 設(shè)置時(shí)鐘源為晶體時(shí)鐘(40MHz,默認(rèn)時(shí)鐘源160MHz) 
  32.  
  33.     for (size_t i = 0; i < sizeof(g_scoreNotes)/sizeof(g_scoreNotes[0]); i++) { 
  34.         uint32_t tune = g_scoreNotes[i]; // 音符 
  35.         uint16_t freqDivisor = g_tuneFreqs[tune]; 
  36.         uint32_t tuneInterval = g_scoreDurations[i] * (125*1000); // 音符時(shí)間 
  37.         printf("%d %d %d %d\r\n", tune, (40*1000*1000) / freqDivisor, freqDivisor, tuneInterval); 
  38.         PwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor/2, freqDivisor); 
  39.         usleep(tuneInterval); 
  40.         PwmStop(WIFI_IOT_PWM_PORT_PWM0); 
  41.     } 
  42.  
  43.     return NULL; 

譜子中最后兩個(gè)5是錯(cuò)誤的,應(yīng)該是低八度的5,也就是5下面應(yīng)該打一個(gè)點(diǎn);我修改了代碼,讓整個(gè)曲子聽起來更自然;

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

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2019-01-23 16:07:54

數(shù)據(jù)倉庫Hadoop

2016-03-25 16:02:49

中國(guó)企業(yè)新聞網(wǎng)

2013-09-03 13:14:15

諾基亞Google

2023-12-29 13:25:22

AI模型

2010-04-30 14:33:56

HTML 5FlashH.264

2011-09-21 11:28:03

HTCWindows 8平板電腦

2009-04-14 15:30:25

2015-08-19 09:53:17

技術(shù)電商創(chuàng)業(yè)

2017-12-01 05:11:52

2024-08-12 09:52:00

2012-12-04 17:13:21

2018-01-10 10:45:37

2021-12-03 15:04:06

FlatpakLinux

2021-06-29 06:39:21

Linuxdust命令du命令

2023-05-11 13:55:00

LinuxKdenlive編輯視頻

2022-01-09 15:00:16

LinuxAudacity聲音編輯器

2010-10-13 09:29:53

JUnit單元測(cè)試Android

2017-01-15 17:06:16

程序員藝術(shù)家

2009-05-26 16:08:38

網(wǎng)管軟件網(wǎng)絡(luò)拓?fù)?/a>摩卡

2009-08-18 11:16:05

Ubuntu系統(tǒng)高清視頻linux系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: av免费网站在线 | 成年视频在线观看福利资源 | 国产成人久久精品一区二区三区 | 国产福利在线播放 | 日韩在线中文字幕 | 一级毛片免费 | 午夜精品久久久久久久久久久久久 | 亚洲国产成人在线 | 久久久久久一区 | 日韩免费视频 | 亚洲欧美日韩精品 | 国产精品1区2区3区 男女啪啪高潮无遮挡免费动态 | 日日夜夜免费精品 | 成人免费高清 | 亚洲精品视频一区 | 亚洲欧美另类在线 | 午夜视频免费 | 国产激情视频 | 91视频在线看 | 色综合一区二区 | 精品一区欧美 | 最新中文字幕在线播放 | 九色.com | 中国一级特黄真人毛片免费观看 | 精品久久影院 | 国产高清一区二区三区 | 久久大陆 | 国产精品一区一区三区 | 久久国产亚洲 | www..99re| 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 久久这里有精品 | 久久国产精品99久久久大便 | 91成人 | 精品国产乱码久久久久久88av | 亚洲欧洲在线看 | 欧美8一10sex性hd | 亚洲精品成人网 | 欧美成人精品二区三区99精品 | 中文字幕在线国产 | 亚洲成人在线视频播放 |