【解析新特性】300W单路输出工业电源>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 电子钢琴的按键扫描实现问题(50us内扫描74个按键)

共4条 1/1 1 跳转至

电子钢琴的按键扫描实现问题(50us内扫描74个按键)

助工
2019-07-30 19:09:50    评分

最近有个需求:检测琴键的按键速度。一个琴键有两个轻触开关,检测这两个轻触开关的时差就能实现按键速度。

用GD32F350CPU,50us定时扫描键盘,把按下的按键对应的速度通过USB发出去,裸机代码只做这两件事情。

实际测试扫描键盘的时间不到40us,现在的问题是:当同时按下全部的按键时,有时会扫描不到部分按键。同时按下的按键数比较少时,就不会发生上述问题。

洗耳恭听大家的建议和指导!


代码如下:


void Martrix_KB_Handle(void)

{

        uint8 idx;

        

        for(idx=0;idx<Matrix_KB_KeyNum;idx++)

        {

                switch (Keys[idx].State)

                {

            case State_NoteOFF:

                

                if ( PRE_NOTE_ON == Keys[idx].Cur_KeyStatus ) 

                {

                    Keys[idx].State = State_PreNoteON;

                }

                break;


           case State_PreNoteON://Front键先按下,velocity开始计数

                                

                Keys[idx].Note_Velocity.u32_velocity++;

                                

                if ( NOTE_ON == Keys[idx].Cur_KeyStatus )

                {

                        Keys[idx].State = State_NoteON;

                        #ifdef JLINK_RTT_DEBUG

                        SEGGER_RTT_printf(0,"%2d: ON%5d\r\n",idx+1,Keys[idx].Note_Velocity.u32_velocity);

                        #endif

                        if(Sys_Flag.Upload_Enable)

                        {

                                ON_FIFO.Note_Buffer[ON_FIFO.Idx_IN].num = idx;

                                    ON_FIFO.Note_Buffer[ON_FIFO.Idx_IN].velocity.u32_velocity  = Keys[idx].Note_Velocity.u32_velocity;

                                    ON_FIFO.Idx_IN++;

                                    if(ON_FIFO.Idx_IN==Buffer_Size) ON_FIFO.Idx_IN = 0;

                        }

                        Keys[idx].Note_Velocity.u32_velocity = 0;

                  }

                  else if ( NOTE_OFF == Keys[idx].Cur_KeyStatus ) //按下一半就松开的情况

                  {

                        Keys[idx].Note_Velocity.u32_velocity = 0;

                        Keys[idx].State = State_NoteOFF;

                  }

                  break;


                case State_NoteON:

                                

                        if ( PRE_NOTE_OFF == Keys[idx].Cur_KeyStatus )

                        {

                                Keys[idx].State = State_PreNoteOFF;

                        }

                        break;

                                

                case State_PreNoteOFF:

                        

                        Keys[idx].Note_Velocity.u32_velocity++;

                                

                        if ( NOTE_OFF == Keys[idx].Cur_KeyStatus )

                        {

                                Keys[idx].State = State_NoteOFF;

                                        

                                #ifdef JLINK_RTT_DEBUG

                                SEGGER_RTT_printf(0,"%2d:OFF%5d\r\n",idx+1,Keys[idx].Note_Velocity.u32_velocity);

                                #endif


                                if(Sys_Flag.Upload_Enable)

                                {

                                        OFF_FIFO.Note_Buffer[OFF_FIFO.Idx_IN].num = idx;

                                            OFF_FIFO.Note_Buffer[OFF_FIFO.Idx_IN].velocity.u32_velocity  = Keys[idx].Note_Velocity.u32_velocity;

                                            OFF_FIFO.Idx_IN++;

                                            if(OFF_FIFO.Idx_IN==Buffer_Size) OFF_FIFO.Idx_IN = 0;

                                }

                                Keys[idx].Note_Velocity.u32_velocity = 0;                                        

                        }

                        break;

                                

                        

                default:

                        break;

                }

                

        }

}



void Martrix_KB_Handle(void)

{

        uint8 idx;

        

        for(idx=0;idx<Matrix_KB_KeyNum;idx++)

        {

                switch (Keys[idx].State)

                {

            case State_NoteOFF:

                

                if ( PRE_NOTE_ON == Keys[idx].Cur_KeyStatus ) 

                {

                    Keys[idx].State = State_PreNoteON;

                }

                break;


           case State_PreNoteON://Front键先按下,velocity开始计数

                                

                Keys[idx].Note_Velocity.u32_velocity++;

                                

                if ( NOTE_ON == Keys[idx].Cur_KeyStatus )

                {

                        Keys[idx].State = State_NoteON;

                        #ifdef JLINK_RTT_DEBUG

                        SEGGER_RTT_printf(0,"%2d: ON%5d\r\n",idx+1,Keys[idx].Note_Velocity.u32_velocity);

                        #endif

                        if(Sys_Flag.Upload_Enable)

                        {

                                ON_FIFO.Note_Buffer[ON_FIFO.Idx_IN].num = idx;

                                    ON_FIFO.Note_Buffer[ON_FIFO.Idx_IN].velocity.u32_velocity  = Keys[idx].Note_Velocity.u32_velocity;

                                    ON_FIFO.Idx_IN++;

                                    if(ON_FIFO.Idx_IN==Buffer_Size) ON_FIFO.Idx_IN = 0;

                        }

                        Keys[idx].Note_Velocity.u32_velocity = 0;

                  }

                  else if ( NOTE_OFF == Keys[idx].Cur_KeyStatus ) //按下一半就松开的情况

                  {

                        Keys[idx].Note_Velocity.u32_velocity = 0;

                        Keys[idx].State = State_NoteOFF;

                  }

                  break;


                case State_NoteON:

                                

                        if ( PRE_NOTE_OFF == Keys[idx].Cur_KeyStatus )

                        {

                                Keys[idx].State = State_PreNoteOFF;

                        }

                        break;

                                

                case State_PreNoteOFF:

                        

                        Keys[idx].Note_Velocity.u32_velocity++;

                                

                        if ( NOTE_OFF == Keys[idx].Cur_KeyStatus )

                        {

                                Keys[idx].State = State_NoteOFF;

                                        

                                #ifdef JLINK_RTT_DEBUG

                                SEGGER_RTT_printf(0,"%2d:OFF%5d\r\n",idx+1,Keys[idx].Note_Velocity.u32_velocity);

                                #endif


                                if(Sys_Flag.Upload_Enable)

                                {

                                        OFF_FIFO.Note_Buffer[OFF_FIFO.Idx_IN].num = idx;

                                            OFF_FIFO.Note_Buffer[OFF_FIFO.Idx_IN].velocity.u32_velocity  = Keys[idx].Note_Velocity.u32_velocity;

                                            OFF_FIFO.Idx_IN++;

                                            if(OFF_FIFO.Idx_IN==Buffer_Size) OFF_FIFO.Idx_IN = 0;

                                }

                                Keys[idx].Note_Velocity.u32_velocity = 0;                                        

                        }

                        break;

                                

                        

                default:

                        break;

                }

                

        }

}





关键词: 电子钢琴     钢琴     按键     扫描    

助工
2019-07-30 22:28:14    评分
2楼

硬件电路是怎么样的?有加二极管吗?


助工
2019-07-30 22:32:36    评分
3楼

要是我就用嵌入汇编来写,否则时序和程序优化会出问题. 


工程师
2019-07-30 22:39:34    评分
4楼

程序挺长的,可读性较差

要是EEPW 页面展示效果好些,就更好了!


我补充一个问题: 按键机械抖动都不止50us? 一般不是需要10~20ms吗?



共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]