![]() |
中国面包师贴吧-楼主(阅:455/回:0)带演奏指示灯的电子琴笔者开发了一种电路,它可以安装在电子琴的按键上。这个电路有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 <reg52.h> //*** 函数定义 *** void long_delay(void); // 长延时 void short_delay(void); // 短暂延时 void delay10ms(unsigned char); // 延时10MS void write7279(unsigned char, unsigned char); // 写入到HD7279 unsigned char read7279(unsigned char); // 从HD7279读出 void send_byte(unsigned char); // 发送一个字节 unsigned char receive_byte(void); // 接收一个字节 //*** 变量及I/O口定义 *** unsigned char digit[5]; unsigned char key_number, j, k,m,n; unsigned int tmr; unsigned long wait_cnter; unsigned char code dis_code[65] = {16,17,1,2}; unsigned char code dis_code1[256] = {0,1,2,3,4}; unsigned char code dis_code2[9] = {0,1,2,3,4,5,6,7,8}; unsigned char code dis_code3[65] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; unsigned char code dis_code4[256] = {0,1,2,3,4,5,6,7,8,9,10,11,12}; unsigned char code dis_code5[128] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; unsigned char code dis_code6[65] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; unsigned char code dis_code7[256] = {0,1,2,3,4,5,6,7,8,9,10}; unsigned char code dis_code8[128] = {0,1,2,3,4,5,6,7,8,9,10,11}; unsigned char code dis_code9[128] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; sbit cs=P1^4; // cs at P1.4 sbit clk=P1^5; // clk 连接于 P1.5 sbit dat=P1^2; // dat 连接于 P1.2 sbit key=P1^3; // key 连接于 P1.3 sbit S1=P0^0; // key 连接于 P1.3 sbit S2=P0^1; // key 连接于 P1.3 //****** HD7279A 指令 ****** #define CMD_RESET 0xa4 #define CMD_TEST 0xbf #define DECODE0 0x80 #define DECODE1 0xc8 #define CMD_READ 0x15 #define UNDECODE 0x90 #define RTL_CYCLE 0xa3 #define RTR_CYCLE 0xa2 #define RTL_UNCYL 0xa1 #define RTR_UNCYL 0xa0 #define ACTCTL 0x98 #define SEGON 0xe0 #define SEGOFF 0xc0 #define BLINKCTL 0x88 void write7279(unsigned char cmd, unsigned char dta) { send_byte (cmd); send_byte (dta); } unsigned char read7279(unsigned char command) { send_byte(command); return(receive_byte()); } void send_byte( unsigned char out_byte) { unsigned char i; 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_byte*2; } dat=0; } unsigned char receive_byte(void) { unsigned char i, in_byte; dat=1; // set to input mode long_delay(); for (i=0;i<8;i++) { clk=1; short_delay(); in_byte=in_byte*2; if (dat) { in_byte=in_byte|0x01; } clk=0; short_delay(); } dat=0; return (in_byte); } void long_delay(void) { unsigned char i; for (i=0;i<0x30;i++); } void short_delay(void) { unsigned char i; for (i=0;i<8;i++); } // ******* 延时n个1MS ******* // ******* 输入:n 延时个数 ******* void delay1ms(unsigned char n) { unsigned int i; while(n --) { for(i = 0;i < 125;i ++); // i ++ ,8μS 左右 } } // ******* 延时n个10MS ******* // ******* 输入:n 延时个数 ******* void delay10ms(unsigned char n) { unsigned int i; while(n --) { for(i = 0;i < 1250;i ++); // i ++ ,8μS 左右 } } void delay(void) { unsigned int n; for(n=0;n<10000;n++) ; } //*** 主程序 *** //*** 主程序 *** main() { unsigned char p; 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) //使用多分支选择语句 { case 1: 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; case 2: 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; } } } } |
| 发帖须知: 1,发帖请遵守《计算机信息网络国际联网安全保护管理办法》、《互联网信息服务管理办法》、 《互联网电子公告服务管理规定》、《维护互联网安全的决定》等法律法规。 2,请对您的言论负责,我们将保留您的上网记录和发帖信息。 3,在此发帖表示认同我们的条款,我们有权利对您的言论进行审核、删除或者采取其他在法律、地方法规等条款规定之内的管理操作。 |