老题:按键复用功能扫描(atmega16)
拆了一个流量计想用上面的屏和按键,一看屏的io和按键是公用的
以前都是用的单功能键,为了用上那板子,终于学习了按键功能复用
/////按键复用程序
/////liuchengliaaa 201201 01 这里用的是PA口的高四位作按键PB0是检测口
/////在每次进中断都要重新配置端口方向,和数据,否则会影响lcd的读写
voidkey_scanff()
{
uchari;
//SFIOR&=~(1<<PUD); //上拉使能
KEY_IN_DDR&=~(1<<KEY_IN);
KEY_IN_PORT|=(1<<KEY_IN);//配置输入口
//当引脚配置为输入时,若PORTxn 为"1“,上拉电阻将使能 p49
KEY_OUT_DDR|=(1<<KEY_OUT_1)|(1<<KEY_OUT_2)|(1<<KEY_OUT_3)|(1<<KEY_OUT_4);//配置输出口
KEY_OUT_PORT|=(1<<KEY_OUT_1)|(1<<KEY_OUT_2)|(1<<KEY_OUT_3)|(1<<KEY_OUT_4);
NOP();
if((key_valid==0)&&(keyflag==0))
{
for(i=4;i!=0;i--)
{
switch(i) //依次把按键口置低
{
case 1:KEY_1_SCAN();break;
case 2:KEY_2_SCAN();break;
case 3:KEY_3_SCAN();break;
case 4:KEY_4_SCAN();break;
}
NOP();
if(KEY_YES)//按键检测
{
keypointer=i; //按键识别
key_valid=1;
}
if(key_valid)break; //如果有检测到按键,跳出for循环
}
}
else if((key_valid==1)&&(keyflag==0)) //有键按下
{
switch(keypointer) //消抖
{
case 1:KEY_1_SCAN();break;
case 2:KEY_2_SCAN();break;
case 3:KEY_3_SCAN();break;
case 4:KEY_4_SCAN();break;
}
NOP();
if(KEY_YES)//按键有效
{
keyflag=1; //有效按键标志
BEEP_ON(); //按键音
}
else //无效的按键
{
keycode=0;keyflag=0;
key_valid=0;
BEEP_OFF();
keycount=0;keypointer=0;
}
}
else if(keyflag==1)//等待按键是释放
{
keycount++;
if(keycount>=BEEPTIME)BEEP_OFF();//用于长按消音
if(keycount>=10000)keycount=0;
switch(keypointer)
{
case 1:KEY_1_SCAN();break;
case 2:KEY_2_SCAN();break;
case 3:KEY_3_SCAN();break;
case 4:KEY_4_SCAN();break;
}
NOP();
if(KEY_NO)//按键以释放
{
keycode=keypointer;//提取键值
BEEP_OFF();
if(keycount>=400)keyflag1=1;//大于4秒为长按键
else keyflag1=2;
keycount=0; keyflag=0; key_valid=0;keypointer=0;//计数回零
}
}
//SFIOR|=(1<<PUD); //关闭上拉电阻
KEY_IN_DDR|=(1<<KEY_IN);
KEY_IN_PORT&=~(1<<KEY_IN);//输出低电平,防止按键干扰lcd读写 20120103
KEY_OUT_PORT|=(1<<KEY_OUT_1)|(1<<KEY_OUT_2)|(1<<KEY_OUT_3)|(1<<KEY_OUT_4);//恢复原来的高电平状态
}
兄弟汇编版本的你有没有搞过啊??{:smile:}{:smile:} Hale_123 发表于 2013-6-24 19:15 static/image/common/back.gif
兄弟汇编版本的你有没有搞过啊??
原来搞过一点点51的汇编
avr的汇编没有搞过 用LCD数据线作按键输入不错
页:
[1]