.
  • 作者:127.0.0.*
  • 2025/3/25 15:42:27
  • 中国面包师贴吧-楼主(阅:472/回: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,在此发帖表示认同我们的条款,我们有权利对您的言论进行审核、删除或者采取其他在法律、地方法规等条款规定之内的管理操作。
    内容:
    验证: 验证码,看不清楚?请点击刷新验证码 * 匿名发表需要进行验证!
     
           
    中国面包师贴吧-中国烘焙师贴吧- 弹性深蓝色可爱版右侧悬浮qq在线客服代码
    在线咨询 x
    有什么可以帮到您
    点击咨询
    -粤ICP备13040473号-2