俞海華 尹浙民 沈小玲 謝少偉
本文介紹一種用89C2051單片機(jī)設(shè)計(jì)的3位LED音樂隨機(jī)數(shù)據(jù)發(fā)生器,它在音樂播放的同時(shí)產(chǎn)生隨機(jī)數(shù)據(jù),其關(guān)鍵技術(shù)為在單片機(jī)音樂發(fā)生同時(shí)實(shí)現(xiàn)LED動(dòng)態(tài)數(shù)據(jù)顯示,可用于小型晚會(huì)抽獎(jiǎng)及點(diǎn)出節(jié)目助興。以下就其硬件原理、軟件編寫作一介紹,有興趣者不妨一試。
硬件設(shè)計(jì)
圖1為3位LED隨機(jī)數(shù)據(jù)發(fā)生器硬件電路。圖中C3、R1為上電復(fù)位電路,R2、K構(gòu)成按鍵電路,并由P3.0檢測(cè)按鍵狀態(tài)。由于89C2051的P1口能吸收20mA灌入電流并可直接驅(qū)動(dòng)LED顯示器,因此,圖中由P1.0~P1.6提供三位LED七段段線,分別對(duì)應(yīng)a~g,并通過7個(gè)200Ω電阻上拉接+5V電源,當(dāng)P1.0~P1.6口線輸出高電平時(shí),由+5V電源提供LED驅(qū)動(dòng)電流,當(dāng)P1.0~P1.6口線輸入低電平時(shí),+5V電源通過200Ω電阻,向P1.0~P1.6灌電流,并使LED段線處于低電平狀態(tài)。同樣,當(dāng)89C2051的P3口作為一般口線時(shí),P3口同樣能吸收20mA灌電流,因此直接采用P3.5、P3.4、P3.3控制LED1、LED2、LED3的位線,實(shí)現(xiàn)了用89C2051口線直接驅(qū)動(dòng)LED動(dòng)態(tài)顯示的可能。P3.7是音樂信號(hào)輸出口線,同樣采用灌電流的方式通過9013電流放大驅(qū)動(dòng)8Ω喇叭以實(shí)現(xiàn)音樂播放。
軟件設(shè)計(jì)
本隨機(jī)數(shù)據(jù)發(fā)生器的工作過程如下:開機(jī)后,處于待機(jī)狀態(tài),當(dāng)K按下并釋放后,音樂響起并循環(huán)播放,同時(shí),3位LED快速循環(huán)顯示0~9數(shù)字,隨機(jī)數(shù)據(jù)寄存器從1到最高值(最大可到999)加1循環(huán)。一旦K再次按下并釋放后,音樂停播,同時(shí)隨機(jī)數(shù)據(jù)寄存器循環(huán)加1并顯示,逐漸減慢并停止在某一值,但由于K再次按下是隨機(jī)的,因此這一值也為隨機(jī)值。當(dāng)K第三次按下時(shí)將再次處于待機(jī)狀態(tài),否則一直顯示隨機(jī)值。隨機(jī)數(shù)據(jù)發(fā)生器的程序即是按上述過程編寫的,其程序流程如圖2所示,主要由音樂發(fā)生、三位LED動(dòng)態(tài)顯示及隨機(jī)數(shù)據(jù)處理三個(gè)部分組成,圖中R2為中斷次數(shù)寄存器,R4為樂曲長(zhǎng)度寄存器,30H為隨機(jī)數(shù)據(jù)寄存器。
單片機(jī)音樂發(fā)聲原理是在一口線上產(chǎn)生音頻范圍內(nèi)的方波信號(hào),并經(jīng)放大驅(qū)動(dòng)喇叭便可發(fā)出某一頻率的音調(diào),控制音調(diào)播放時(shí)間使其按節(jié)拍變化,便可編程演奏一首樂曲。方波信號(hào)的頻率由定時(shí)器控制產(chǎn)生,采用16位定時(shí)方式。附表列出C調(diào)音階與頻率及初值的對(duì)應(yīng)關(guān)系。將初值制表在程序中,將音符作為偏移量查該表即可得音符對(duì)應(yīng)的初值。
節(jié)拍長(zhǎng)度由定時(shí)器T1控制,定時(shí)時(shí)間可取總節(jié)拍長(zhǎng)度的1/4或1/8,通過控制定時(shí)器的中斷次數(shù),即可滿足1/8、1/4、1/2、1、2拍等不同節(jié)拍的定時(shí)要求。將樂譜轉(zhuǎn)換成代碼,如音符、音長(zhǎng),組成一個(gè)字節(jié),如下處理便可播放音樂:
1.將音符代碼裝入8位字節(jié)高4位,節(jié)拍代碼裝入低4位,組成一個(gè)字節(jié),將整段音樂換成一定長(zhǎng)度的代碼并在程序中制表。
2.在程序執(zhí)行時(shí)先查代碼表,取出音符代碼,查頻率初值表將初值置入T0定時(shí)器,取節(jié)拍代碼,置入T1口定時(shí)中斷次數(shù)寄存器,啟動(dòng)T0、T1即可發(fā)音。
3.啟動(dòng)后T1每中斷一次,中斷次數(shù)寄存器減1,在主程序中加以判斷,一旦為零,結(jié)束該音節(jié)播放,取下一個(gè)音節(jié)代碼再按上述步驟處理,每一音節(jié)播放完畢,樂曲即音節(jié)長(zhǎng)度寄存器減1并判零,為零即樂曲結(jié)束,可作停播或重播處理。
在T1中斷次數(shù)寄存器判零等待期間,進(jìn)行隨機(jī)數(shù)據(jù)寄存器循環(huán)加1、LED1~LED3 0~9循環(huán)加1顯示及判鍵處理,必須注意的是處理時(shí)間不得超過T1定時(shí)時(shí)間,否則將影響節(jié)拍長(zhǎng)度控制。而在此間若K鍵按下,則音樂停播,進(jìn)行隨機(jī)數(shù)據(jù)循環(huán)加1顯示并逐漸減慢固定顯示在某一值,其流程圖如圖3所示。
圖中30H為隨機(jī)數(shù)據(jù)寄存器,33H為減慢顯示速度控制寄存器,32H為暫儲(chǔ)寄存器。
程序通過增加顯示同一隨機(jī)數(shù)據(jù)次數(shù)來減慢顯示速度,當(dāng)顯示次數(shù)與設(shè)定值相等時(shí)停止加1,并固定顯示隨機(jī)數(shù)據(jù)寄存器的內(nèi)容,此值即為產(chǎn)生的隨機(jī)數(shù)據(jù)。
程序中設(shè)有處理LED1~LED3分別顯示0~9的顯示子程序、顯示隨機(jī)數(shù)據(jù)寄存器內(nèi)容顯示子程序及T1、T2中斷服務(wù)等程序,不再詳述。
若隨機(jī)數(shù)據(jù)在0~255范圍,則只需一個(gè)8位隨機(jī)數(shù)據(jù)寄存器,如流程中的30H,若需顯示0~999,則需二個(gè)8位寄存器。另外在音樂停播時(shí),必須將音樂輸出口線P3.7置高電平,否將造成9013及喇叭長(zhǎng)期導(dǎo)通而發(fā)熱,這在程序調(diào)試時(shí)也得注意。
由于89C2051的工作電壓范圍較寬,可用3節(jié)5號(hào)電池提供4.5V 電壓供電。