C语言,4*4矩阵按键按几数码管显示几 !注意模块化!! 急!!!!是C51的单片机

我复制进去不行啊、、、、、我要的是模块化饿 是矩阵4*4 也就是0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F 这16个键 按下其中一个按键如6号键 就在数码管中显示6

第1个回答  2012-12-14
如果情况一直这样,你先注意数码管的接法(共阴还是共阳),再者检查下电路焊接。来自:求助得到的回答
第1个回答  2012-12-14
这个不难:希望可以帮到您

/*****************************************************************
** function: 全部键值分行获取
** abstract:
******************************************************************/
u08 key_input( void )
{
u08 ret=0; //最终键值缓冲
u08 keyval[7];//各行键值缓冲值

keyval[0] =0;
keyval[1] =0;
keyval[2] =0;
keyval[3] =0;
keyval[4] =0;
keyval[5] =0;
ROW1 = 1;
ROW2 = 1;
ROW3 = 1;
ROW4 = 1;
ROW5 = 1;
// ROW6 = 1;
//扫描第1行
ROW1 = 0;
keyval[0] = key_input_row();
ROW1 = 1;
//扫描第2行
ROW2 = 0;
keyval[1] = key_input_row();
ROW2 = 1;
//扫描第3行
ROW3 = 0;
keyval[2] = key_input_row();
ROW3 = 1;
//扫描第4行
ROW4 = 0;
keyval[3] = key_input_row();
ROW4 = 1;
//扫描第5行
ROW5 = 0;
keyval[4] = key_input_row();
ROW5 = 1;
//扫描第6行
// ROW6 = 0;
// keyval[5] = key_input_row();
// ROW6 = 1;

if( keyval[0] >0 ) { ret = keyval[0]+10 ;}
if( keyval[1] >0 ) { ret = keyval[1]+20 ;}
if( keyval[2] >0 ) { ret = keyval[2]+30 ;}
if( keyval[3] >0 ) { ret = keyval[3]+40 ;}
if( keyval[4] >0 ) { ret = keyval[4]+50 ;}
// if( keyval[5] >0 ) { ret = keyval[5]+60 ;}

//复合键
// if( keyval[0] == _KEY_S1 && keyval[5] == _KEY_S22)
// {
// ret = _KEY_S1_S22 ;
// }
//如果有键按下响一次蜂鸣器
if(ret%10 >0)
{
// beep_once();
}

return ret;

}
//////////////////////////////////////////////////////////////////////////////
//按键扫描驱动,返回key的类型和键值,直接操作按键相关的全局变量
//按键扫描的状态机编程方法:有如下几种状态
//|--------20ms---------||------------100ms---------||----->=100ms----------
//state0----------------state1----------------------state2------state3------
//按键起始采样---------〉短按-------〉长按首次 --------〉长按循环
//////////////////////////////////////////////////////////////////////////////
//20081214 :在判断单击按键是否弹起时,原先采用本次扫描值与上次不同,现改为本次
// 扫描值为0;防止组合键时,一个键现行按下。执行了一次这个键的单击事件
// 然后才去执行组合键的功能。
// --------------------------------------------------------------------------

void key_scan(void) //按照10-50ms的间隔周期调用本函数,以便软件去抖

{
static u08 keystate=0; //状态机记录
static u08 keypre=0; //上次按键记录
static u08 keydowncnt=0;//记录按键有效按下的次数,用以区分长安首次与长安循环
static u08 keynow=0; //临时变量,用于按键端口读写,表征当前按键的键值

if( f20ms == FALSE)
{
goto exit;
}
else
{
f20ms = FALSE;
}
keynow = key_input(); //读取按键的瞬时值

switch ( keystate )
{
case 0: {
keypre=keynow;
keystate =1;
break;
}//首次按下
//////////////////////////////////////单击
case 1: {
if( keypre==keynow) //10-50ms去抖后判断是否真的按下
{
// keypre=keynow; //refresh the keypre for next judge
keystate =2; //swtich to next state
}
else
{
keystate=0; //keynow is invalid,state back to start
}
break;
}
//////////////////////////////////////长按首次
case 2: {
if( keypre==keynow )
{
keystate =2;
//此处计数器用于区分长按首次与长按循环
if( keydowncnt++ > LONG_PRESS_FIRST_OR_REPEAT)
{
keystate = 3;
keydowncnt = 0;
key.val = keynow;
key.type = LONG_PRESS_FIRST;
}
}
// 表明弹起,单击事件的结束条件
else if(keynow == 0 )
{
keystate = 0; //key up
keydowncnt = 0; //reset counter
key.val = keypre; //return 键值产生单击事件
key.type = SHORT_PRESS;
}
// 又有其他键按下 重新扫描,以便实现复合键功能时,降低同事按键的
// 难度,可以把一定间隔以内的按键先后按下,当作同时按下。
else
{
keystate = 0; //key up
keydowncnt = 0; //reset counter
key.val = _KEY_NOKEY; //return 键值产生单击事件
key.type = INVALID;
}
break;
}
/////////////////////////////////////长按重复
case 3: {
if ( keypre==keynow)
{
if( keydowncnt++ > LONG_PRESS_REPEAT_FRQ)
{
keydowncnt = 0;
key.val = keynow;
key.type = LONG_PRESS_REPEAT;
}
}
else
//if( keynow == _KEY_NOKEY ) 有问题 20090905
{
keystate = 0;//reset keystate
keydowncnt = 0;
key.val = _KEY_NOKEY;
key.type = INVALID;
}
break;
}
//////////////////////////////////还可以增加两个状态用于按键抬起的去抖////
default:
{
keystate = 0;
key.val = _KEY_NOKEY;
key.type = INVALID;
break;
}

}/////////switch
exit: return ;//返回

}追问

我复制进去不行啊、、、、、我要的是模块化饿 是矩阵4*4 也就是0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F 这16个键 按下其中一个按键如6号键 就在数码管中显示6

追答

呵呵 复制过去肯定要针对你的端口做改变的啊 。

本回答被提问者和网友采纳
第2个回答  2012-12-15
连电路都没有,楼上就可以写代码了,厉害啊。。。
第3个回答  2012-12-16
楼上的键盘扫描算法太复杂了。
相似回答