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

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

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

[[350170]]

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

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

用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實際輸出的方波頻率等于 PWM時鐘源頻率 除以 分頻倍數(shù),即

f = Fcs / freq

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

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

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

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

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

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

  1. PWM輸出的方波頻率和freq成反比,freq越大,輸出的方波頻率越小;
  2. freq是unsinged short類型,最大值為65535;
    因此,輸出頻率的最小值取決于時鐘源,而PWM的默認時鐘源為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時鐘源條件下,輸出方波的最低頻率是:160M/65535=2441.44...,這個頻率還是略高,在上面的表格中沒有找到音名。但是我可以用上面表格值繼續(xù)往后推算兩個八度,就能夠覆蓋這個頻率(不過通常只使用7個八度,所以還是有點高)。

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

  1. /** 
  2.  * @ingroup iot_pwm 
  3.  * 
  4.  * Enumerates the PWM clock sources.CNcomment:PWM時鐘源枚舉。CNend 
  5.  */ 
  6. typedef enum { 
  7.     PWM_CLK_160M, /**< 160M APB clock.CNcomment:160M 工作時鐘 CNend */ 
  8.     PWM_CLK_XTAL, /**< 24M/40M crystal clock.CNcomment:24M或40M 晶體時鐘 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è)置為晶體時鐘,晶體時鐘可能為24M或40M;

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

晶體時鐘頻率是多少?
可以通過實驗測算出晶體時鐘頻率,具體步驟如下:

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

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

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

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

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

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

  1. 左上角的1=C是表示調(diào)式(可以不用關(guān)心),1是唱名,C是音名,1=C是正調(diào)(就是常規(guī)的對應(yīng)關(guān)系: 1-C,2-D, 3-E, 4-F, 5-G, 6-A, 7-B);
  2. 左上角的 4/4 是四四拍,是指 四分音符為一拍, 每小節(jié)有四拍;
  3. 下面譜子上的豎線就是每個小節(jié)分隔符,和4/4對應(yīng);
  4. “跑得快”上面5后面的橫線表示延時一拍;
  5. “一只沒有眼睛”一句,5后面的點表示順延半拍,一條下劃線表示二分之一時間,兩條下劃線表示四分之一時間;
    編寫代碼
    有了以上知識,我們就可以編寫代碼了,關(guān)鍵代碼如下:
  1. static const uint16_t g_tuneFreqs[] = { // 音符對應(yīng)的分頻系數(shù) 
  2.     0, // 40M Hz 時鐘源,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 // 低一個八度的 5 
  11. }; 
  12.  
  13. // 曲譜音符 
  14. static const uint8_t g_scoreNotes[] = { 
  15.     // 《兩只老虎》簡譜: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, // 最后兩個 5 應(yīng)該是低八度的,鏈接圖片中的曲譜不對,聲音到最后聽起來不太對勁 
  18. }; 
  19.  
  20. // 曲譜時值,根據(jù)簡譜記譜方法轉(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è)置時鐘源為晶體時鐘(40MHz,默認時鐘源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); // 音符時間 
  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; 

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

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

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

 

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

2019-01-23 16:07:54

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

2013-09-03 13:14:15

諾基亞Google

2016-03-25 16:02:49

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

2023-12-29 13:25:22

AI模型

2009-04-14 15:30:25

2010-04-30 14:33:56

HTML 5FlashH.264

2011-09-21 11:28:03

HTCWindows 8平板電腦

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單元測試Android

2017-01-15 17:06:16

程序員藝術(shù)家

2009-08-18 11:16:05

Ubuntu系統(tǒng)高清視頻linux系統(tǒng)

2009-05-26 16:08:38

網(wǎng)管軟件網(wǎng)絡(luò)拓撲摩卡
點贊
收藏

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

主站蜘蛛池模板: 特黄色一级毛片 | 欧美日韩专区 | 韩日在线 | 国产一区 在线视频 | 亚洲欧美在线观看 | 国产xxxx岁13xxxxhd | 亚洲欧美国产视频 | 亚洲网站在线播放 | 国产在线视频一区二区 | 久久久国产一区二区三区四区小说 | 亚洲精品乱码久久久久久按摩 | av在线天堂| 亚洲理论在线观看电影 | 日韩亚洲一区二区 | 一区二区三区在线观看视频 | 第四色播日韩第一页 | 激情一区二区三区 | av手机在线免费观看 | 97精品国产97久久久久久免费 | 一区二区福利视频 | 国产激情精品 | 888久久久| 美国十次成人欧美色导视频 | 性视频网 | 波多野结衣中文字幕一区二区三区 | 免费永久av | 欧美中文在线 | 久久99视频 | 欧美一区二区三区四区在线 | 成人综合在线视频 | 自拍视频精品 | 99精品视频一区二区三区 | 一二区电影 | av性色全交蜜桃成熟时 | 精品日韩 | 狠狠干狠狠操 | 亚洲一区二区三区 | 精品国产乱码久久久久久丨区2区 | 阿v视频在线观看 | 日本精品在线观看 | 日韩成人高清 |