分享一个已验证的多功能电子琴
单片机源程序如下:
- 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)
|