这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» 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

{

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;

}

}

}





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

工程师
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 跳转至

回复

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