单片机简易电子琴程序

作者&投稿:冻琪 (若有异议请与网页底部的电邮联系)
基于单片机的简易电子琴设计C程序解释~

http://wenku.baidu.com/view/667bc03210661ed9ad51f35f.html 可以参考一下这个,基本原理都是一样的

//本程序的单片机晶振采用11.0592M
#include
sbit speaker=P1^2;
unsigned char timer0h,timer0l,time;
//世上只有妈妈好数据表
code unsigned char sszymmh[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0
};
// 音阶频率表 高八位
code unsigned char FREQH[]={
0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
} ;
// 音阶频率表 低八位
code unsigned char FREQL[]={
0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
};
void delay(unsigned char t)
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1<t;t1++)
{
for(t2=0;t2<8000;t2++)
{
;
}
}
TR0=0;
}
void t0int() interrupt 1
{
TR0=0;
speaker=!speaker;
TH0=timer0h;
TL0=timer0l;
TR0=1;
}
void song()
{
TH0=timer0h;
TL0=timer0l;
TR0=1;
delay(time);
}

void main(void)
{
unsigned char k,i;
TMOD=1; //置CT0定时工作方式1
EA=1;
ET0=1;//IE=0x82 //CPU开中断,CT0开中断
while(1)
{
i=0;
while(i<100){ //音乐数组长度 ,唱完从头再来
k=sszymmh[i]+7*sszymmh[i+1]-1;
timer0h=FREQH[k];
timer0l=FREQL[k];
time=sszymmh[i+2];
i=i+3;
song();
}
}
}

;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:    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



你爽了,我正好有!
这是一款用51单片机控制的玩具电子琴,用到了51的定时器和键盘技术,它的汇编程序流程如下,很适合初学者学习制作。
说明:由单片机的P1.0口输出音频信号,在P1.0口接三极管以驱动喇叭,最好用两个三极管构成达林顿结构。P2口连接8个一端接地的按键作为输入,当然也需要连接8只10K的电阻至电源作为上拉电阻。P2.0~P2.7依次为Do、Re、Mi、Fa、So、La、Si、Do(高)音。

BUZZ EQU P1.0
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP INT_T0
ORG 0100H
MAIN:
MOV SP,#60H ;初始化堆栈指针
MOV 30H,#00 ;定时器初值清零
MOV 31H,#00
MOV P1,#0FFH ;设置P1口为输入模式
MOV TMOD,#01H ;设置定时器0为工作模式1
SETB ET0 ;开定时器0中断
SETB EA ;开总中断
CLR TR0 ;关闭定时器0
START:
MOV R0,P2
CJNE R0,#0FFH,KEY1 ;键盘扫描
CLR TR0
SJMP START
KEY1:
CJNE R0,#0FEH,KEY2 ;K1键按下
MOV 30H,#0FBH ;设置音阶1
MOV 31H,#0E9H
LJMP SET_TIMER
KEY2:
CJNE R0,#0FDH,KEY3 ;K2键按下
MOV 30H,#0FCH ;设置音阶2
MOV 31H,#5CH
LJMP SET_TIMER
KEY3:
CJNE R0,#0FBH,KEY4 ;K3键按下
MOV 30H,#0FCH ;设置音阶3
MOV 31H,#0C1H
LJMP SET_TIMER
KEY4:
CJNE R0,#0F7H,KEY5 ;K4键按下
MOV 30H,#0FCH ;设置音阶4
MOV 31H,#0EFH
LJMP SET_TIMER
KEY5:
CJNE R0,#0EFH,KEY6 ;K5键按下
MOV 30H,#0FDH ;设置音阶5
MOV 31H,#045H
LJMP SET_TIMER
KEY6:
CJNE R0,#0DFH,KEY7 ;K6键按下
MOV 30H,#0FDH ;设置音阶6
MOV 31H,#92H
LJMP SET_TIMER
KEY7:
CJNE R0,#0BFH,KEY8 ;K7键按下
MOV 30H,#0FDH ;设置音阶7
MOV 31H,#0D6H
LJMP SET_TIMER
KEY8:
CJNE R0,#7FH,NOKEY ;K8按下
MOV 30H,#0FDH ;设置音阶8
MOV 31H,#0FBH
SET_TIMER:
SETB TR0 ;发声
SJMP START
NOKEY:
CLR TR0 ;无键按下
SJMP START
INT_T0: ;T0中断服务程序
MOV TH0,30H ;定时器赋初值
MOV TL0,31H
CPL BUZZ ;输出方波
RETI
END

22. 电子琴
1. 实验任务
(1. 由4X4组成16个按钮矩阵,设计成16个音。
(2. 可随意弹奏想要表达的音乐。
2. 电路原理图

图4.22.1
3. 系统板硬件连线
(1. 把“单片机系统”区域中的P1.0端口用导线连接到“音频放大模块”区域中的SPK IN端口上;
(2. 把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4 R1-R4端口上;
4. 相关程序内容
(1. 4X4行列式键盘识别;
(2. 音乐产生的方法;
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数T0相关的计数值如下表所示
音符 频率(HZ) 简谱码(T值) 音符 频率(HZ) 简谱码(T值)
低1 DO 262 63628 # 4 FA# 740 64860
#1 DO# 277 63731 中 5 SO 784 64898
低2 RE 294 63835 # 5 SO# 831 64934
#2 RE# 311 63928 中 6 LA 880 64968
低 3 M 330 64021 # 6 932 64994
低 4 FA 349 64103 中 7 SI 988 65030
# 4 FA# 370 64185 高 1 DO 1046 65058
低 5 SO 392 64260 # 1 DO# 1109 65085
# 5 SO# 415 64331 高 2 RE 1175 65110
低 6 LA 440 64400 # 2 RE# 1245 65134
# 6 466 64463 高 3 M 1318 65157
低 7 SI 494 64524 高 4 FA 1397 65178
中 1 DO 523 64580 # 4 FA# 1480 65198
# 1 DO# 554 64633 高 5 SO 1568 65217
中 2 RE 587 64684 # 5 SO# 1661 65235
# 2 RE# 622 64732 高 6 LA 1760 65252
中 3 M 659 64777 # 6 1865 65268
中 4 FA 698 64820 高 7 SI 1967 65283
下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据
低音0-19之间,中音在20-39之间,高音在40-59之间
TABLE: DW 0,63628,63835,64021,64103,64260,64400,64524,0,0
DW 0,63731,63928,0,64185,64331,64463,0,0,0
DW 0,64580,64684,64777,64820,64898,64968,65030,0,0
DW 0,64633,64732,0,64860,64934,64994,0,0,0
DW 0,65058,65110,65157,65178,65217,65252,65283,0,0
DW 0,65085,65134,0,65198,65235,65268,0,0,0
DW 0
2、音乐的音拍,一个节拍为单位(C调)
曲调值 DELAY 曲调值 DELAY
调4/4 125ms 调4/4 62ms
调3/4 187ms 调3/4 94ms
调2/4 250ms 调2/4 125ms
对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。
下面就用AT89S51单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。
在这个程序中用到了两个定时/计数器来完成的。其中T0用来产生音符频率,T1用来产生音拍。
5. 程序框图
贴不了.
7. C语言源程序
#include <AT89X51.H>
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char STH0;
unsigned char STL0;
unsigned int code tab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};

void main(void)
{
TMOD=0x01;
ET0=1;
EA=1;

while(1)
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=0;
break;
case 0x0d:
key=1;
break;
case 0x0b:
key=2;
break;
case 0x07:
key=3;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}

P3=0xff;
P3_5=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=6;
break;
case 0x07:
key=7;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}

P3=0xff;
P3_6=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=8;
break;
case 0x0d:
key=9;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=11;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}

P3=0xff;
P3_7=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=12;
break;
case 0x0d:
key=13;
break;
case 0x0b:
key=14;
break;
case 0x07:
key=15;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
}
}

void t0(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}

根据自己的情况稍微改改就好了

一般用4*4键盘实现比较节约资源,
我在实现的时候和你一样,用8个按键输入,
效果很好,程序可以到我Q空间查看。。。。


高分求单片机课程设计报告
手边有一些你需要的关于单片机的论文设计资料 需要的话加QQ 晚上7点以后隐身在线,直接加就行,说明要的资料名字就好。嘿嘿 楼主 要是觉的好的话 可别忘了给分哦。

吉他和电子琴哪个容易学?
电子琴更好学,容易上手些。电子琴是一种电子键盘乐器,属于电子合成器。它采用大规模集成电路,大多配置声音记忆存储器(波表)。用于存放各类乐器的真实声音波形并在演奏的时候输出。常用的电子琴有编曲键盘(带自动伴奏)和合成器(无自动伴奏)两大类,广义上的电子琴包括电子钢琴(数码钢琴,区别于...

2014小提琴重庆地区考级地点和时间
乐器考级4月辅助报名 钢琴为1日至2日 小提琴为3日至7日 报名费10元———4月1日至2日和4月3日至7日分别是今年钢琴和小提琴考级加报的时间。记者从中国音乐家协会获悉,小提琴考级内容进行了适当调整,考试内容更为简易。据中国音乐家协会音乐考级办公室王主任介绍,4月份的考级报名是辅助正常的2月...

电影\/电视剧
这次他在《永不妥协》的配乐中尝试运用大量的电子乐,藉着轻短的敲打与拨弄将电子吉他作整个大幅度的低音呈现。电子琴与风琴的表现则带点爵士味道挑动,在简易旋律中不断爬升重复。这样极简式的音乐表现让汤玛士纽曼的配乐,听来总在温柔中带点冷淡的都会气息。除此之外,雪瑞儿可洛在1996年荣获葛莱美奖...

我的琴为什么没有电池的呢?
电脑电子琴是指采用大规模音源集成电路和单片计算机(CPU)集成电路组成的多功能电子琴,如卡西欧(MT-65、MT-68)、雅马哈(PSR-11、PSR-12、CT-310、350、360)等型号,这类电子琴的特点是功能齐全、音调准确、音色较好、可靠性高。一、故障特点 简易电子琴的常见故障是音调不准、按键接触不良、声音发毛...

电子琴和钢琴的区别
通过按键盘上的键,触动钢琴里裹着毛毡的琴槌,然后敲击钢丝弦发出声音。电钢琴按下按键时,开启内部的晶体振荡器,产生一定的频率波形,经分频器放大后送到扬声器发声。电钢琴的键盘结构比较简单,一般以弹簧为主,并增加了配重结构。其他部分都是电子电路,可以通过声音连接耳机。

献给孩子的暑期礼物!电影《外太空的莫扎特》是一部儿童片吗?
要尊重孩子的选择是没有错,但这样的事情下,还非要让小孩舍弃前途似锦的电子琴,投身于充斥着不明的天文学工作,是否也过于勉强了一点?令人觉得难以相信是指,此片无缘无故地把造型艺术和科学合理摆到矛盾的部位上。学琴和天文学科学研究,怎么就变成水火不相容的关联?主创人员不容易不清楚,别人大...

钢琴学习从初级到高级练习的曲目和书目共有那些?
初级阶段:可用拜厄《钢琴基本教程》;汤普森的《现代钢琴教程》第一册等教材:这阶段主要是学习用手臂重量弹琴,学会手指支撑手臂的重量。接着就可以学习车尔尼的《钢琴初步教程》(599)《钢琴简易练习曲》(作品139)、《钢琴流畅练习曲》(作品849);巴赫的《初级钢琴曲集》《前奏曲与赋格曲》;《小...

像若贝尔这样的人有哪些
到1986年,他借助电子计算机分析了几十万个数据,编了几万条程序,发表了二十多篇论文,从而对准定常行星波的物理成因、传播规律及及其异常做出了进一步的解释...说话间,袁老师还特意从书房里搬出一架雅马哈电子琴来,说是去日本讲学时带回来的,还不错。他一边说,一边接通电源,随意调整着各个控制钮,咚咚咚地试了几...

笔记本那种薄薄的键盘 是什么材质? 有类似的外接独立键盘吗..._百度知...
笔记本键盘基本都是X构架的键盘(尤其是手感好的键盘)!类似的键盘当然有的!比如明基的海湾或者海贝键盘!但现在不太好买到了!再有就是普拉多键盘!都是超薄静音手感不错的!你也可以在网上搜剪刀脚或者是X构架!能搜到不少地!希望能找到和适的键盘!

茂港区15870401319: 单片机简易电子琴程序
方贩曼欣: ;R5音调延时值;R6从内存中读到的数据nbsp;;9H--TABLE1~11数据;20H--TL1初值;21H--TH1初值;22H--修正后的按键值;30H--TABLE1~11地址计数器nbsp;;0AH--弹奏音调延时值;0BH--内存地址;0CH--读写到内存的数据;0DH--按键值...

茂港区15870401319: 单片机简易电子琴程序 -
方贩曼欣: ;R5音调延时值;R6从内存中读到的数据 ;9H--TABLE1~11数据;20H--TL1初值;21H--TH1初值;22H--修正后的按键值;30H--TABLE1~11地址计数器 ;0AH--弹奏音调延时值;0BH--内存地址;0CH--读写到内存的数据;0DH--按键值;0EH--...

茂港区15870401319: 单片机 简易电子琴的设计? -
方贩曼欣: 22. 电子琴 (1. 由4X4组成16个按钮矩阵,设计成16个音. (2. 可随意弹奏想要表达的音乐. 2. 电路原理图 图4.22.1 3. 系统板硬件连线 (1. 把“单片机系统”区域中的P1.0端口用导线连接到“音频放大模块”区域中的SPK IN端口上; (2. 把...

茂港区15870401319: 单片机设计电子琴,如何编写程序最简单 -
方贩曼欣: /* 21个按键,对应高中低音1234567 三个LED表示音高 7个LED表示音符 按下一个按键,发出对应的声音,对应的音高,音符的LED识点亮 */ ProteUS仿真工程(可运行),供参考运行效果,及原理图的设计. http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4454671&bbs_id=1037

茂港区15870401319: 利用单片机设计简易电子琴
方贩曼欣: http://wenku.baidu.com/view/48b17173f242336c1eb95e9c.html这个肯定适合你!!Proteus电子琴整个设计过程,程序电路图都有了

茂港区15870401319: 求程序52单片机设计要求设计一个电子琴.利用所给键盘的1,2,3,4,5,6,7,8八个键,能够发出8个不同的音调,并且要求按下按键发声松开延时一段时间停止,在该延时时间内再按别的键则发另一音调的声音
方贩曼欣: 想听不同的音,频率改变就好了,你自己改变数值就好了, 如(x=(65536-320)/256;y=(65536-320)%256;)改变320就好了#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit k1=P3^0;sbit k2=P3^1;sbit k3=P3^2;...

茂港区15870401319: 用单片机实现简易电子琴的课程设计 -
方贩曼欣:说明:由单片机的P1.0口输出音频信号,在P1.0口接三极管以驱动喇叭,最好用两个三极管构成达林顿结构.P2口连接8个一端接地的按键作为输入,当然也需要连接8只10K的电阻至电源作为上拉电阻.P2.0~P2.7依次为Do、Re、Mi、Fa、...

茂港区15870401319: 用51单片机 制作简易电子琴 的两个问题 -
方贩曼欣: 内部大循环只要把扫描程序等需要不停执行的程序写在 while(1) { ......(这里) } 识别按键只要与按键相连的引脚检测到低电平即可 给你一个按键范例:假如按键接到单片机P2^0引脚 sbit K = P2^0; if(K == 0) { delay(5); //延时去抖 if(K == 0) //确定键按下 { while(!K); //判断松手 .....(功能函数) } }

茂港区15870401319: 单片机电子琴程序.带存储回放功能
方贩曼欣: 设定两个数组,,一个数组放音调,一个数组放节拍,也就是时间长度... 就OK了 ,,希望能帮到你..

茂港区15870401319: 求单片机简易电子琴程序如何编写 -
方贩曼欣: http://zhidao.baidu.com/question/271733376.html http://zhidao.baidu.com/question/270531185.html

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网