你可以参考下这个吧,希望对你有帮助
基于单片机的电子琴设计.rar (699.15KB)
等待一下,选择“Click here to Download”
电子琴,是供人弹奏的。
电子琴,不会播放乐曲。
参考。
;R5音调延时值;R6从内存中读到的数据
;9H--TABLE1~11数据;20H--TL1初值;21H--TH1初值;22H--修正后的按键值;30H--TABLE1~11地址计数器
;0AH--弹奏音调延时值;0BH--内存地址;0CH--读写到内存的数据;0DH--按键值;0EH--内存器件地址
PORT1 EQU P1
PORT2 EQU P2
SCK BIT P3.0
SDA BIT P3.1
ORG 0H
SJMP MAIN
ORG 0BH
LJMP TIME0
ORG 1BH
LJMP TIME1
ORG 30H
;--------------------------------------------------------------------------
MAIN: CLR TR0
CLR TR1
MOV SP,#4FH
MOV R0,#100
CLR P3.4
LCALL DELAY5
MOV 9H,#0
MOV 0AH,#0
MOV 0BH,#0
MOV 0CH,#0
MOV TMOD,#11H
MOV IE,#8AH
MOV 0DH,#88H
;------------扫描放歌和弹奏建------------------------------------
XIAN: JB P3.2,QT1 ;没按下放歌建跳qt1
SETB P3.4 ;按下放歌建LED发光
LCALL DELAY1
LCALL DELAY1
JNB P3.2,$ ;放歌建没释放原地等待
LCALL DELAY1
LCALL DELAY1
Q1: LCALL SAO
CJNE R0,#0,Q11
SJMP Q1
Q11: LCALL TRANF
JZ MAIN
MOV 0DH,A ;0DH=按键值
LJMP SING0
QT1: JB P3.3,QT4 ;没按弹奏建跳QT3
SETB P3.4
LCALL DELAY1
LCALL DELAY1
JNB P3.3,$ ;弹奏键没释放原地等待
LCALL DELAY1
LCALL DELAY1
QT2: LCALL SAO
CJNE R0,#0,QT3
SJMP QT2
QT3: LCALL TRANF
CJNE A,#0BH,QT11 ;若按键值=11转(B键)MAIN;!=11键转QT11
LJMP MAIN
QT11: JC MAIN ;若按键值11转MAIN;11继续
CJNE A,#0CH,M4 ;若按键值!=12转M1;=12(C键)继续 ;即C键没按下转M1
MOV PORT1,#11101111B
JNB P1.3,$ ;若C键没释放原地等待
MOV 0BH,#0
LJMP LOOP ;输入乐曲存储并演奏
M4: LCALL DELAY1
LCALL DELAY1
LCALL RWX80 ;擦写内存数据;全部为1
LJMP MAIN
QT4: LJMP XIAN ;返回重新扫描放歌和弹奏建
;--------------------------------------------------------------------------
RWX80: CJNE A,#0DH,MM2 ;A!=13(D键)转M2;若为D键继续;D键没按下转M2
MOV 0EH,#0A2H ;0EH=162=10100010B;0EH为24c16页地址
SJMP MM
MM2: CJNE A,#0EH,MM3 ;A!=14(E键)转M3;E键没按下转M3
MOV 0EH,#0A4H ;0EH=164=10100100B
SJMP MM
MM3: MOV 0EH,#0A6H ;F键按下;0EH=166=10100110B
MM: MOV 0BH,#0
MOV 0CH,#0H
RWX801: LCALL RKX02
LCALL WKX02
INC 0BH
INC 0BH
INC 0BH
INC 0BH
MOV A,0BH
CJNE A,#0FFH,MM4
MOV 0BH,#0
MM4: INC 0CH
INC 0CH
INC 0CH
INC 0CH
CJNE A,#0H,RWX801
RET
;--------读数据------------------------------
RKX02:
LCALL START
MOV A,#0A0H ;24C16寻址10100000写
LCALL WRBYT
LCALL TACK
MOV A,0BH ;发送24c16子地址
LCALL WRBYT
LCALL TACK
LCALL START
MOV A,#0A1H ;24C16寻址10100001读
LCALL WRBYT
LCALL TACK
;LCALL WRBYT
;LCALL TACK
MOV 10H,R6
LCALL RDBYT
LCALL NOTACK
;LCALL WRBYT
;LCALL TACK
MOV 11H,R6
LCALL RDBYT
LCALL NOTACK
;LCALL WRBYT
;LCALL TACK
MOV 12H,R6
LCALL RDBYT
LCALL TACK
MOV 13H,R6
LCALL NOTACK
LCALL STOP
RET
;---------写数据-----------------------
WKX02:
MOV R1,#10H
LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
MOV A,0CH
LCALL WRBYT
LCALL TACK
MOV R0,#4
WKX021: MOV A,@R1
LCALL WRBYT
LCALL TACK
INC R1
DJNZ R0,WKX021
LCALL STOP
LCALL DELAY5
LCALL DELAY5
RET
;-------输入乐曲存储并演奏--------------------------------------------
LOOP: CLR TR0
CLR TR1
AAA: JB P3.3,LOOP4 ;弹奏键按下 向下执行存储乐曲并演奏 否则转LOOP4继续输入乐曲
LCALL DELAY1
LCALL DELAY1
MOV 0CH,#0
LCALL WBAY ;存00结束乐谱
LCALL DELAY1
MOV 0DH,#12
LJMP SING0 ;播放弹奏的乐曲
LOOP4: LCALL SAO
CJNE R0,#0,KEYIN
LJMP LOOP
KEYIN: LCALL TRANF
SWAP A
MOV 09H,A
SWAP A
CJNE A,#0,ZZZ ;非0键转ZZZ
CLR TR1
CLR TR0
LJMP ZZZZ ;0键转ZZZZ
ZZZ: DEC A ;A为按键值;因从1键值音调序号对应TABLE频率表0位置;故减1
MOV 22H,A ;22H存修正后(A=A-1)的按键值
CLR C
RLC A ;A*2因TABLE一个单元为2字节(1字),指向该单元的第1个字节
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV TH1,A ;TH1赋初值
MOV 21H,A ;TH1初值存21H
MOV A,22H
CLR C
RLC A ;A*2因TABLE一个单元为2字节(1字)
INC A ;指向该单元的第2个字节
MOVC A,@A+DPTR
MOV TL1,A ;TL1赋初值
MOV 20H,A ;TL1初值存20H
MOV TH0,#0C2H
MOV TL0,#0F6H
SETB TR0
SETB TR1
ZZZZ: MOV A,PORT1
ORL A,#0F0H
CJNE A,#0FFH,ZZZZ
CLR TR0
CLR TR1
MOV A,0AH ;弹奏乐谱频率延迟值赋A
CLR C
RRC A
CLR C
RRC A
CLR C
RRC A ;弹奏乐谱频率延迟值/8
CJNE A,#0FH,NODE
SJMP DDD
NODE: JC DDD
MOV A,#0FH ;弹奏乐谱频率延迟值/8后;若15则=15
DDD: ORL 09H,A ;
MOV 0AH,#0
WWW:nbsp; MOV A,09H
MOV 0CH,A
LCALL WBAY
LCALL DELAY5
INC 0BH
LJMP LOOP
;-----频率延时-----------------------------------------
DELAY: MOV R7,#125
DLY2: MOV R4,#02
DLY3: MOV R3,#248
DJNZ R3,$
DJNZ R4,DLY3
DJNZ R7,DLY2
DJNZ R5,DELAY
RET
;---------延时----------------------
DELAY1: MOV R7,#30
MOV R6,#0
S1: DJNZ R6,$
DJNZ R7,S1
RET
DELAY5: MOV R7,#10
MOV R6,#0
S5: DJNZ R6,$
DJNZ R7,S5
RET
;-----扫描按键子程序----------
SAO: MOV R0,#4
MOV R3,#11101111B
MOV R2,#11111111B
NLINE1: MOV A,R3
MOV PORT1,A
MOV A,PORT1
ORL A,#0F0H
CJNE A,#0FFH,KEYIN1
MOV A,R3
RL A
MOV R3,A
DJNZ R0,NLINE1
RET
KEYIN1: LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
LCALL NOPEN
RET
;-----按键延时-------------
NOPEN: MOV A,PORT1
MOV R2,A
ORL A,#0F0H
CJNE A,#0FFH,NOPEN1
SJMP NOPEN
NOPEN1: LCALL DELAY1
LCALL DELAY1
RET
;----------键盘码转换为按键值-----------------
TRANF: MOV B,#0
MOV A,R2
C1: RRC A
JNC C2 ;C=0跳C2
INC B
INC B
INC B
INC B ;B=B+4
LJMP C1
C2: MOV A,R2
RR A
RR A
RR A
RR A
C3: RRC A
JNC C4
INC B
LJMP C3
C4: MOV A,B ;B为按键值
RET
;---------按键值散转表-------------------
SING0:
MOV 30H,#00H ;30H为TABLE1~11地址计数器
NEXT: MOV A,0DH
CJNE A,#1,NN1
MOV DPTR,#TABLE1
LJMP WW
NN1: CJNE A,#2,NN2
MOV DPTR,#TABLE2
LJMP WW
NN2: CJNE A,#3,NN3
MOV DPTR,#TABLE3
LJMP WW
NN3: CJNE A,#4,NN4
MOV DPTR,#TABLE4
LJMP WW
NN4: CJNE A,#5,NN5
MOV DPTR,#TABLE5
LJMP WW
NN5: CJNE A,#6,NN6
MOV DPTR,#TABLE6
LJMP WW
NN6: CJNE A,#7,NN7
MOV DPTR,#TABLE7
LJMP WW
NN7: CJNE A,#8,NN8
MOV DPTR,#TABLE8
LJMP WW
NN8: CJNE A,#9,NN9
MOV DPTR,#TABLE9
LJMP WW
NN9: CJNE A,#10,NN10
MOV DPTR,#TABLE10
LJMP WW
NN10: CJNE A,#11,NN11
MOV DPTR,#TABLE11
LJMP WW
NN11: CJNE A,#12,NN12
MOV 0EH,#0A1H
MOV 0BH,#0
LJMP NN
NN12: CJNE A,#13,NN13
;MOV 0EH,#0A3H
;MOV 0BH,#0H
LJMP MAIN
NN13: CJNE A,#14,NN14
;MOV 0EH,#0A5H
;MOV 0BH,#0H
LJMP MAIN
NN14: CJNE A,#15,NN
;MOV 0EH,#0A7H
;MOV 0BH,#00H
LJMP MAIN
;--------------------------------
NN: LCALL RBAY ;读内存
NNT: MOV A,R6 ;R6为从内存中读到的数据
LJMP IIC
;-----------奏乐--------------------------------------------
WW: MOV A,30H
JZ WW0
MOVC A,@A+DPTR
SJMP IIC
WW0: MOVC A,@A+DPTR
MOV 30H,#1
MOV 31H,A
SJMP WW
IIC: MOV R2,A
JZ ENDF ;A=00 结束标志跳ENDF程序重新开始
ANL A,#0FH ;低4位为延时值
MOV R5,A ;R5延时值;频率延时(DELAY)程序用
MOV A,R2
SWAP A
ANL A,#0FH ;高4位为音调序号若
JNZ SING ;为0则
CLR TR1 ;为休止符
SJMP DLY1
SING: DEC A ;频率表从0位置开始,音调序号表从1位置开始,0位置数据是解密数据
PUSH ACC
MOV A,0DH
CJNE A,#11,BD ;若11(B)键,即为C~F键转BD0;若=11(B)键转DE,音调序号+31H
POP ACC
SJMP DE
BD: POP ACC
JNC BD0
DE: ADD A,31H
BD0: MOV 22H,A
RL A
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV TH1,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV TL1,A
MOV 20H,A
SETB TR1
DLY1: INC R5
ACALL DELAY
INC 30H
INC 0BH
MOV A,0DH ;取按键值;判断是读内存键还是读乐谱序号键
CJNE A,#0BH,NNBD ;若按键值11取下1个乐谱;若按键值为12~15(C~F)转NNBD读内存
NEXT1: LJMP NEXT
NNBD: JC NEXT1
LJMP NN ;读内存
;--------程序重新开始---------------------------------------
ENDF: CLR TR1
LJMP MAIN
;--------T0中断服务弹奏频率延迟时间---------------------------------------------
TIME0: INC 0AH ;弹奏乐谱频率延迟值
MOV TH0,#0C2H
MOV TL0,#0F6H ;定时初值 =49910 计数次数为 2^16(65536)-49910=15626=16ms
RETI
;--------T1中断服务发声-----------------------
TIME1: PUSH ACC
PUSH PSW
MOV TL1,20H
MOV TH1,21H
CPL P3.7
POP PSW
POP ACC
RETI
;--------读数据--------------------
RBAY: LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
LCALL START
MOV A,0EH
LCALL WRBYT
LCALL TACK
LCALL RDBYT
LCALL NOTACK
LCALL STOP
RET
;-------写数据-------------------
WBAY: LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
MOV A,0CH
LCALL WRBYT
LCALL TACK
LCALL STOP
RET
;---------写数据---------------
;WKX03: MOV R1,#10H
;LCALL START
;MOV A,#0A2H
;LCALL WRBYT
;LCALL TACK
;MOV A,0CH
;LCALL WRBYT
;LCALL TACK
;MOV R0,#4
;WKX031: MOV A,@R1
;LCALL WRBYT
;LCALL TACK
;INC R1
;DJNZ R0,WKX031
;LCALL STOP
;LCALL DELAY1
;LCALL DELAY1
;RET
;-------启动24C16读写时序------------------
START: SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
RET
;-------停止信号------------------
STOP: CLR SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
;CLR SCK
;NOP
;NOP
;NOP
;NOP
RET
;-------应答信号-----------------
TACK: SETB SDA
;CLR SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
;SETB SDA
;NOP
;NOP
;NOP
;NOP
RET
;-------------------------
CHACK: SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
MOV C,SDA
CLR SCK
NOP
NOP
NOP
NOP
RET
;-----------------------------
NOTACK: ;NOP
SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
RET
;------读IIC-24C16------------------
RDBYT: MOV R7,#8
SETB SDA
NOP
NOP
NOP
NOP
RDBYT1: SETB SCK
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,SDA
MOV A,R6
RLC A
MOV R6,A
CLR SCK
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,RDBYT1
RET
;------写IIC-24C16---------------
WRBYT: MOV R7,#8
WRBYT1: RLC A
MOV SDA,C
;JC WRBYT2
;CLR SDA
;NOP
;NOP
;NOP
;NOP
SETB SCK
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,WRBYT1
RET
;WRBYT2: SETB SDA
;NOP
;NOP
;NOP
;NOP
;SETB SCK
;NOP
;NOP
;NOP
;NOP
;CLR SCK
;NOP
;NOP
;NOP
;NOP
;CLR SDA
;NOP
;NOP
;NOP
;NOP
;DJNZ R7,WRBYT1
RET
;-------;TABLE为频率值 -------------------------------------
TABLE: DW 0F88CH,0F95BH,0FA15H,0FA67H,0FB04H,0FB90H,0FC0CH ;低音1~7
DW 0FC44H,0FCACH,0FD09H,0FD34H,0FD82H,0FDC8H,0FE06H ;中音1~7
DW 0FE22H,0FE56H,0FE85H,0FE9AH,0FEC1H,0FEE4H,0FF03H ;高音1~7
;--------TABLE1~11为音调序号和音调延时表调;数据高4位是-----------------------------------
;--------音调序号;低4位是音调延时值-----------------------------------------------------------------
;--------;兰花草---------------------------------------
TABLE1: DB 02H,42H,82H,82H,82H,84H,02H,72H,62H,72H,62H
DB 52H,48H,0B2H,0B2H,0B2H,0B2H,0B4H,02H,0A2H
DB 12H,0A2H,0D2H,92H,88H,82H,0B2H,0B2H,0A2H,84H
DB 02H,72H,62H,72H,62H,52H,44H,02H,12H,12H,62H
DB 62H,52H,44H,02H,82H,72H,62H,52H,32H,48H,00
;-------;哈巴--------------------------------------------
TABLE2: DB 04H,42H,42H,42H,52H,64H,04H,62H,62H,62H,72H,84H,04H
DB 92H,92H,82H,72H,64H,04H,82H,82H,52H,62H,44H,04H
DB 42H,42H,42H,52H,64H,04H,62H,62H,62H,72H,84H,04H
DB 92H,92H,82H,72H,64H,04H,82H,82H,52H,62H,44H,04H,00H
;-------;生日快乐---------------------------------------
TABLE3: DB 04H,82H,01H,81H,94H,84H,0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H,0C4H,0B4H,04H
DB 82H,01H,0F4H,0D4H,0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H,00H
;-------;不倒翁--------------------------------------------
TABLE4: DB 04H,84H,94H,88H,64H,54H,68H,84H,64H
DB 54H,44H,62H,82H,42H,62H,58H;1
DB 84H,94H,88H,64H,54H,68H,84H,64H;2
DB 54H,44H,52H,42H,52H,62H,48H,00
;-------;妹妹背着洋娃娃---------------------------------------
TABLE5: DB 04H,84H,02H,82H,64H,54H,64H,54H,48H,64H
DB 02H,52H,44H,24H,14H,24H,18H;1
DB 24H,02H,22H,42H,24H,44H,54H,68H,54H;2
DB 02H,52H,84H,84H,54H,64H,48H,00
;-------;两只老虎-------------------------------------------------
TABLE6: DB 04H,44H,54H,64H,44H,44H,54H,64H,44H,64H,74H,88H,64H,74H,88H;1
DB 82H,92H,82H,72H,64H,44H,82H,92H,82H
DB 72H,64H,44H,44H,84H,48H,44H,14H,48H,00
;-------;三只小猫----------------------------------------------
TABLE7: DB 04H,62H,82H,82H,62H,98H,92H,0B2H,0B2H,82H,98H
DB 2H,82H,82H,52H,68H,92H,0B2H,0B2H,82H,98H
DB 62H,82H,82H,62H,92H,92H,94H
DB 92H,0B2H,0B2H,92H,84H,94H,0B8H,0B4H,04H,00
;-------;绿-------------------------------------------------------
TABLE8: DB 02H,42H,82H,82H,82H,84H,02H,72H,62H,72H,62H,52H,48H
DB 0B2H,0B2H,0B2H,0B2H,0B4H,02H,0A2H
DB 12H,0A2H,0D2H,92H,88H,82H,0B2H,0B2H,0A2H,84H
DB 02H,72H,62H,72H,62H,52H,44H,02H,12H
DB 12H,62H,62H,52H,44H,02H,82H,72H,62H,52H,32H,48H,00
;-------;绿岛小夜曲-----------------------------------------------
TABLE9: DB 00H,0C2H,0D2H,0F2H,0D2H,0C4H,0D2H,0F2H
DB 0D2H,0C2H,0A2H,92H,0A8H
DB 92H,0A2H,0C2H,0A2H,92H,82H,62H,82H,58H,58H
DB 0C4H,22H,0D2H,0C4H,0A4H,92H,0A2H,92H,82H,92H,0A4H,092H
DB 84H,82H,32H,54H,22H,62H,052H,058H
DB 64H,22H,52H,64H,84H,92H,0A2H,92H,82H,92H,0A4H,0C2H
DB 92H,94H,0A2H,0C4H,22H,0D2H,0C8H,0C8H
DB 0D2H,0D4H,0C2H,0A2H,0A2H,92H,82H,92H,0A2H,0C2H,0A8H
DB 92H,94H,82H,62H,52H,52H,82H,98H,98H
DB 0A2H,0A4H,92H,0A2H,0C2H,0A4H,92H,0A2H,92H,82H,68H
DB 52H,0C2H,0A2H,0F2H,0C2H,0D2H,0A2H,92H,88H,88H
DB 0D2H,0D2H,0D2H,0C2H,0A2H,0A2H,22H
DB 92H,94H,82H,62H,52H,62H,82H,98H,98H
DB 0C2H,0D2H,0C2H,92H,0A2H,0A4H,0A2H
DB 92H,94H,82H,64H,84H,0C8H,0D1H,0C1H,0A2H,0C2H,0D4H,0D2H,0E2H
DB 0C2H,0D2H,0C2H,0A2H,98H
DB 0A4H,92H,82H,64H,22H,82H,92H,0A1H,91H,82H,92H,0A4H,22H,0C2H
DB 0D4H,22H,0A2H,94H,0A2H,92H,88H,88H,00
;---------------------------------------------------------------------------
TABLE10:DB 00H,04H,42H,52H,62H,42H,42H,52H,62H,42H,62H,72H,86H,62H,72H,86H;1
DB 82H,92H,82H,72H,62H,42H,82H,92H,82H
DB 72H,62H,42H,42H,82H,46H,42H,12H,48H,00
;----------------------------------------------------------------------------
TABLE11:DB 00H,23H,01H,63H,01H,51H,61H,41H,51H
DB 64H,22H,92H,51H,61H,72H,64H
DB 04H,63H,01H,93H,01H,81H,91H,0A1H,0A1H
DB 94H,53H,61H,41H,51H,41H,31H,24H,04H
DB 53H,61H,41H,51H,41H,31H,24H,04H,53H,61H,82H
DB 92H,0AAH,02H,93H,0A1H,91H,81H,98H,04H,91H
DB 81H,92H,04H,61H,51H,62H,04H,56H,42H,12H
DB 22H,32H,32,28H,08H,00
;--------------------------------------------------------------------------
;TABLE12:
;DB 01H,00H
;---------------------
END
手边有一些你需要的关于单片机的论文设计资料 需要的话加QQ 晚上7点以后隐身在线,直接加就行,说明要的资料名字就好。嘿嘿 楼主 要是觉的好的话 可别忘了给分哦。
电子琴程序
信号发生器设计报告
电子琴程序
2009-08-30 13:47:34| 分类: 默认分类
| 标签: |举报 |字号大中小 订阅
电子琴程序发送部分:
/*
本程序是用AD9851的DDS模块做的电子琴,
电子琴的音符完整,共21个按键,分别是低1--7,中1--7,高1--7。本程序为双机通信的发送部分,可以显示频率
*/
#include REG51.H //
单片机内部专用寄存器定义
/**************************************/
sbit K1= P1^0; //
键K1输入引脚定义
sbit K2= P1^1; // 键K2输入引脚定义
sbit K3= P1^2; //
键K3输入引脚定义
sbit K4= P1^3; // 键K4输入引脚定义
sbit K5= P1^4; //
键K5输入引脚定义
sbit K6= P1^5; // 键K6输入引脚定义
sbit K7= P1^6; //
键K7输入引脚定义
sbit K8= P1^7; //
键K15输入引脚定义
/**************************************/
sbit K9= P2^0; //
键K8输入引脚定义
sbit K10= P2^1; // 键K9输入引脚定义
sbit K11= P2^2; //
键K10输入引脚定义
sbit K12= P2^3; // 键K11输入引脚定义
sbit K13= P2^4; //
键K12输入引脚定义
sbit K14= P2^5; // 键K13输入引脚定义
sbit K15= P2^6; //
键K14输入引脚定义
sbit K16= P2^7; //
键K16输入引脚定义
/**************************************/
sbit K17= P3^2; //
键K17输入引脚定义
sbit K18= P3^3; // 键K18输入引脚定义
sbit K19= P3^4; //
键K19输入引脚定义
sbit K20= P3^5; // 键K20输入引脚定义
sbit K21= P3^7; // 键K21输入引脚定义
/******************延时程序********************/
void delay(unsigned int
k)
{
unsigned int i,j;
for(i=0;ik;i++){
for(j=0;j121;j++)
{;}}
}
/*****************串口初始化程序*****************/
void
init
(void)
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
SCON=0x50;
TR1=1;
}
/*****************串口发送程序*****************/
void chuan(shu)
{
SBUF=shu;
TI=0;
}
/******************主程序********************/
void main(void)
{
init();
while(1)
{
if(K1==0) chuan(1);
else if(K2==0)
chuan(2);
else if(K3==0) chuan(3);
else if(K4==0) chuan(4);
else
if(K5==0) chuan(5);
else if(K6==0) chuan(6);
else if(K7==0)
chuan(7);
else if(K8==0) chuan(8);
else if(K9==0) chuan(9);
else
if(K10==0) chuan(10);
else if(K11==0) chuan(11);
else if(K12==0)
chuan(12);
else if(K13==0) chuan(13);
else if(K13==0)
chuan(13);
else if(K14==0) chuan(14);
else if(K15==0)
chuan(15);
else if(K16==0) chuan(16);
else if(K17==0)
chuan(17);
else if(K18==0) chuan(18);
else if(K19==0)
chuan(19);
else if(K20==0) chuan(20);
else if(K21==0)
chuan(21);
else chuan(0);
}
}
电子琴接收部分:
/*
本程序是用AD9851的DDS模块做的电子琴,
电子琴的音符完整,共21个音符,分别是低1--7,中1--7,高1--7。本程序为双机通信的接受部分。有直接演奏方式,录音演奏方式,录音后放音方式
,可以显示频率 */
#include STC12C5410AD.H
#includeintrins.h
#include stdio.h /* prototype
declarations for I/O functions */
#define uchar unsigned char
#define uint unsigned int
sbit
E_CLK =P2^6;//clock input 同步时钟输入端
sbit RW_SID
=P2^5;//data input/output 串行数据输入、输出端
sbit RS_DI
=P2^4; // 4号脚 jichunqi input
sbit DataIn_AD9851=P2^3;
//控制子串传送位
sbit DDS_CLK=P2^2; //接外部晶振时钟 这里为30M
sbit
DDS_FQUD=P2^1; //更新发送频率
sbit RST_AD9851= P2^0; //复位
unsigned char Control_AD9851 = 0x01; // Phase0 ,power on mode and 6 REFCLK
Multiplier enable
/* T0_int 定时 时间常数 5ms=5000=1388H-EC78H f=12MH */
#define
time_5ms_H 0xC2 /* 定时时间为1/64s */
#define time_5ms_L 0xF7
char shu, bb;
unsigned char p=0;
unsigned char
point=0;
unsigned char recode_n=0;
unsigned char xdata
array[50]={0};
unsigned int xdata arrayt[50]={0};
float const
ton[]={0.00,261.63,293.67,329.63,349.23,391.99,440.00,494.00,
523.25,587.33,659.25,698.46,783.99,880.00,987.76,
1046.50,1174.66,1381.51,1396.92,1567.98,1760.00,1975.52};
unsigned int ttt,
nnn;
unsigned char mode=0;
sbit KEY_rec =P3^5;
sbit KEY_play=P3^7;
/*************************延时程序***************************/
void
delay(uint k)
{
uint i,j;
for(i=0;ik;i++)
{for(j=0;j121;j++)
{;}}
}
/*************************串行发送一字节数据***************************/
void SendByte(unsigned char dat)
{
unsigned
char i;
RS_DI=1;
for(i=0;i8;i++)
{
E_CLK=0;
if(dat0x80)RW_SID=1;
else RW_SID=0;
E_CLK=1;
dat=dat1;
}
}
/*************************写控制命令***************************/
void
SendCMD(unsigned char dat)
{
SendByte(0xF8);//11111,00,0
RW=0,RS=0 同步标志
SendByte(dat0xF0);//高四位
SendByte((dat0x0F)4);//低四位
}
/************************写显示数据或单字节字符 ****************************/
void SendDat(unsigned char dat)
{
SendByte(0xFA);//11111,01,0 RW=0,RS=1
SendByte(dat0xF0);//高四位
SendByte((dat0x0F)4);//低四位
}
/************************显示字符串****************************/
void
hzkdis(unsigned char code *s)
{ while(*s0)
{
SendDat(*s);
s++;
delay(5);
}
}
/************************显示数据子程序****************************/
void
Display(unsigned char x_add,unsigned long date,unsigned char dot)
{
unsigned char date0,date1,date2,date3,date4,date5;//;
date5=(date%1000000)/100000;
date4=(date%100000)/10000;
date3=(date%10000)/1000;
date2=(date%1000)/100;
date1=(date%100)/10;
date0=date%10;
SendCMD(x_add);
if(dot==0x02) //100---9999.99
{
SendDat(0x30+date5);
SendDat(0x30+date4);
SendDat(0x30+date3);
SendDat(0x30+date2);
SendDat(0x2e);
SendDat(0x30+date1);
SendDat(0x30+date0);
SendDat(0x48);
SendDat(0x7a);
}
}
/*************************设置AD9851频率***************************/
void
SentFreq(unsigned long int freq)
{
unsigned char i=0;
unsigned int
temp;
DDS_FQUD=0;
for(i=0;i32;i++) //串口数据
输入频率控制字
{
DDS_CLK =
0;
temp=((freqi)1);
DataIn_AD9851 = temp;
DDS_CLK =
1;
}
for(i=0;i8;i++) //phase-b4 ph-b3 ph-b2 ph-b1 ph-b0 Power-down
Logic0* 6*REFCLK Multiplier_En
{
DDS_CLK = 0;
temp=((Control_AD9851i)1);
DataIn_AD9851 = temp;
DDS_CLK = 1;
}
DDS_CLK = 0;
DDS_FQUD = 1;
DDS_FQUD =
0;
}
/**************************换算频率,并输出***********************/
void
Set_Freq(float Freqency)
{unsigned long int freq_temp;
freq_temp=
(unsigned long int)(23.861*Freqency); // SYSCLK = 180 MHz
2^32/180000000=23.861
SentFreq(freq_temp);
}
/*************************T0作定时器,T1作波特率发生器,初始化*************************/
void
init (void)
{
TMOD= 0x01; /* 0001$0001 T1 T0 are 16bit
timers */
TH0 = time_5ms_H; /* T0 timer 5ms */
TL0 =
time_5ms_L;
/* TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 */
TCON= 0x10; /* 0 0 0 1 0 0 0 0 */
/* start T0 xint1 xint0 */
IE= 0x82; /* 1000 0010,
EA=ET0=1,
*/
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0x50;
ES=1;
EA=1;
}
/*************************设置AD9851初始化*************************/
void
AD9851Init(void) //DDS初始化函数,包括DDS复位和初始化为串行发送
{
DDS_CLK=0;
DDS_FQUD=0;
RST_AD9851=0;
RST_AD9851=1;//复位AD9851
RST_AD9851=1;
RST_AD9851=1;
RST_AD9851=0;
DDS_CLK=1;
DDS_CLK=0;
DDS_FQUD=1;
DDS_FQUD=0;
}
/**************************初始化LCM
**************************/
void initlcm(void)
{
delay(100);
SendCMD(0x30);//功能设置,一次送8位数据,基本指令集
SendCMD(0x0C);//0000,1100 整体显示,游标off,游标位置off
SendCMD(0x14);
SendCMD(0x01);//0000,0001 清DDRAM 即清屏
SendCMD(0x02);//0000,0010 DDRAM地址归位
SendCMD(0x80);//1000,0000
设定DDRAM 7位地址000,0000到地址计数器AC
//SendCMD(0xb8|page);翻页
}
/**********************主程序******************************/
void
main(void)
{
uchar t;
init();
AD9851Init();
initlcm(); //12864初始化程序
shu=0;
bb=255;
while(1)
{
switch(mode)
{
case 0: //
演奏方式
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐播放频率:");
if (shu!=bb)
{
Set_Freq(ton[shu]);
Display(0x93,(unsigned
long)100*ton[shu],0x02);
bb=shu;
}
if
(KEY_rec==0)
{
mode=1;
point=0;
recode_n=0;
shu=0;
bb=255;
nnn=0;
}
else if (KEY_play==0)
{
mode=2;
p=1;
}
break;
case
1: // 录音方式
// SendCMD(0x01);//0000,0001 清DDRAM 即清屏
//
delay(10);
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐录制频率:");
if (shu!=bb)
{
arrayt[point]=nnn; // 记录上一音阶时间
Set_Freq(ton[shu]);
Display(0x93,(unsigned long)100*ton[shu],0x02);
nnn=0;
bb=shu;
recode_n++;
}
if ((recode_n=50) || (KEY_play==0))
//停止录音
{
Set_Freq(0.0);
p=0;
mode=0;
shu=0;
bb=20;
}
break;
case 2: //
放音方式
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐重播频率:");
for(t=0;t recode_n;t++)
{
Set_Freq(ton[array[p]]);
Display(0x93,(unsigned
long)*ton[array[p]],0x02);
ttt=arrayt[p];
while
(ttt);
delay(100);
p++;
}
if
(precode_n)
{
Set_Freq(0.0);
p=0;
mode=0;
shu=0;
bb=20;
}
break;
}
}
}
//*==================================*/
/* 串口中断接收
*/
/*==================================*/
void s_receive() interrupt 4
//串行中断
{
if(RI==1) //接收中断标志位
{
RI=0; //中断标志清零
shu=SBUF; //RXData赋值
}
else
TI=0;
}
单片机电子琴设计报告的介绍就聊到这里吧,感谢您花时间阅读,谢谢。
本文标签:单片机电子琴设计报告