最近有个需求:检测琴键的按键速度。一个琴键有两个轻触开关,检测这两个轻触开关的时差就能实现按键速度。
用GD32F350CPU,50us定时扫描键盘,把按下的按键对应的速度通过USB发出去,裸机代码只做这两件事情。
实际测试扫描键盘的时间不到40us,现在的问题是:当同时按下全部的按键时,有时会扫描不到部分按键。同时按下的按键数比较少时,就不会发生上述问题。
洗耳恭听大家的建议和指导!
代码如下:
void Martrix_KB_Handle(void)
{
uint8 idx;
for(idx=0;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 { 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; } } }