前言
本片我們使用PWM輸出不同頻率占空比的信號(hào)來驅(qū)動(dòng)喇叭,實(shí)現(xiàn)MIDI音樂播放器的Demo。
PWM驅(qū)動(dòng)喇叭原理
PWM驅(qū)動(dòng)喇叭有兩種方法
一種是PWM-ADC方法,即控制PWM占空比實(shí)現(xiàn)不同電壓等級(jí)的輸出,來模擬DAC的輸出;
一種是控制PWM頻率,直接播放數(shù)字MIDI音樂即不同頻率代表不同的音調(diào)。
我們這里采用第二種方式來實(shí)現(xiàn)音樂播放。
以國際標(biāo)準(zhǔn)音A-la-440HZ為準(zhǔn):
do的頻率為261.6HZ,
re的頻率為293.6HZ,
mi的頻率為329.6HZ,
fa的頻率為349.2HZ,
sol的頻率為392HZ,
la的頻率為440HZ,
si的頻率為493.8HZ。
我們升一個(gè)八度則
Do頻率為261.6x2=523.2Hz,其他的類推。
控制PWM頻率就可以輸出上述音調(diào),控制PWM占空比則可對(duì)應(yīng)聲音的大小,播放時(shí)間長度則可對(duì)應(yīng)音節(jié)時(shí)長。
以兩只老虎為例
播放音樂需要三個(gè)參數(shù)
頻率:beepfrep對(duì)應(yīng)音調(diào)
聲音大小: beepduty 占空比
播放時(shí)間: beeptime 對(duì)應(yīng)節(jié)拍
簡譜中可以看到
2/4拍子 4分音符一拍 每小節(jié)2拍
一分鐘76拍。
于是可以定義音調(diào)和上述參數(shù)如下
DO = 523
RE = 587
MI = 659
FA = 698
_SO = 392
SO = 784
LA = 880
SI = 987
NO = 523
DUTY0 = 0
METERS = 76 #拍數(shù)76 1分鐘76拍 每拍60/76秒
#2/4 4分音符一拍 每小節(jié)2拍
NOTE_4 = (60/METERS) #先定一拍對(duì)應(yīng)的音符 4分音符
NOTE_8 = (NOTE_4/2) # 8分音符 一個(gè)下劃線
NOTE_16 = (NOTE_8/2) # 16分音符 二個(gè)下劃線
beepfrep = [DO,RE,MI,DO,
DO,RE,MI,DO,
MI,FA,SO,NO,
MI,FA,SO,NO,
SO,LA,SO,FA,MI,DO,
SO,LA,SO,FA,MI,DO,
DO,_SO,DO,NO,
DO,_SO,DO,NO]
beepduty = [400,400,400,400,
400,400,400,400,
400,400,400,DUTY0,
400,400,400,DUTY0,
400,400,400,400,400,400,
400,400,400,400,400,400,
400,400,400,DUTY0,
400,400,400,DUTY0,
]
beeptime = [NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
]
代碼
完整代碼如下
import time
from machine import Pin, PWM
pwm = PWM(Pin(21))
DO = 523
RE = 587
MI = 659
FA = 698
_SO = 392
SO = 784
LA = 880
SI = 987
NO = 523
DUTY0 = 0
METERS = 76 #拍數(shù)76 1分鐘76拍 每拍60/76秒
#2/4 4分音符一拍 每小節(jié)2拍
NOTE_4 = (60/METERS) #先定一拍對(duì)應(yīng)的音符 4分音符
NOTE_8 = (NOTE_4/2) # 8分音符 一個(gè)下劃線
NOTE_16 = (NOTE_8/2) # 16分音符 二個(gè)下劃線
beepfrep = [DO,RE,MI,DO,
DO,RE,MI,DO,
MI,FA,SO,NO,
MI,FA,SO,NO,
SO,LA,SO,FA,MI,DO,
SO,LA,SO,FA,MI,DO,
DO,_SO,DO,NO,
DO,_SO,DO,NO]
beepduty = [400,400,400,400,
400,400,400,400,
400,400,400,DUTY0,
400,400,400,DUTY0,
400,400,400,400,400,400,
400,400,400,400,400,400,
400,400,400,DUTY0,
400,400,400,DUTY0,
]
beeptime = [NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
]
while(1):
for i in range(len(beepfrep)):
pwm.freq(beepfrep[i])
pwm.duty_u16(beepduty[i])
time.sleep(beeptime[i])
測試
接上喇叭,這里使用了功放
PWM使用P21
運(yùn)行程序
可以聽到演奏的效果,詳細(xì)見視頻。
-
播放器
+關(guān)注
關(guān)注
5文章
397瀏覽量
37409 -
編程
+關(guān)注
關(guān)注
88文章
3614瀏覽量
93685 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5032瀏覽量
97371 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68519 -
單板計(jì)算機(jī)
+關(guān)注
關(guān)注
0文章
74瀏覽量
15627 -
編譯
+關(guān)注
關(guān)注
0文章
657瀏覽量
32851 -
MIDI
+關(guān)注
關(guān)注
0文章
75瀏覽量
15657 -
ESP32
+關(guān)注
關(guān)注
18文章
971瀏覽量
17200
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論