⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key_switch.c

📁 MEGA32L 单片机的按键,LED,LCD等测试例程,ICCAVR编译器
💻 C
字号:
//======================================
//按键输入模块源程序
//FileName =key_switch.c
//Date Time=20071214...20071215
//======================================
#include "key_switch.h"
#include "delay.h"

volatile struct	_st_judge_key	st_judge_key;	//按键判断使用的变量结构
volatile struct	_st_curr_key	st_curr_key;	//当前的按键标识,用于主程序流程转换

const	uchar	CONST_KEY_PORT_VAL_TO_LABEL[]={
	0x00,
	
	CONST_KEY_PORT_VAL_MENU,
	CONST_KEY_PORT_VAL_EXIT,
	CONST_KEY_PORT_VAL_UP,
	CONST_KEY_PORT_VAL_DOWN
};

//......................................
//本地按键端口数据值的读入
//返回:
//仅仅本地4按键的值,已经取反,有按键则对应的BIT位为高!
//......................................
static uchar	local_key_read(void)
{
	return(~PORTA &0xf0);	
}


//......................................
//输入:
//	port_val	按键端口值
//输出:
//	按键标志
//......................................
static uchar	change_and_get_key_label(uchar port_val)
{
uchar i;
	for(i=0; i<sizeof(CONST_KEY_PORT_VAL_TO_LABEL); i++)
	{
		if(port_val ==CONST_KEY_PORT_VAL_TO_LABEL[i])
		{
			return(i);
		}
	}
	return(CONST_KEY_LABEL_IDEL);
}

//......................................
//本地按键读入的判断,得到本地按键的端口数据值
//使用:
//	byte_key_step		按键步骤号
//	byte_key_delay_time	按键延时时间,单位:ms	
//	press_now_key_value	当键按下后的读出的按键键值
//	press_last_key_value	上次的按键键值
//	
//返回:
//	=1 当前存在按键(curr_get_key_value,curr_key_is_long) 
//	=0 当前没有按键,
//外面可以控制仅仅在前一按键标识处理后再读下一个按键
//......................................
//使用查询的方式进行按键端口的读入!
//按键使用Timer0进行时间延时计数,所以按键查询必须启动Timer0并允许中断!
static uchar	key_local_judge_press(void)
{
uchar	key_v;
	
	if( (key_v =local_key_read()) !=0)
	{	//存在按键
		st_judge_key.byte_key_delay_time =CONST_KEY_PRESS_DELAY;
		//按键延时
		while(st_judge_key.byte_key_delay_time !=0);
		if( (key_v =local_key_read()) ==0)
		{	//按键毛刺,忽略为没有按键
			return(0);
		}
		st_judge_key.press_now_key_value =key_v;

		if(st_judge_key.press_last_key_value ==st_judge_key.press_now_key_value)
		{	//重复按键			
			st_judge_key.byte_key_delay_time =CONST_KEY_CONTINUE_DELAY;
			while(st_judge_key.byte_key_delay_time !=0)
			{
				if( (key_v =local_key_read()) ==0)
				{	//按键在中间时刻已经弹起,认为是最后的长按键(防止连续长按键的最后出现同键值的短按键)
					st_judge_key.curr_key_is_long =1;
					st_judge_key.curr_get_key_value =st_judge_key.press_now_key_value;
					//清除重复按键判断寄存器
					st_judge_key.press_now_key_value =0x00;
					st_judge_key.press_last_key_value =0x00;					
					return(1);
				}
			};
			
			//是重复长按键
			st_judge_key.curr_key_is_long =1;
			st_judge_key.curr_get_key_value =st_judge_key.press_now_key_value;
			return(1);
		}
		else
		{	//非重复按键
			st_judge_key.byte_key_delay_time =CONST_KEY_CONTINUE_DELAY_FIRST;
			while(st_judge_key.byte_key_delay_time !=0)
			{
				if( (key_v =local_key_read()) ==0)
				{	//按键在中间时刻已经弹起,非长按键
					st_judge_key.curr_key_is_long =0;
					st_judge_key.curr_get_key_value =st_judge_key.press_now_key_value;
					//清除重复按键判断寄存器
					st_judge_key.press_now_key_value =0x00;
					st_judge_key.press_last_key_value =0x00;
					return(1);
				}
			};
			
			//是首次的长按键,保存按键值后自动退出
			st_judge_key.curr_key_is_long =1;
			st_judge_key.curr_get_key_value =st_judge_key.press_now_key_value;
			st_judge_key.press_last_key_value =st_judge_key.press_now_key_value;
			return(1);
		}
	}
	//没有按键
	return(0);
}


//......................................
//本地按键的综合判断,
//输入:
//	key_local_judge_press()的返回
//返回:
//	st_curr_key数据结构
//		flag_key_is_long_type
//		local_key_label
//输出:
//	=CONST_NOT_READ_KEY 没有按键, =CONST_HAS_READ_KEY 有按键发生
//......................................
uchar	judge_read_local_keys(void)
{
uchar key_label;		//按键标识
	
	key_label =CONST_KEY_LABEL_IDEL;
	if(key_local_judge_press() !=0)
	{	//存在按键输入
		key_label =change_and_get_key_label(st_judge_key.curr_get_key_value);		
	}
	else
	{	//没有按键
		key_label =CONST_KEY_LABEL_IDEL;	
	}
	
	st_curr_key.flag_key_is_long_type =st_judge_key.curr_key_is_long;	
	st_curr_key.local_key_label =key_label;
	return(CONST_HAS_READ_KEY);
}

//End Of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -