单片机简易电子琴程序

单片机简易电子琴程序,第1张

R5音调延时值R6从内存中读到的数据

9H--TABLE1~11数据20H--TL1初值21H--TH1初值22H--修正后的按键值30H--TABLE1~11地址计数器

0AH--d奏音调延时值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

------------扫描放歌和d奏建------------------------------------

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      没按d奏建跳QT3

SETB  P3.4

LCALL DELAY1

LCALL DELAY1

JNB   P3.3,$   d奏键没释放原地等待

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    返回重新扫描放歌和d奏建

--------------------------------------------------------------------------

RWX80:  CJNE  A,#0DH,MM2  A!=13(D键)转M2若为D键继续D键没按下转M2

MOV   0EH,#0A2H  0EH=162=10100010B0EH为24c16页地址

SJMP  MM

MM2:     CJNE  A,#0EH,MM3  A!=14(E键)转M3E键没按下转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 d奏键按下 向下执行存储乐曲并演奏 否则转LOOP4继续输入乐曲

LCALL DELAY1

LCALL DELAY1

MOV   0CH,#0

LCALL WBAY    存00结束乐谱

LCALL DELAY1

MOV   0DH,#12

LJMP  SING0     播放d奏的乐曲

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     d奏乐谱频率延迟值赋A

CLR   C

RRC   A

CLR   C

RRC   A

CLR   C

RRC   A   d奏乐谱频率延迟值/8

CJNE  A,#0FH,NODE

SJMP  DDD

NODE:   JC    DDD

MOV   A,#0FH  d奏乐谱频率延迟值/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中断服务d奏频率延迟时间---------------------------------------------

TIME0:  INC   0AH    d奏乐谱频率延迟值

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,58H1

DB 84H,94H,88H,64H,54H,68H,84H,64H2

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,18H1

DB 24H,02H,22H,42H,24H,44H,54H,68H,54H2

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,88H1

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,86H1

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

电子琴程序

信号发生器设计报告

电子琴程序

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=0i<ki++){

for(j=0j<121j++)

{}}

}

/*****************串口初始化程序*****************/

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)

elsechuan(0)

}

}

电子琴接收部分:

/*

本程序是用AD9851的DDS模块做的电子琴,

电子琴的音符完整,共21个音符,分别是低1--7,中1--7,高1--7。本程序为双机通信的接受部分。有直接演奏方式,录音演奏方式,录音后放音方式

,可以显示频率 */

#include <STC12C5410AD.H>

#include<intrins.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号脚 jichunqiinput

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

charshu, 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=0i<ki++)

{for(j=0j<121j++)

{}}

}

/*************************串行发送一字节数据***************************/

void SendByte(unsigned char dat)

{

unsigned

char i

RS_DI=1

for(i=0i<8i++)

{

E_CLK=0

if(dat&0x80)RW_SID=1

else RW_SID=0

E_CLK=1

dat=dat<<1

}

}

/*************************写控制命令***************************/

void

SendCMD(unsigned char dat)

{

SendByte(0xF8)//11111,00,0

RW=0,RS=0 同步标志

SendByte(dat&0xF0)//高四位

SendByte((dat&0x0F)<<4)//低四位

}

/************************写显示数据或单字节字符 ****************************/

void SendDat(unsigned char dat)

{

SendByte(0xFA)//11111,01,0 RW=0,RS=1

SendByte(dat&0xF0)//高四位

SendByte((dat&0x0F)<<4)//低四位

}

/************************显示字符串****************************/

void

hzkdis(unsigned char code *s)

{ while(*s>0)

{

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=0i<32i++) //串口数据

输入频率控制字

{

DDS_CLK =

0

temp=((freq>>i)&1)

DataIn_AD9851 = temp

DDS_CLK =

1

}

for(i=0i<8i++)//phase-b4 ph-b3 ph-b2 ph-b1 ph-b0 Power-down

Logic0* 6*REFCLK Multiplier_En

{

DDS_CLK = 0

temp=((Control_AD9851>>i)&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 T0xint1 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=0t<recode_nt++)

{

Set_Freq(ton[array[p]])

Display(0x93,(unsigned

long)*ton[array[p]],0x02)

ttt=arrayt[p]

while

(ttt)

delay(100)

p++

}

if

(p>recode_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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11414135.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存