AVR单片机按键程序

来源:本站
导读:目前正在解读《AVR单片机按键程序》的相关信息,《AVR单片机按键程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《AVR单片机按键程序》的详细说明。
简介:本按键程序为4X4支持长按.短按.并返回不同的按键值.可以拿来直接用,此程序经硬件验证过OK.

#include "global.h"

/*******************************************************************

按键控制流程

stateaction

0检测是否有按下

1消抖

2检测是否有按下

行扫描,列读取出健值,送出键值,并移至高4位

3行扫描,列读取出健值跟上一次比较.相同计时(2s)加一.计满转下一个状态(长按);

不同则转到1(组合键可以在这一状态下判断)

4行扫描,列读取出健值跟上一次比较.相同计时(100ms)加一.计满送出键值,不同则转到1

5按键弹起处理

**********************************************************************/

#define LPT 1200

#define LPT_SEND_DATA200

#define JUDGE_KEY_DOWN0

#define WAIT_KEY_STATE1

#define SEND_KEY_VALUE2

#define JUDGE_LOONG_PRESS3

#define LOONG_PRESS_ACTION4

#define KEY_UP_STATE5

#define key_port PORTC

#define key_dd DDRC

#define key_in PINC

#define key_IO 0xF0

//备配IO的输入输出.1为输出.O为输入

#define key_L 0xF0

//列输出来,低位输出

#define key_R 0x0F

//行输入,高位读入

unsigned char key_pin[]={0x10,0x20,0x40,0x80};

const unsigned char key_table[]={

0x00,0x01,0x02,0xff,0x03,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第一行

0x10,0x05,0x06,0xff,0x07,0xff,0xff,0xff,0x08,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第二行

0x20,0x09,0x0a,0xff,0x0b,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第三行

0x30,0x0d,0x0e,0xff,0x0f,0xff,0xff,0xff,0x10,0xff,0xff,0xff,0xff,0xff,0xff,0xff//第四行

};

volatile unsigned char key_value_old;

volatile unsigned int key_time;

volatile unsigned char state;

volatile unsigned char j;

unsigned char key_scan(void)

{

unsigned char j;

for(j=0;j<4;j++)

{

key_port =key_pin[j];

key_port = key_pin[j];

//_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

if( (key_in & key_R)!= 0x00 )

{

//return (key_table[j + key_in]);//i=0,5,10,15

//PORTD = key_table[i <<4 + key_in];

//PORTD = key_in;

//key_port = 0x0f;

//return j;

switch(key_in)

{

case 0b00010001: return 0;

break;

case 0b00100001: return 1;

break;

case 0b01000001: return 2;

break;

case 0b10000001: return 3;

break;

case 0b00010010: return 4;

break;

case 0b00100010: return 5;

break;

case 0b01000010: return 6;

break;

case 0b10000010: return 7;

break;

case 0b00010100: return 8;

break;

case 0b00100100: return 9;

break;

case 0b01000100: return 10;

break;

case 0b10000100: return 11;

break;

case 0b00011000: return 12;

break;

case 0b00101000: return 13;

break;

case 0b01001000: return 14;

break;

case 0b10001000: return 15;

break;

default:break;

}

}

}

key_port = key_IO;

return 0x00;

}

void key_deal(void)

{

key_port = key_IO;

key_dd = key_IO;

key_port = key_IO;

key_port = key_IO;

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

if( (key_in & key_R) !=0x00 )

{

switch(state)

{

case JUDGE_KEY_DOWN:

key_time = 0;

key_value= 0;

key_value_old = 0;

if(key_scan() != 0x00)//判断键有按下

{

state =WAIT_KEY_STATE;

}

else

{

state=KEY_UP_STATE;

}

break;

case WAIT_KEY_STATE :

if(key_f1ms_flag ==1)//消抖

{

key_f1ms_flag = 0;

key_time++;

if(key_time>10)

{

key_time=0;

state=SEND_KEY_VALUE;

}

}

break;

case SEND_KEY_VALUE:

if(key_value = key_scan())//送出键值

{

key_value_old = key_value;

state=JUDGE_LOONG_PRESS;

}

else

{

state=KEY_UP_STATE;

}

break;

case JUDGE_LOONG_PRESS:

if(key_value_old == key_scan())//判断键值是否相同

{

if(key_f1ms_flag ==1)

{

key_f1ms_flag = 0;

key_time++;

if(key_time >LPT)//长按计时

{

key_time=0;

state = LOONG_PRESS_ACTION;

}

}

}

else

{

state = JUDGE_KEY_DOWN;//键值不同重新判断

}

break;

case LOONG_PRESS_ACTION:

if(key_value_old == key_scan())

{

if(key_f1ms_flag ==1)

{

key_f1ms_flag =0;

key_time++;

if(key_time >LPT_SEND_DATA)

{

key_time=0;

key_value=key_value_old;//每100ms送出键值

}

}

}

else

{

state=JUDGE_KEY_DOWN;

}

break;

case KEY_UP_STATE:

key_time = 0;

//key_value= 0;

key_value_old = 0;

state = JUDGE_KEY_DOWN;

default:break;

}

}

else

{

key_time = 0;

//key_value= 0;

key_value_old = 0;

state = JUDGE_KEY_DOWN;

}

}

提醒:《AVR单片机按键程序》最后刷新时间 2024-03-14 00:58:47,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《AVR单片机按键程序》该内容的真实性请自行鉴别。