配色: 字号:
带演奏指示灯的电子琴
2017-03-20 | 阅:  转:  |  分享 
  
笔者开发了一种电路,它可以安装在电子琴的按键上。这个电路有64个LED指示灯,64个按键。这64个按键和电子琴共用。电子琴也使用这64个按键弹奏音乐。每个按键对应一个LED灯。电路通过STC89C51单片机控制,当要演奏一首乐曲时,这个乐曲要弹奏的第一个按键上面的LED灯就会亮起来,只有演奏者按下这个按键,这个LED等才会熄灭。同时,当上一个LED灯熄灭以后,这个乐曲要弹奏的第二个按键上面的LED灯就会亮起。只有演奏者按下这个按键,这个LED等才会熄灭。紧接着,这个乐曲要弹奏的第三个按键上面的LED灯就会亮起,同样,只有演奏者按下这个按键,这个LED等才会熄灭。按键上面的LED就按照乐曲要弹奏的按键的顺序亮起,同时,只有演奏者按照乐曲要弹奏的按键的顺序弹奏乐曲,按键上的LED才会熄灭。这样就实现了,演奏者按照乐曲弹奏按键的顺序,也就是按照LED等亮起的顺序,演奏乐曲的功能。也就让一个不会弹琴的人,按照LED的指示来学习弹琴。下面是这个电路的电路图。



电路中,单片机STC89C51控制芯片HD7279A。HD7279A控制64个按键和64个LED灯。按照程序,第一个LED亮,当按下第一个按键时,这个LED灭,同时,第二个LED亮,当按下第二个按键时,这个LED灭。这样就实现了按键以此熄灭LED的功能。下面是程序:

#include



//函数定义

voidlong_delay(void); //长延时

voidshort_delay(void); //短暂延时

voiddelay10ms(unsignedchar); //延时10MS

voidwrite7279(unsignedchar,unsignedchar); //写入到HD7279

unsignedcharread7279(unsignedchar); //从HD7279读出

voidsend_byte(unsignedchar); //发送一个字节

unsignedcharreceive_byte(void); //接收一个字节



//变量及I/O口定义

unsignedchardigit[5];

unsignedcharkey_number,j,k,m,n;

unsignedinttmr;

unsignedlongwait_cnter;

unsignedcharcodedis_code[65]

=



{16,17,1,2};

unsignedcharcodedis_code1[256]

=



{0,1,2,3,4};

unsignedcharcodedis_code2[9]

=



{0,1,2,3,4,5,6,7,8};



unsignedcharcodedis_code3[65]

=



{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

unsignedcharcodedis_code4[256]

=



{0,1,2,3,4,5,6,7,8,9,10,11,12};

unsignedcharcodedis_code5[128]

=



{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};



unsignedcharcodedis_code6[65]

=



{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

unsignedcharcodedis_code7[256]

=



{0,1,2,3,4,5,6,7,8,9,10};

unsignedcharcodedis_code8[128]

=



{0,1,2,3,4,5,6,7,8,9,10,11};

unsignedcharcodedis_code9[128]

=



{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};



sbitcs=P1^4; //csatP1.4

sbitclk=P1^5; //clk连接于P1.5

sbitdat=P1^2; //dat连接于P1.2

sbitkey=P1^3; //key连接于P1.3

sbitS1=P0^0; //key连接于P1.3

sbitS2=P0^1; //key连接于P1.3



//HD7279A指令

#defineCMD_RESET0xa4

#defineCMD_TEST0xbf

#defineDECODE00x80

#defineDECODE10xc8

#defineCMD_READ0x15

#defineUNDECODE0x90

#defineRTL_CYCLE0xa3

#defineRTR_CYCLE0xa2

#defineRTL_UNCYL0xa1

#defineRTR_UNCYL0xa0

#defineACTCTL0x98

#defineSEGON0xe0

#defineSEGOFF0xc0

#defineBLINKCTL0x88









voidwrite7279(unsignedcharcmd,unsignedchardta)

{

send_byte(cmd);

send_byte(dta);

}



unsignedcharread7279(unsignedcharcommand)

{

send_byte(command);

return(receive_byte());

}



voidsend_byte( unsignedcharout_byte)

{

unsignedchari;

cs=0;

long_delay();

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

{

if(out_byte&0x80)

{

dat=1;

}

else

{

dat=0;

}

clk=1;

short_delay();

clk=0;

short_delay();

out_byte=out_byte2;

}

dat=0;

}



unsignedcharreceive_byte(void)

{

unsignedchari,in_byte;

dat=1; //settoinputmode

long_delay();

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

{

clk=1;

short_delay();

in_byte=in_byte2;

if(dat)

{

in_byte=in_byte|0x01;

}

clk=0;

short_delay();

}

dat=0;

return(in_byte);

}



voidlong_delay(void)

{

unsignedchari;

for(i=0;i<0x30;i++);

}



voidshort_delay(void)

{

unsignedchari;

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

}







//延时n个1MS

//输入:n延时个数

voiddelay1ms(unsignedcharn)

{

unsignedinti;



while(n--)

{

for(i=0;i<125;i++); //i++,8μS左右

}

}



//延时n个10MS

//输入:n延时个数

voiddelay10ms(unsignedcharn)

{

unsignedinti;



while(n--)

{

for(i=0;i<1250;i++); //i++,8μS左右

}

}



voiddelay(void)

{

unsignedintn;

for(n=0;n<10000;n++)

;

}



//主程序

//主程序

main()

{



unsignedcharp;

p=0;//将i初始化为0

while(1)

{

if(S1==0)//如果S1键按下

{ delay10ms(20);

//延时一段时间

if(S1==0)//如果再次检测到S1键按下

p++;//i自增1

delay10ms(20);

//延时一段时间

if(p==4)//如果i=9,重新将其置为1

p=1;



}

switch(p)//使用多分支选择语句

{

case1:

for(j=0;j<256;)

{



write7279(SEGON,dis_code1[j]); //将64个显示段逐个点亮

if(!key) //如果有键按下

{

key_number=read7279(CMD_READ); //读出键码





if(key_number==dis_code1[j]) //如果有键按下

{

write7279(SEGOFF,dis_code1[j]); //将64个显示段逐个点亮

delay10ms(20);

j++;



}





}

}





break;

case2:

for(j=0;j<256;)

{



write7279(SEGON,dis_code[j]); //将64个显示段逐个点亮

if(!key) //如果有键按下

{

key_number=read7279(CMD_READ); //读出键码





if(key_number==dis_code[j]) //如果有键按下

{

write7279(SEGOFF,dis_code[j]); //将64个显示段逐个点亮

delay10ms(20);

j++;



}





}



break;



default://缺省值,关闭所有LED

P0=0xff;



}

}



}





}



献花(0)
+1
(本文系馆名9xyuj0w...首藏)