本文介紹如何在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???/**通過注釋我們知道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其中譜子最后兩個5是譜子的錯誤,應該是低八度的5,也就是5下面應該打一個點;我修改了代碼,讓整個曲子聽起來更自然;
編輯:hfy
-
有源無源蜂鳴器
+關注
關注
0文章
2瀏覽量
1164 -
鴻蒙
+關注
關注
57文章
2363瀏覽量
42888
發布評論請先 登錄
相關推薦
評論