單片機(jī)課程設(shè)計(jì)單片機(jī)演奏樂(lè)曲試驗(yàn)_第1頁(yè)
單片機(jī)課程設(shè)計(jì)單片機(jī)演奏樂(lè)曲試驗(yàn)_第2頁(yè)
單片機(jī)課程設(shè)計(jì)單片機(jī)演奏樂(lè)曲試驗(yàn)_第3頁(yè)
單片機(jī)課程設(shè)計(jì)單片機(jī)演奏樂(lè)曲試驗(yàn)_第4頁(yè)
單片機(jī)課程設(shè)計(jì)單片機(jī)演奏樂(lè)曲試驗(yàn)_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、單片機(jī)課程設(shè)計(jì)課程設(shè)計(jì)題目:?jiǎn)纹瑱C(jī)演奏樂(lè)曲試驗(yàn)課程設(shè)計(jì)組: 08電子信息工程姓名: 單片機(jī)演奏樂(lè)曲實(shí)驗(yàn)摘要:本文是應(yīng)用16f877a單片機(jī)原理和控制理論來(lái)設(shè)計(jì)音樂(lè)盒的硬件電路,并利用16單片機(jī)語(yǔ)言進(jìn)行程序設(shè)計(jì)。通過(guò)控制單片機(jī)內(nèi)部的定時(shí)器來(lái)產(chǎn)生不同頻率的方波,驅(qū)動(dòng)喇叭發(fā)出不同音調(diào)的音樂(lè),再利用延遲來(lái)控制發(fā)音時(shí)間的長(zhǎng)短。該程序通過(guò)把樂(lè)譜轉(zhuǎn)化成相應(yīng)的定時(shí)常數(shù)來(lái)驅(qū)動(dòng)發(fā)音設(shè)備演奏出悅耳動(dòng)聽(tīng)的音樂(lè)。這種控制電路結(jié)構(gòu)簡(jiǎn)單,可靠性高,應(yīng)用性強(qiáng);軟件程序適應(yīng)范圍廣,對(duì)于不同的音樂(lè)只需要改變相應(yīng)的定時(shí)常數(shù)即可。關(guān)鍵詞:16f877a單片機(jī) 匯編語(yǔ)言單片機(jī)控制電路的設(shè)計(jì)本設(shè)計(jì)中用到了16f877a單片機(jī),蜂鳴器。蜂

2、鳴器硬件電路控制如下圖音樂(lè)產(chǎn)生的方法:一首音樂(lè)是許多不同的音階組成的,而每個(gè)音階對(duì)應(yīng)著不同的頻率,這樣我們就可以利用不同的頻率的組合,即可構(gòu)成我們所想要的音樂(lè)了,當(dāng)然對(duì)于單片機(jī)來(lái)產(chǎn)生不同的頻率非常方便,我們可以利用單片機(jī)的定時(shí)/計(jì)數(shù)器t0來(lái)產(chǎn)生這樣方波頻率信號(hào),因此,我們只要把一首歌曲的音階對(duì)應(yīng)頻率關(guān)系弄正確即可?,F(xiàn)在以單片機(jī)12mhz晶振為例,例出高中低音符與單片機(jī)計(jì)數(shù)t0相關(guān)的計(jì)數(shù)值如下表4.1所示:表4.1高中低音符與單片機(jī)計(jì)數(shù)t0相關(guān)的計(jì)數(shù)值音符對(duì)應(yīng)的pr2值音符對(duì)應(yīng)的pr2值m_1119m_2105m_394m_579m_670h_159l_5158l_6141如表4.2所示:音樂(lè)的

3、音拍,一個(gè)節(jié)拍為單位(c調(diào))表4.2音樂(lè)的音拍曲調(diào)值delay曲調(diào)值delay調(diào)4/4125ms調(diào)4/462ms調(diào)3/4187ms調(diào)3/494ms調(diào)2/4250ms調(diào)2/4125ms對(duì)于不同的曲調(diào)我們也可以用單片機(jī)的另外一個(gè)定時(shí)/計(jì)數(shù)器來(lái)完成。發(fā)音部分代碼在程序中實(shí)現(xiàn),靠單片機(jī)的一個(gè)管腳輸出,考慮到聲音可能不夠大所以我們加入了功放電路,利用lm386來(lái)對(duì)聲音信號(hào)進(jìn)行放大。音頻輸出信號(hào)由adu out引出,信號(hào)可經(jīng)功放電路lm386輸出到揚(yáng)聲器或耳機(jī)。軟件流程圖程序代碼如下所示:;樂(lè)曲名:友誼天長(zhǎng)地久*;文件名“3.asm”;功能:單片機(jī)演奏樂(lè)曲實(shí)驗(yàn);*#include p16f877a.inc

4、 #define youyi 0x2100;樂(lè)譜編號(hào)#define l_5.158#definel_6.141#definem_1.119#definem_2.105#definem_3.94#definem_5.79#definem_6.70#defineh_1.59#definem_0.0; tone8=158,141,119,105,94,79,70,59;聲調(diào)的高低,實(shí)際上是pwm的周期值;計(jì)算方法是ccp的時(shí)鐘1mhz除以預(yù)分頻比16,再除以要產(chǎn)生的頻率,最后再減去1。portd_d equ 20h ;顯示緩沖器countcount1 equ 21hcount2 equ 22hcou

5、nt3 equ 23hcount4 equ 24hsavew equ 25h ;w保護(hù)寄存器saves equ 26h ;status保護(hù)寄存器count5 equ 27h ;節(jié)拍數(shù)h equ 28h ;地址寄存器hang equ 29h ;行寄存器lie equ 30h ;列寄存器tmp1 equ 31h ;tmp1緩存寄存器byte equ 32h ;緩存count6 equ 33h ;節(jié)拍數(shù)count7 equ 34h ;節(jié)拍數(shù)dd_ram_addrequ 35h ; 第一行顯示地址寄存器dd_ram_ul equ 36h ; 第二行顯示地址寄存器count equ 37hcount e

6、qu 38h ;計(jì)數(shù)寄存器count2 equ 39h;*;* 定義 lcd數(shù)據(jù)& 控制i/o口 ;*#definelcd_db7 portb,3 ;占用的i/o口定義 #definelcd_db6 portb,2 ;lcd的db6與rb2連接,其它類(lèi)推#definelcd_db5 portb,1 ;#definelcd_db4 portb,0 ;#define lcd_en portc,0#define lcd_rs portc,1#definelcd_db7_dirtrisb,3 ;對(duì)應(yīng)的方向寄存器定義#definelcd_db6_dirtrisb,2 ;#definelcd_db5_di

7、rtrisb,1 ;#definelcd_db4_dirtrisb,0 ;#definelcd_en_dirtrisc,0 ;#definelcd_rs_dirtrisc,1 ; ;*lcd 模塊命令*#definedisp_on0x00c ; 開(kāi)顯示#definedisp_on_c0x00e ; 開(kāi)顯示, 開(kāi)指針#definedisp_on_b0x00f ; 開(kāi)顯示, 開(kāi)指針,開(kāi)閃爍#definedisp_off0x008 ; 關(guān)顯示#defineclr_disp0x001 ; 清顯示的操作數(shù)#defineentry_inc0x006 ; 操作數(shù)#defineentry_inc_s0x007

8、 ; 操作數(shù)#defineentry_dec0x004 ; 操作數(shù)#defineentry_dec_s0x005 ; 操作數(shù);* org youyi de l_5,l_5,m_1,m_1,m_1,m_1,m_1,m_1,m_1,m_3,m_3,m_2,m_2,m_2,m_2de m_1,m_2,m_2,m_3,m_3,m_1,m_1,m_1,m_1,m_1,m_3,m_3,m_5,m_5,m_6de m_6,m_6,m_6,m_6,m_6,m_6,m_6,m_6,m_6,m_5,m_5,m_5,m_5,m_3,m_3de m_3,m_1,m_1,m_2,m_2,m_2,m_2,m_1,m_2,

9、m_2,m_3,m_3,m_1,m_1,m_1de m_1,l_6,l_6,l_6,l_5,l_5,m_1,m_1,m_1,m_1,m_1,m_1,m_1,m_1,m_6de m_6,m_5,m_5,m_5,m_5,m_3,m_3,m_3,m_1,m_1,m_2,m_2,m_2,m_2,m_1de m_2,m_2,m_6,m_6,m_5,m_5,m_5,m_5,m_3,m_3,m_3,m_5,m_5,m_6,m_6de m_6,m_6,m_6,m_6,m_6,m_6,h_1,h_1,m_5,m_5,m_5,m_5,m_3,m_3,m_3de m_1,m_1,m_2,m_2,m_2,m_2,m_

10、1,m_2,m_2,m_3,m_3,m_1,m_1,m_1,m_1de l_6,l_6,l_6,l_5,l_5,m_1,m_1,m_1,m_1,m_1,m_1,m_0,m_0,m_0,m_0;* org 0x000 nop ;空指令 goto main org 0x004 ;中斷入口 banksel savew movwf savew swapf status,w clrf status movwf saves ;中斷保護(hù) goto ccpint ;*table*table1 ;取第一行的顯示碼tmr2 count addwf pcl,1 ;地址偏移量加當(dāng)前pc值 retlw i ;t ret

11、lw n ;m retlw n ;r retlw o ;2 retlw v ;空格 retlw a ;空格 retlw t ;c retlw o ;o retlw r ;u retlw ;n retlw ;t retlw v ;n retlw 1 ;t retlw . ;n retlw 5 ;t retlw 00h;*table1*table ;取第二行顯示time: ms addwf pcl,1 ;地址偏移量加當(dāng)前pc值 retlw h ;t retlw e ;i retlw l ;m retlw l ;e retlw o ;: retlw ;空格 retlw p ;空格 retlw i ;

12、空格 retlw c ;空格 retlw ! ;空格 retlw 00h;*table2*table2 addwf pcl,1 retlw 30h ;0 retlw 31h ;1 retlw 32h ;2 retlw 33h ;3 retlw 34h ;4 retlw 35h ;5 retlw 36h ;6 retlw 37h ;7 retlw 38h ;8 retlw 39h ;9;*主程序開(kāi)始*main call lcd_dispay banksel trisd ;選擇體1 clrf trisd ;portd為輸出端口 movlw 07h ; movwf option_reg ;1:256

13、 banksel t1con clrf count5 movlw 30h ;分頻器為1:8,關(guān)閉tmr1 movwf t1con ; bcf pir1,tmr1if ;溢出標(biāo)志位清零 clrf tmr1h clrf tmr1l movlw 0xee ;設(shè)定tmr1低位初值 addwf tmr1l ; movlw 0x85 ;設(shè)定tmr1高位初值 addwf tmr1h ; bsf t1con,0 ;啟動(dòng)tmr1 banksel trisc ;跳到體1 bcf trisc,2 ;ccp1為輸出狀態(tài) banksel eeadr ;跳到體2 movlw youyi ;將地址存到w寄存器 movwf

14、eeadr ;將地址送入eeprom地址寄存器 banksel eecon1 ;選定bank3 bcf eecon1,eepgd ;選擇eeprom作為非易失性存儲(chǔ)器操作對(duì)象 bsf eecon1,rd ;啟動(dòng)一次讀eeprom的操作 banksel eedata ;跳到體2 movf eedata,w ;由于eeprom的讀出操作花費(fèi)的時(shí)間很短,此時(shí)eeprom banksel pr2 ;跳到體1 movwf pr2 ;將w的值存到pr2 banksel t2con ;跳到體0 movlw 0x07 ;預(yù)分頻1:16,后預(yù)分頻1:1 movwf t2con ;開(kāi)定時(shí)器2 movlw 0x0c

15、 ;將0x0c存到w寄存器 movwf ccp1con ;使用8位pwm方式 banksel pr2 ;跳到體1 movf pr2,0 ;將pr2值存到w寄存器 banksel ccpr1l ;跳到體0 movwf ccpr1l ;將w存到ccpr1l movlw b11111100 ;屏蔽低兩位 andwf ccpr1l,1 rrf ccpr1l,1 ;ccpr1l右移一位 rrf ccpr1l,1 ;ccpr1l右移一位 rrf ccpr1l,1 ;ccpr1l右移一位 banksel pie1 ;跳到體1 bsf pie1,tmr1ie ;啟動(dòng)tmr1中斷 bsf intcon,peie

16、 ;開(kāi)啟外設(shè)中斷 bsf intcon,gie ;開(kāi)啟全局中斷 banksel portd ;選擇體0 clrf portd movlw 01h ;顯示緩沖器賦初值 movwf portd_d loop ;call delay_500ms ;延時(shí)500ms ;rlf portd_d ;顯示緩沖器循環(huán)左移 goto loop ;等待中斷;*ccpint中斷子程序*ccpint btfss pir1,tmr1if ;判斷是否是tmr1中斷 goto jmp4 ;否,跳出中斷 bcf pir1,tmr1if ;是,清中斷標(biāo)志位 movlw 30h ;分頻器為1:8,關(guān)閉tmr1 movwf t1co

17、n ; clrf tmr1h ;清tmr1h clrf tmr1l ;清tmr1l movlw 0xee ;設(shè)定tmr1低位初值 addwf tmr1l ; movlw 0x85 ;設(shè)定tmr1高位初值 addwf tmr1h ; bsf t1con,0 ;啟動(dòng)tmr1 banksel eeadr ;跳到體2 movlw youyi ;將地址存到w寄存器 movwf eeadr ;將地址送入eeprom地址寄存器 banksel count5 ;跳到體0 movf count5,0 ;將count存到w寄存器 banksel eeadr ;跳到體2 addwf eeadr,1 ;eeadr=e

18、eadr+count banksel eecon1 ;選定bank3 bcf eecon1,eepgd ;選擇eeprom作為非易失性存儲(chǔ)器操作對(duì)象 bsf eecon1,rd ;啟動(dòng)一次讀eeprom的操作 banksel eedata ;跳到體2 movf eedata,w ;由于eeprom的讀出操作花費(fèi)的時(shí)間很短,此時(shí)eeprom banksel pr2 ;跳到體1 movwf pr2 ;將w存到pr2 banksel ccpr1l ;跳到體0 movwf ccpr1l ;將w存到ccpr1l movlw b11111100 ;將11111100存到w寄存器 andwf ccpr1l,

19、1 ;屏蔽低兩位 rrf ccpr1l,1 ;ccpr1l左移一位 rrf ccpr1l,1 ;ccpr1l左移一位 rrf ccpr1l,1 ;ccpr1l右移一位 movlw .149 ;將149存到w寄存器 subwf count5,0 ;w=count-149 btfss status,c ;判斷是否有借位 goto jmp1 ;有,跳到j(luò)mp1 goto jmp2 ;無(wú),跳到j(luò)mp2jmp1 incf count5,1 ;count=couint+1 goto jmp ;跳到j(luò)mpjmp2 clrf count5 ;count清零jmp movlw b00000000 ;送.0到w寄

20、存器 xorwf portd,0 ;判斷portd是否為0 btfss status,z goto jmp3 ;否,跳到j(luò)mp1 movf portd_d,0 ;是,將portd_d的值 movwf portd ;送到portd goto jmp4jmp3 clrf portd ;portd清零 bcf status,c ;清楚其他操作對(duì)c的影響 rlf portd_d ;顯示緩沖器循環(huán)左移 btfsc status,c goto jmp5 goto jmp4 jmp5 movlw 01h ;顯示緩沖器賦初值 movwf portd_d jmp4 swapf saves,w movwf sta

21、tus swapf savew,f swapf savew,w ;恢復(fù)中斷 retfie;*700ms延時(shí)子程序*delay_500ms movlw .5 movwf count3loop1 movlw d133 ;設(shè)置外部循環(huán)次數(shù) movwf count1 ;loop2 movlw d249 ;設(shè)置內(nèi)部循環(huán)次數(shù) movwf count2 ;loop3 decfsz count2 ,1 ;內(nèi)部循環(huán)變量自減1,為0則跳轉(zhuǎn) goto loop3 ; decfsz count1,1 ;外部循環(huán)變量自減1,為0則跳轉(zhuǎn) goto loop2 ; decfsz count3,1 ;外部循環(huán)變量自減1,為0

22、則跳轉(zhuǎn) goto loop1 ; return ;返回主程序;*lcd_dispay顯示子程序*lcd_dispay banksel h ;選擇體0 movlw 0xc0 ;lcd第二行首地址 movwf dd_ram_ul movlw 0x80 ;lcd第一行首地址 movwf dd_ram_addr call lcd_intf ;調(diào)lcd初始化子程序 movlw .0 ;第一行顯示tmr2 count movwf hang ;的位置 movlw .2 movwf lie call adress ;調(diào)地址轉(zhuǎn)換子程序 call set_cursor ;調(diào)設(shè)置光標(biāo)子程序 call display

23、 ;調(diào)第一行顯示子程序 movlw .1 ;第二行顯示time:xxxxms movwf hang ;的位置行和列 movlw .0 movwf lie call adress ;調(diào)地址轉(zhuǎn)換子程序 call set_cursor ;調(diào)設(shè)置光標(biāo)子程序 call display1 ;調(diào)第二行顯示子程序 ;call watch_change ;調(diào)watch_change子程序 movlw .1 ;設(shè)置時(shí)間顯示位置行和列 movwf hang movlw .7 movwf lie call adress ;調(diào)地址轉(zhuǎn)換子程序 call set_cursor ;調(diào)設(shè)置光標(biāo)子程序 ;call display

24、_watch ;調(diào)時(shí)間顯示子程序 return ;子程序返回;*lcd_intf初始化子程序* lcd_intf bsf status,rp0 ;bank 1 bcf status,rp1 ;初始化相關(guān)i/o引腳 bcf lcd_db7_dir bcf lcd_db6_dir bcf lcd_db5_dir bcf lcd_db4_dir bcf lcd_en_dir bcf lcd_rs_dir bcf status,rp0 ;bank 0 bcf lcd_rs bcf lcd_en ;清數(shù)據(jù)線(xiàn) movlw0x28 ;設(shè)置工作方式 callsendcmd ;四位數(shù)據(jù)總線(xiàn),兩行顯示,5x7點(diǎn)陣

25、字符 bsf lcd_en bcf lcd_en movlwdisp_on ;開(kāi)顯示 callsendcmd movlwentry_inc ;設(shè)置指針移動(dòng)方式 callsendcmd callclrlcd ;清屏 movlw 0x80 ;設(shè)定行值 call sendcmd return ;子程序返回;*adress地址轉(zhuǎn)換子程序*adress btfss hang,0 ;判斷行是否為1 goto j1 ;是,跳到j(luò)1 movf lie,0 ;否,將列值送到w寄存器 addwf dd_ram_ul,0 ;第二行首地址加上列值 goto j2j1 movf lie,0 ;將列值送到w寄存器 add

26、wf dd_ram_addr,0 ;第一行首地址加上列值 j2 movwf h ;將地址存到h寄存器 return ;子程序返回;*set_cursor設(shè)置光標(biāo)位置子程序* set_cursor banksel h movf h,0 ;設(shè)置光標(biāo)位置 call sendcmd movlw disp_on ; 開(kāi)顯示 call sendcmd return ;子程序返回;*display第一行顯示子程序*display clrf count ;清0查表偏移地址 write_a movfw count ;count值送到w寄存器 call table ;查表,顯示tmr2 count movwf t

27、mp1 ;送暫存器 incf count,1 ;偏移地址加1 movfw tmp1 ;tmp1值送到w寄存器 xorlw 00h ;判斷是否顯示完所有數(shù)據(jù) btfsc status,z ;(約定表格做后一個(gè)00h做為結(jié)束標(biāo)志) goto $+4 ;全部顯示完成 movfw tmp1 ;tmp1值送到w寄存器 call putclcd ;沒(méi)有顯示完,把當(dāng)前查表所得數(shù)據(jù)送lcd顯示 goto write_a ;調(diào)用顯示程序 return ;子程序返回;*display1第二行顯示子程序*display1 clrf count ;清0查表偏移地址 write2_a movfw count ;coun

28、t值送到w寄存器 call table1 ;查表,顯示time: ms movwf tmp1 ;送暫存器 incf count,1 ;偏移地址加1 movfw tmp1 ;tmp1值送到w寄存器 xorlw 00h ;判斷是否顯示完所有數(shù)據(jù) btfsc status,z ;(約定表格做后一個(gè)00h做為結(jié)束標(biāo)志) goto $+4 ;全部顯示完成 movfw tmp1 ;tmp1值送到w寄存器 call putclcd ;沒(méi)有顯示完,把當(dāng)前查表所得數(shù)據(jù)送lcd顯示 goto write2_a ;調(diào)用顯示程序 return ;子程序返回;*putclcd 將字符數(shù)據(jù)送入 lcd * ;* 本程序?qū)⒆址麛?shù)據(jù)分成了高半字節(jié)和低半字節(jié)分別輸入 ;* 先送入的是高半字節(jié) ;* putclcd bsf lcd_rs ;設(shè)置為送數(shù)據(jù)模式 movwf byte call write ;寫(xiě)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論