本帖最后由 牛东 于 2014-3-21 12:11 编辑
结果是每次上电第一次按key_1,程序是按照设计的运行:消抖,先亮一盏,延时1秒两盏,再延时1秒亮三盏,松手全灭。
可是松手后第二次怎么按Key_1程序都没反应,要过几分钟或重新上电复位才行!!!晕啊!!搞了很久没搞定!!
#include <reg52.h>
#include "MacroAndConst.h"
#include "Timer.h"
#include "KeyProg.h"
void main(void)
{
uint8 KeyValue = KEY_NULL;
KeyInit() ;
Timer0Init();
EA = 1;
P0=0xff;
while(1)
{
GetKey(&KeyValue);
if(KeyValue == (KEY_VALUE_1 | KEY_DOWN)) P0 = 0xfe;
if(KeyValue == (KEY_VALUE_1 | KEY_LONG)) P0 = 0xfc;
if(KeyValue == (KEY_VALUE_1 | KEY_CONTINUE)) P0 = 0xf8;
if(KeyValue == (KEY_VALUE_1 | KEY_UP)) P0 = 0xf0;
if(KeyValue ==KEY_NULL) P0=0xff;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <reg52.h>
#include "MacroAndConst.h"
#include "Timer.h"
#define KEY_VALUE_1 0x0e //确定哪个键按下,键值
#define KEY_VALUE_2 0x0d
#define KEY_VALUE_3 0x0b
#define KEY_VALUE_4 0x07
#define KEY_NULL 0x0f
sbit io_key_1 = P3^0 ;
sbit io_key_2 = P3^1 ;
sbit io_key_3 = P3^2 ;
sbit io_key_4 = P3^3 ;
void KeyInit(void)
{
io_key_1 = 1 ;
io_key_2 = 1 ;
io_key_3 = 1 ;
io_key_4 = 1 ;
}
static uint8 KeyScan(void) //确定哪个键按下,键值
{
if(io_key_1 == 0)return KEY_VALUE_1 ;
if(io_key_2 == 0)return KEY_VALUE_2 ;
if(io_key_3 == 0)return KEY_VALUE_3 ;
if(io_key_4 == 0)return KEY_VALUE_4 ;
return KEY_NULL ;
}
//定义按键返回值状态(按下,长按,连发,释放)
#define KEY_DOWN 0x80
#define KEY_LONG 0x40
#define KEY_CONTINUE 0x20
#define KEY_UP 0x10
//定义按键状态
#define KEY_STATE_INIT 0
#define KEY_STATE_WOBBLE 1
#define KEY_STATE_PRESS 2
#define KEY_STATE_LONG 3
#define KEY_STATE_CONTINUE 4
#define KEY_STATE_RELEASE 5
void GetKey(uint8 *pKeyValue)
{
static uint8 s_u8KeyState =KEY_STATE_INIT ;
static uint16 s_u8KeyTimeCount = 0; //按键时间计数器
static uint8 s_u8LastKey = KEY_NULL ; //保存按键释放时候的键值
uint8 KeyTemp = KEY_NULL ;
KeyTemp =KeyScan() ;
switch(s_u8KeyState)
{
case KEY_STATE_INIT :
{
if(KEY_NULL != (KeyTemp))
{
s_u8KeyState = KEY_STATE_WOBBLE ;
}
}
break ;
case KEY_STATE_WOBBLE : //消抖
{
if(g_bSystemTime1Ms ) //系统1mS时标到
{
g_bSystemTime1Ms = 0 ;
s_u8KeyTimeCount++;
if(s_u8KeyTimeCount==10)
{
s_u8KeyTimeCount=0;
s_u8KeyState = KEY_STATE_PRESS ;
}
}
}
break ;
case KEY_STATE_PRESS :
{
if(KEY_NULL != (KeyTemp))
{
s_u8LastKey = KeyTemp ; //保存键值,以便在释放按键状态返回键值
KeyTemp |= KEY_DOWN ; //按键按下
s_u8KeyState = KEY_STATE_LONG ;
}
else
{
s_u8KeyState = KEY_STATE_INIT ;
}
}
break ;
case KEY_STATE_LONG :
{
if(KEY_NULL != (KeyTemp))
{
if(g_bSystemTime1Ms ) //系统1mS时标到
{
g_bSystemTime1Ms =0;
s_u8KeyTimeCount++;
if(s_u8KeyTimeCount==1000)
{
s_u8KeyTimeCount=0;
KeyTemp |= KEY_LONG ; //长按键事件发生
s_u8KeyState = KEY_STATE_CONTINUE ;
}
}
}
else
{
s_u8KeyState = KEY_STATE_RELEASE ;
}
}
break ;
case KEY_STATE_CONTINUE :
{
if(KEY_NULL != (KeyTemp))
{
if(g_bSystemTime1Ms ) //系统1mS时标到
{
g_bSystemTime1Ms =0;
s_u8KeyTimeCount++;
if(s_u8KeyTimeCount==1000)
{
s_u8KeyTimeCount=0;
KeyTemp |= KEY_CONTINUE ;
}
}
}
else
{
s_u8KeyState = KEY_STATE_RELEASE ;
}
}
break ;
case KEY_STATE_RELEASE :
{
s_u8LastKey |= KEY_UP ;
KeyTemp = s_u8LastKey ;
s_u8KeyState = KEY_STATE_INIT ;
}
break ;
default : break ;
}
*pKeyValue = KeyTemp ; //返回键值
}
//////////////////////////////////////////////////////////////////////////////////////////////////
#include<reg52.h>
#include "MacroAndConst.h"
bit g_bSystemTime1Ms = 0 ; // 1MS系统时标
void Timer0Init(void)
{
TMOD &= 0xf0 ;
TMOD |= 0x01 ; //定时器0工作方式1
TH0 = 0xfc ; //定时器初始值1MS
TL0 = 0x66 ;
TR0 = 1 ;
ET0 = 1 ;
}
void Time0Isr(void) interrupt 1
{
TH0 = 0xfc ; //定时器重新赋初值1MS
TL0 = 0x66 ;
g_bSystemTime1Ms = 1 ; //1MS时标标志位置位
}
再问一下!!我用定时器延时的方式可行吗??
一周热门 更多>