本文介紹如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系統(tǒng)的PWM接口 驅(qū)動(dòng)蜂鳴器 播放音樂。
用PWM輸出方波
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)系
參考:https://liam.page/2018/04/09/pitch-interval-and-harmonic/
開發(fā)板可以輸出的最低頻率
通過前面的公式,我們知道:
PWM輸出的方波頻率和freq成反比,freq越大,輸出的方波頻率越?。?/p>
freq是unsinged short類型,最大值為65535;
因此,輸出頻率的最小值取決于時(shí)鐘源,PWM的默認(rèn)時(shí)鐘源為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); }
我們通過直接調(diào)用hi_pwm_set_clock接口,可以修改時(shí)鐘源:
/** *@ingroupiot_pwm * *EnumeratesthePWMclocksources.CNcomment:PWM時(shí)鐘源枚舉。CNend */typedefenum{ PWM_CLK_160M,/**160M?APB?clock.CNcomment:160M?工作時(shí)鐘?CNend?*/ ????PWM_CLK_XTAL,?/**24M/40M?crystal?clock.CNcomment:24M或40M?晶體時(shí)鐘?CNend?*/ ????PWM_CLK_MAX???/**通過注釋我們知道hi_pwm_set_clock(PWM_CLK_XTAL);可以將時(shí)鐘源設(shè)置為晶體時(shí)鐘,晶體時(shí)鐘可能為24M或40M;
那么問題來了——晶體時(shí)鐘到底是多少?晶體時(shí)鐘頻率是多少?
我們可以通過通過實(shí)驗(yàn),測(cè)算出晶體時(shí)鐘頻率,具體步驟如下:
使用hi_pwm_set_clock(PWM_CLK_XTAL);設(shè)置時(shí)鐘源為晶體時(shí)鐘;
使用PwmStart(WIFI_IOT_PWM_PORT_PWM0, 20*1000, 40*1000);輸出方波信號(hào);
使用示波器測(cè)量方波頻率;
經(jīng)實(shí)際測(cè)量,方波評(píng)率為1000Hz,因此,時(shí)鐘頻率為1000 * 40 * 1000也就是 40 MHz;可以輸出的方波最低頻率
因此,方波最低頻率就是 40M / 65535 ,也就是:
>>>40*1000*1000/65535 610.3608758678569對(duì)照上面的頻率表,可以知道,能夠輸出E?以上的所有音符;
準(zhǔn)備曲譜
為了代碼實(shí)現(xiàn)起來簡單,我選擇了《兩只老虎》的曲譜作為素材,很快找到了簡譜:
簡譜說明
對(duì)于缺乏音樂基礎(chǔ)的同學(xué),簡譜上的一些記號(hào)可能不太清楚是什么意思,這里簡單說明一下:
左上角的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);
左上角的 4/4 是四四拍,是指 四分音符為一拍, 每小節(jié)有四拍;
下面譜子上的豎線就是每個(gè)小節(jié)分隔符,和4/4對(duì)應(yīng);
“跑得快”上面5后面的橫線表示延時(shí)一拍;
“一直沒有眼睛”一句,5后面的點(diǎn)表示順延半拍,一條下劃線表示二分之一時(shí)間,兩條下劃線表示四分之一時(shí)間;
編寫代碼
有了以上知識(shí),我們就可以編寫代碼了,關(guān)鍵部分代碼如下:
staticvolatileintg_buttonPressed=0;staticconstuint16_tg_tuneFreqs[]={0,//40MHz對(duì)應(yīng)的分頻系數(shù): 38223,//11046.5 34052,//21174.7 30338,//31318.5 28635,//41396.9 25511,//51568 22728,//61760 20249,//71975.5 51021//5_783.99//第一個(gè)八度的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,//最后兩個(gè)5應(yīng)該是低八度的,鏈接圖片中的曲譜不對(duì),聲音到最后聽起來不太對(duì)勁};//曲譜時(shí)值,根據(jù)簡譜記譜方法轉(zhuǎn)寫,4/4拍中下面劃一條線是半拍,劃兩條線是四分之一拍,點(diǎn)是順延半拍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);//設(shè)置時(shí)鐘源為晶體時(shí)鐘(40MHz,默認(rèn)時(shí)鐘源160MHz) for(size_ti=0;i其中譜子最后兩個(gè)5是譜子的錯(cuò)誤,應(yīng)該是低八度的5,也就是5下面應(yīng)該打一個(gè)點(diǎn);我修改了代碼,讓整個(gè)曲子聽起來更自然;
編輯:hfy
-
有源無源蜂鳴器
+關(guān)注
關(guān)注
0文章
2瀏覽量
1225 -
鴻蒙
+關(guān)注
關(guān)注
60文章
2620瀏覽量
44058
發(fā)布評(píng)論請(qǐng)先 登錄
評(píng)論