//***************************************************************
// File Name : keyboard.c
// Author : Coolbor Xie
// Created : 2009-11-13
// Modified :
// Edition : V0.0
// Revisor : ouluolin 2011-7-17
// Revision : V0.1
//***************************************************************
#ifndef _keyboard_c_
#define _keyboard_c_
#include <reg52.h>
#include <intrins.h>
#include "keyboard.h"
#include "datatype.h"
//***************************************************************
//端口定义
//PIN DESCRIPTION
//P17 P16 P15 P14
// | | | |
// \---\---\---\---P10 1 2 3 F1
// \---\---\---\---P11 4 5 6 F2
// \---\---\---\---P12 7 8 9 F3
// \---\---\---\---P13 * 0 # F4
//***************************************************************
#define KeyPort P1
#define key_state_0 0 //定义按键状态(基于状态机)
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define NO_key 0
INT8U flag_2ms;
INT8U flag_key_scan_timer_10ms;
INT8U key_scan_timer;
//***************************************************************
// Function : KeyBoardScan
// Input : none
// Output : Key Number
// 0~9、*、#:ASCII code
// F1、F2、F3、F4: (A、B、C、D) ASCII code
// Description : 4*4 matrix keyboard scanning Function
//
//***************************************************************
void Time0_init() //定时器0初始化
{
TMOD=0x01; //定时器T0,工作在方式1
IE =0x82; //允许定时器T0中断
TH0=0xF8;
TL0=0x30; //12M晶振,定时2ms
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Time0_int() interrupt 1 //定时器0中断子函数
{
TH0=0xF8;
TL0=0x30; //12M晶振,定时2ms
//flag_2ms = 1; // 此定时扫描可用来做其他的事
if (++key_scan_timer >= 5)
{
key_scan_timer = 0;
flag_key_scan_timer_10ms = 1;
}
}
INT8U KeyBoardScan(void) //线反转法扫描键盘
{
INT8U key_temp,temp1,temp2;
INT8U key_num = NO_key;
static INT8U key_status = key_state_0; //按键状态
KeyPort = 0x0f; // 列线全输出0,行线全输出1
//key_temp = KeyPort; // 检测行号
temp1 = KeyPort&0x0f; // 检测行状态并保存
KeyPort = 0xf0; // 列线全输出1,行线全输出0
//key_temp |= KeyPort; // 检测列号
temp2 = KeyPort&0xf0; // 检测列状态并保存
key_temp = temp1|temp2; //
KeyPort = 0xff;
switch(key_status)
{
case key_state_0:
if(key_temp != 0xff)
key_status = key_state_1;
break;
case key_state_1:
if(key_temp == 0xff)
key_status = key_state_0;
else
{
key_status = key_state_2;
switch(key_temp)
{
case 0x7e: //0111 1110
key_num = '1';
break;
case 0xbe: //1011 1110
key_num = '2';
break;
case 0xde: //1101 1110
key_num = '3';
break;
case 0x7d: //0111 1101
key_num = '4';
break;
case 0xbd: //1011 1101
key_num = '5';
break;
case 0xdd: //1101 1101
key_num = '6';
break;
case 0x7b: //0111 1011
key_num = '7';
break;
case 0xbb: //1011 1011
key_num = '8';
break;
case 0xdb: //1101 1011
key_num = '9';
break;
case 0xb7: //1011 0111
key_num = '0';
break;
case 0x77: //0111 0111
key_num = '*'; //*
break;
case 0xd7: //1101 0111
key_num = '#'; //#
break;
case 0xee: //1110 1110
key_num = 'A'; //F1
break;
case 0xed: //1110 1101
key_num = 'B'; //F2
break;
case 0xeb: //1110 1011
key_num = 'C'; //F3
break;
case 0xe7: //1110 0111
key_num = 'D'; //F4
break;
}
}
break;
case key_state_2: // 后面的语句都是为了等待按键释放
if(key_temp == 0xff)
key_status = key_state_3;
break;
case key_state_3:
if(key_temp == 0xff)
key_status = key_state_0;
else
key_status = key_state_2;
break;
}
return key_num;
}
main()
{
INT8U KeyNum;
Time0_init();
while(1)
{
if (flag_key_scan_timer_10ms == 1)
{
flag_key_scan_timer_10ms == 0;
KeyNum=KeyBoardScan();
}
}
}
#endif
//===============================END OF FILE==================================//
- 1
- 2
- 3
前往页