?? 單片機鍵盤掃描之狀態機實現.doc
字號:
單片機鍵盤掃描之狀態機實現
************************************************************/
#ifndef _TYPE_H_
#define _TYPE_H_
//type define
#define UINT8 unsigned char
#define INT8 char
#define UINT16 unsigned int
#define INT16 signed int
#define UINT32 unsigned long
#define INT32 signed long
#define FLP32 float
#endif
/************************************************************
FileName: includes.h
Version :V1.0
Date: 2008.1.2
Description:
History:
<author> <time> <version > <desc>
************************************************************/
#ifndef _INCLUDES_H_
#define _INCLUDES_H_
//system header files
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
//user header files
#include "type.h"
#include "queue.h"
#include "key.h"
#define SYSTEM_FREQUENCY_HZ 8000000
#endif
/************************************************************
FileName: queue.h
Version :V1.0
Date: 2008.1.2
Description:
History:
<author> <time> <version > <desc>
************************************************************/
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include "type.h"
class CQueue
{
private:
INT8 *pBuf;
UINT16 BufLen;
INT8 *pHead;
INT8 *pTail;
UINT16 count;
public:
UINT8 IsQueueEmpty(void);
void QueueInit(INT8 *pBuffer,UINT16 len);
UINT8 AddInQueue(INT8 dat);
UINT8 RequestFrQueue(INT8 *pDat);
};
#endif
/************************************************************
FileName: queue.cpp
Version :V1.0
Date: 2008.1.2
Description:
management of queue
History:
<author> <time> <version > <desc>
************************************************************/
#include "includes.h"
UINT8 CQueue::IsQueueEmpty(void)
{
return 1;
}
void CQueue::QueueInit(INT8 *pBuffer,UINT16 len)
{
pBuf=pBuffer;
pHead=pBuf;
pTail=pBuf;
count=0;
BufLen=len;
}
UINT8 CQueue::AddInQueue(INT8 dat)
{
if(count<BufLen)
{
(*pTail++)=dat;
count++;
if(pTail==(pBuf+BufLen))
{
pTail=pBuf;
}
return 1;
}
else
{
return 0;
}
}
UINT8 CQueue::RequestFrQueue(INT8 *pDat)
{
if(count)
{
*pDat=(*pHead++);
if(pHead==(pBuf+BufLen))
pHead=pBuf;
count--;
return 1;
}
else
{
return 0;
}
}
/************************************************************
FileName: key.h
Version :V1.0
Date: 2008.1.2
Description:
History:
<author> <time> <version > <desc>
************************************************************/
#ifndef _KEY_H_
#define _KEY_H_
#include "type.h"
#define GET_KEY1_SIGNAL PINE&(0X01<<0X02)
#define GET_KEY2_SIGNAL PINE&(0X01<<0X03)
#define MSG_DOWN 0X01
#define MSG_UP 0X02
#define MSG_SHORT_CLICK 0X03
#define MSG_LONG_CLICK 0X04
class CSingleKeyManager
{
private:
#define KEY_STATE_IDLE 0X01
#define KEY_STATE_IS_DOWN 0X02
#define KEY_STATE_DOWN 0X03
#define KEY_STATE_IS_UP 0X04
UINT8 m_state;
UINT8 m_DownCount;
#define MAX_MSG_LENGTH 0X10
INT8 m_MsgBuf[MAX_MSG_LENGTH];
CQueue m_MessageQueue;
public:
CSingleKeyManager();
void StateChange(UINT8 LineHighLow);
UINT8 GetMsg(void);
};
#endif
/************************************************************
FileName: key.cpp
Version :V1.0
Date: 2008.1.2
Description:
key managerment
1.scan mode
2.short clicked
3.long clicked
4.more info refer to file:key.jpeg
History:
<author> <time> <version > <desc>
************************************************************/
#include "includes.h"
CSingleKeyManager::CSingleKeyManager()
{
m_state=KEY_STATE_IDLE;
m_DownCount=0;
m_MessageQueue.QueueInit(m_MsgBuf,MAX_MSG_LENGTH);
}
void CSingleKeyManager::StateChange(UINT8 LineHighLow)
{
switch(m_state)
{
case KEY_STATE_IDLE:
{
if(LineHighLow)
{
asm("nop");
// WriteLog("1H\n");
}
else
{
m_state=KEY_STATE_IS_DOWN;
// WriteLog("1L\n");
}
}
break;
case KEY_STATE_IS_DOWN:
{
if(LineHighLow)
{
m_state=KEY_STATE_IDLE;
// WriteLog("2H\n");
}
else
{
m_state=KEY_STATE_DOWN;
// WriteLog("2L\n");
if(!m_MessageQueue.AddInQueue(MSG_DOWN))
{
asm("nop");//error
// WriteLog("KEY QUEUE ERROR\n");
}
}
}
break;
case KEY_STATE_DOWN:
{
if(LineHighLow)
{
m_state=KEY_STATE_IS_UP;
// WriteLog("3H\n");
}
else
{
m_DownCount++;
if(m_DownCount==255)
m_DownCount=255;
// WriteLog("3L\n");
}
}
break;
case KEY_STATE_IS_UP:
{
if(LineHighLow)
{
// WriteLog("4H\n");
m_state=KEY_STATE_IDLE;
m_MessageQueue.AddInQueue(MSG_UP);
if(m_DownCount>(2000/SYSTEM_RHYTHM_MS))
{
// WriteLog("LONG\n");
m_MessageQueue.AddInQueue(MSG_LONG_CLICK);
m_DownCount=0;
}
else
{
// WriteLog("SHORT\n");
m_MessageQueue.AddInQueue(MSG_SHORT_CLICK);
m_DownCount=0;
}
}
else
{
// WriteLog("4L\n");
m_state=KEY_STATE_DOWN;
}
}
break;
default:
asm("nop");
}
}
UINT8 CSingleKeyManager::GetMsg(void)
{
INT8 msg;
if(m_MessageQueue.RequestFrQueue(&msg))
{
return msg;
}
else
{
return 0x00;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -