分享一個已驗證的多功能電子琴
單片機源程序如下:
- RS EQU P3.5
- RW EQU P3.6
- E EQU P3.7
- ORG 00H
- SJMP MAIN
- ORG 00BH
- MOV TH0,33H
- MOV TL0,34H
- CPL P3.4
- RETI
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ORG 001BH
- INC 3CH ;中斷服務,中斷計數器加1
- MOV TH1,#0D8H
- MOV TL1,#0EFH ;12M晶振,形成10毫秒中斷
- RETI
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ORG 30H
- MAIN : SETB P3.4 ;關閉揚聲器
- LCALL CSH1602 ;初始化1602
- MOV TMOD,#11H ;設置定時器0為工作模式1
- SETB EA ;開總中斷
- SETB ET0 ;開定時器0中斷
- HUANYING: MOV P1,#80H ;歡迎語顯示地址
- LCALL ENABLE
- MOV DPTR,#TAB_HY
- MOV 30H,#00
- LP: MOV A,30H
- MOVC A,@A+DPTR
- JZ KEY
- LCALL DELAY_100MS
- LCALL WRITE_1602
- INC 30H
- SJMP LP
- KEY: MOV P1,#01H ;清屏
- ACALL ENABLE
- MOV P1,#80H
- LCALL ENABLE
- MOV DPTR,#TAB_YANZHOU
- MOV 30H,#00
- LP7: MOV A,30H
- MOVC A,@A+DPTR
- JZ KEY_0
- LCALL WRITE_1602
- INC 30H
- SJMP LP7
- KEY_0: MOV P1,#0C0H ;音符的顯示地址
- LCALL ENABLE
- MOV 38H,#16 ;寫入1602的顯示地址指針
- MOV 35H,#2 ;控制節拍
- KEY_1: MOV P2,#0FFH ;置P2為輸入
- JB P2.0,KEY_2 ;K1鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.0,$
- MOV 36H,#0 ;裝入1的音符碼相對地址
- LCALL BOFANG_YF
- KEY_2:
- JB P2.1,KEY_3 ;K2鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.1,$
- MOV 36H,#2
- LCALL BOFANG_YF
- KEY_3:
- JB P2.2,KEY_4 ;K3鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.2,$
- MOV 36H,#4
- LCALL BOFANG_YF
- KEY_4:
- JB P2.3,KEY_5 ;K4鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.3,$
- MOV 36H,#6
- LCALL BOFANG_YF
- KEY_5:
- JB P2.4,KEY_6 ;K5鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.4,$
- MOV 36H,#8
- LCALL BOFANG_YF
- KEY_6:
- JB P2.5,KEY_7 ;K6鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.5,$
- MOV 36H,#10
- LCALL BOFANG_YF
- KEY_7:
- JB P2.6,KEY_9 ;K7鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.6,$
- MOV 36H,#12
- LCALL BOFANG_YF
- KEY_9:
- JB P3.2,KEY_1 ;K9鍵沒按下,重新掃描
- LCALL DELAY_10MS ;延時消抖
- JNB P3.2,$
- LCALL DELAY_10MS
- ;-----------播放音樂程序段---------------
- MOV P1,#01H ;清屏
- ACALL ENABLE
- MOV P1,#80H
- LCALL ENABLE
- MOV DPTR,#TAB_PLAY
- MOV 30H,#00
- LP8: MOV A,30H
- MOVC A,@A+DPTR
- JZ PLAY
- LCALL WRITE_1602
- INC 30H
- SJMP LP8
- PLAY: MOV P2,#0FFH ;置P2為輸入
- JB P2.0,PLAY_2 ;K1鍵沒按下,轉移
- MOV DPTR,#TAB_GEQU1 ;存曲目標志
- LCALL BOFANG_GEQU
- PLAY_2:
- JB P2.1,PLAY_3 ;K2鍵沒按下,轉移
- SETB ET1
- MOV 3BH,TMOD
- MOV TMOD,#11H
- mov dptr,#tab2
- mov p1,#0c0h
- lcall enable
- lcall write1
- MOV DPTR,#DAT2
- LCALL MUSIc0
- CLR TR1
- CLR ET1
- MOV TMOD,3BH
- PLAY_3:
- JB P2.2,PLAY_4 ;K3鍵沒按下,轉移
- SETB ET1
- MOV 3BH,TMOD
- MOV TMOD,#11H
- mov dptr,#tab1
- mov p1,#0c0h
- lcall enable
- lcall write1
- MOV DPTR,#DAT1
- LCALL MUSIc0
- CLR TR1
- CLR ET1
- MOV TMOD,3BH
- PLAY_4:
- JB P2.3,PLAY_9
- MOV R1,#50H
- LCALL BOFANG_LUYIN
- PLAY_9: JB P3.2,PLAY ;K8鍵沒按下,重新掃描
- LCALL DELAY_10MS ;延時消抖
- JNB P3.2,$
- LCALL DELAY_10MS
- ;------------錄音程序段---------------
- MOV P1,#01H ;清屏
- ACALL ENABLE
- MOV P1,#80H
- LCALL ENABLE
- MOV DPTR,#TAB_RECORD
- MOV 30H,#00
- LP9: MOV A,30H
- MOVC A,@A+DPTR
- JZ RECORD_0
- LCALL WRITE_1602
- INC 30H
- SJMP LP9
- RECORD_0: MOV R1,#50H ;錄取音符存放地址
- MOV 35H,#3 ;控制節拍
- MOV P1,#0C0H ;音符的顯示地址
- LCALL ENABLE
- MOV 38H,#16 ;寫入1602的顯示地址指針
- ;---------寫入錄音的名字---------
- MOV 30H,#00
- C5: MOV A,30H
- LCALL TAB_RECORDING
- MOV @R1,A
- INC R1
- INC 30H
- CJNE A,#0FEH,C5
- RECORD_1: MOV P2,#0FFH ;置P2為輸入
- JB P2.0,RECORD_2 ;K1鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.0,$
- MOV 36H,#0 ;裝入1的音符碼相對地址
- LCALL BOFANG_YF
- LCALL CUNCU ;調存音符子程序
- RECORD_2:
- JB P2.1,RECORD_3 ;K2鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.1,$
- MOV 36H,#2
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_3:
- JB P2.2,RECORD_4 ;K3鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.2,$
- MOV 36H,#4
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_4:
- JB P2.3,RECORD_5 ;K4鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.3,$
- MOV 36H,#6
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_5:
- JB P2.4,RECORD_6 ;K5鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.4,$
- MOV 36H,#8
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_6:
- JB P2.5,RECORD_7 ;K6鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.5,$
- MOV 36H,#10
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_7:
- JB P2.6,RECORD_8 ;K7鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.6,$
- MOV 36H,#12
- LCALL BOFANG_YF
- LCALL CUNCU
- RECORD_8:
- JB P2.7,RECORD_9 ;K8鍵沒按下,轉移
- LCALL DELAY_10MS ;延時消抖
- JNB P2.7,$
- MOV 36H,#42 ;休止符標志存36H
- LCALL DELAY_100MS
- LCALL CUNCU
- RECORD_9:
- JNB P3.2,J0 ;K8鍵沒按下,重新掃描
- LJMP RECORD_1
- J0: LCALL DELAY_10MS ;延時消抖
- JNB P3.2,$
- LCALL DELAY_10MS
- MOV @R1,#255 ;寫入歌曲結束標志
- LJMP KEY ;回演奏模式
- ;***********子程序區***************
- ;=======初始化1602顯示器========
- CSH1602: MOV P3,#0FFH
- MOV P1,#01H
- ACALL ENABLE
- MOV P1,#38H
- ACALL ENABLE
- MOV P1,#0CH
- ACALL ENABLE
- MOV P1,#06H
- ACALL ENABLE
- RET
- ;====1602發命令子程序====
- ENABLE: CLR RS
- CLR RW
- CLR E
- ACALL DELAY_2MS
- SETB E
- RET
- ;=====讀1602IR中命令子程序======
- ENABLE_1: CLR RS
- SETB RW
- CLR E
- ACALL DELAY_2MS
- SETB E
- RET
- ;====寫數據子程序(1602)====
- WRITE_1602: MOV P1,A
- SETB RS
- CLR RW
- CLR E
- MOV R5,#50 ;延時100us(12M晶振)
- DJNZ R5,$
- SETB E
- RET
- ;===========播放一個音符并顯示音符和頻譜=========
- BOFANG_YF: MOV A,36H
- LCALL TAB_YF
- MOV 33H,A
- MOV A,36H
- INC A
- LCALL TAB_YF
- MOV 34H,A
- MOV TH0,33H
- MOV TL0,34H
- SETB TR0 ;啟動定時器0
- MOV A,36H ;取音符的顯示碼
- LCALL TAB_YF1
- LCALL WRITE_1602
- DEC 38H
- MOV A,36H
- INC A
- LCALL TAB_YF1
- LCALL WRITE_1602
- DJNZ 38H,D2 ;1602一行沒寫滿,轉移
- MOV 30H,#16 ;1602滿行清行并從頭開始寫
- MOV P1,#0C0H
- LCALL ENABLE
- MOV A,#' '
- LP10: LCALL WRITE_1602
- DJNZ 30H,LP10
- MOV 38H,#16
- MOV P1,#0C0H
- LCALL ENABLE
- ;----------顯示頻譜分析條程序段----------
- D2: MOV A,36H ;音符碼轉換為相應鍵值
- MOV B,#2
- DIV AB
- ADD A,#1
- MOV 39H,A
- MOV 3AH,39H ;保護音符碼對應的鍵值
- MOV P1,#85H ;設定頻譜分析條顯示初地址
- LCALL ENABLE
- MOV A,#'>'
- D5: LCALL WRITE_1602
- DJNZ 39H,D5
- ;--------控制節拍時長程序段---------
- MOV 37H,35H ;保護循環次數控制(節拍)
- LP1: ACALL DELAY_100MS
- DJNZ 35H,LP1 ;延時次數控制
- MOV 35H,37H
- ;---------發音結束,清除頻譜分析條------------
- MOV P1,#85H ;頻譜分析條顯示的初地址
- LCALL ENABLE
- MOV A,#' '
- MOV 39H,3AH
- D6: LCALL WRITE_1602
- DJNZ 39H,D6
- MOV A,#10H ;釋放音符碼顯示地址
- CLR C
- SUBB A,38H
- ADD A,#0C0H
- MOV P1,A
- LCALL ENABLE
- CLR TR0 ;關定時器0
- RET
- ;===========播放一個音符并顯示頻譜=========
- BOFANG_YF_1: MOV A,36H
- LCALL TAB_YF
- MOV 33H,A
- MOV A,36H
- INC A
- LCALL TAB_YF
- MOV 34H,A
- MOV TH0,33H
- MOV TL0,34H
- SETB TR0 ;啟動定時器0
- ;----------顯示頻譜分析條程序段----------
- MOV A,36H ;音符碼轉換為相應鍵值
- MOV B,#2
- DIV AB
- ADD A,#1
- MOV 39H,A
- MOV 3AH,39H ;保護音符碼對應的鍵值
- MOV P1,#85H ;設定頻譜分析條顯示初地址
- LCALL ENABLE
- MOV A,#'>'
- D7: LCALL WRITE_1602
- DJNZ 39H,D7
- ;--------控制節拍時長程序段---------
- MOV 37H,35H ;保護循環次數控制(節拍)
- LP11: ACALL DELAY_100MS
- DJNZ 35H,LP11 ;延時次數控制
- MOV 35H,37H
- ;---------發音結束,清除頻譜分析條------------
- MOV P1,#85H ;頻譜分析條顯示的初地址
- LCALL ENABLE
- MOV A,#' '
- MOV 39H,3AH
- D8: LCALL WRITE_1602
- DJNZ 39H,D8
- CLR TR0 ;關定時器0
- RET
- ;============播放一首歌并顯示歌名=============
- ;------(一個音符2字節存儲,音符碼存低字節,節拍存高字節;254為歌曲名結束標志,255為歌曲結束標志)----------
- BOFANG_GEQU: MOV P1,#0C0H ;歌名顯示地址
- LCALL ENABLE
- MOV 30H,#00
- LP2: MOV A,30H
- MOVC A,@A+DPTR
- INC 30H
- CJNE A,#254,XIANSHI_GEMING
- SJMP C1
- XIANSHI_GEMING: MOV P1,A
- LCALL WRITE_1602
- SJMP LP2
- C1: MOV P1,#0C0H ;歌詞顯示地址
- LCALL ENABLE
- LP3: MOV A,30H
- MOVC A,@A+DPTR ;取音符碼
- CJNE A,#0FFH,C6
- SJMP S0
- C6: CJNE A,#42,C0 ;音符碼為休止符不開定時器,直接調用延時
- INC 30H
- MOV A,30H
- MOVC A,@A+DPTR
- INC 30H
- MOV 35H,A
- LP12: LCALL DELAY_100MS
- DJNZ 35H,LP12
- SJMP LP3
- C0: MOV 36H,A
- INC 30H
- MOV A,30H
- MOVC A,@A+DPTR
- MOV 35H,A
- INC 30H
- LCALL BOFANG_YF_1
- SJMP LP3
- S0: RET
- ;============播放一錄音并顯示歌名和歌詞=============
- ;------(一個音符2字節存儲,音符碼存低字節,節拍存高字節;254為歌曲名結束標志,255為歌曲結束標志)----------
- BOFANG_LUYIN: MOV P1,#0C0H ;歌名顯示地址
- LCALL ENABLE
- LP4: MOV A,@R1
- INC R1
- CJNE A,#254,XIANSHI_LUYIN
- SJMP C2
- XIANSHI_LUYIN: MOV P1,A
- LCALL WRITE_1602
- SJMP LP4
- C2: MOV P1,#0C0H ;歌詞顯示地址
- LCALL ENABLE
- LP5: MOV A,@R1 ;取音符碼
- CJNE A,#255,C3
- SJMP S2
- C3: CJNE A,#42,C4 ;音符碼為休止符不開定時器,直接調用延時
- INC R1
- MOV A,@R1
- MOV 35H,A
- INC R1
- LP6: LCALL DELAY_100MS
- DJNZ 35H,LP6
- SJMP LP5
- C4: MOV 36H,A
- INC R1
- MOV A,@R1
- MOV 35H,A
- INC R1
- LCALL BOFANG_YF_1
- SJMP LP5
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
完整代碼:
電子琴.rar
(67.51 KB, 下載次數: 18)
2021-5-13 12:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|