📄 keyscanf.c
字号:
/******************************************************************
* 文件名称: KeyScanf . c *
* 文件用途: 键盘扫描 *
* *
* *
* *
*******************************************************************/
#include "Public.h"
#include <absacc.h>
#include "W79E532.h"
/*********************端口地址************************************/
#define PortA8255 XBYTE[0x9000]
#define PortB8255 XBYTE[0x9001]
#define PortC8255 XBYTE[0x9002]
#define ControlReg8255 XBYTE[0x9003]
#define DLKCS1 ControlReg8255 = 0x02; ControlReg8255 = 0x03 //PC1由0变为1,产生上升沿信号锁存U1 数据
#define DLKCS2 ControlReg8255 = 0x04; ControlReg8255 = 0x05 //PC2由0变为1,产生上升沿信号锁存U1 数据
#define Init8255 ControlReg8255 = 0x90 //键盘扫描时8255控制字, PortA:方式0 , 输入; PortB:方式0 , 输出 ; PortC: 输出
#define CLR_PC0 ControlReg8255 = 0x00 //CLR PC0
#define SET_PC0 ControlReg8255 = 0x01 //SET PC0
#define MOVXClock 0x04 //MOVX指令的机械周期,用来调整外部I/O的读写 速度
/*********************函数声明************************************/
void KeyBoardInit();
uchar KeyCode();
uchar KeyScanf();
uint DelayWithKeyScanf(uint unCounter);
void LEDLight( uchar ucLEDData , uchar ucPort);
void LEDCLR( uchar ucLEDData , uchar ucPort);
/*********************函数主体************************************/
/*************************************************************************
* 函数名称: KeyBoardInit() *
* 函数用途: 初始化键盘 *
* 输入参数: *
* 无 *
* 输出参数: *
* 无 *
* *
**************************************************************************/
void KeyBoardInit()
{
#if CHIP82C55DIP==0
CKCON=MOVXClock;
#endif
Init8255; //初始化8255
PortB8255 = 0xFF; //LED全熄灭
DLKCS1; //LED0~7状态锁存U1 (LS273)
DLKCS2; //LED8~14状态锁存U2 (LS273)
#if CHIP82C55DIP==0
CKCON=0x01;
#endif
}
/*************************************************************************
* 函数名称: KeyCode() *
* 函数用途: 扫描键盘, 计算键码 *
* 输入参数: *
* 无 *
* 输出参数: *
* 键码 *
* *
**************************************************************************/
uchar KeyCode()
{
uchar ucRowCounter ;
uchar ucColumnCounter;
uchar ucCounter;
uchar ucScanfData;
uchar ucKeyFound;
uchar ucReadData;
#if CHIP82C55DIP==0
CKCON=MOVXClock;
#endif
PortB8255 = 0x00; //行线置低电平
CLR_PC0;
ucKeyFound= 0 ;
ucReadData=PortA8255; //读列线
if(ucReadData!= 0xFF) //不全为高电平则有键被按下
{
SET_PC0; //第8行置高电平
ucScanfData = 0x80; //初始化行线扫描数据,从第0行扫起(注:第0行为PB7)
for(ucCounter =0 ; ucCounter <8 ; ucCounter++) //扫描0~7行
{
PortB8255 = ~ucScanfData;
ucScanfData = ucScanfData >> 1;
if(PortA8255 !=0xFF) //找到行线
{
ucKeyFound++;
ucReadData = ~PortA8255;
ucRowCounter = ucCounter;
}
}// for(ucCounter = 0 ; ucCounter < 8 ; ucCounter++)
PortB8255=0xFF; //第0~7行置高电平
CLR_PC0; //扫描第8行
if(PortA8255 != 0xFF)
{
ucKeyFound++;
ucReadData = ~PortA8255;
ucRowCounter = ucCounter;
}
SET_PC0;
if(ucKeyFound == 1) //计算键码 //计算按键列号
{
ucKeyFound=0;
for(ucCounter=0 ; ucCounter < 8;ucCounter ++)
{
if((ucReadData & 0x01)== 0x1)
{
ucKeyFound++;
ucColumnCounter=ucCounter;
}
ucReadData = ucReadData >>1;
}
}//if(ucKeyFound == 1)
}//if(PortA8255 != 0xFF)
#if CHIP82C55DIP==0
CKCON=0x01;
#endif
if(ucKeyFound==1)
return(ucRowCounter * 8 + ucColumnCounter);
else
return(0);
}
/*************************************************************************
* 函数名称: KeyScanfe() *
* 函数用途: 扫描按键 *
* 输入参数: *
* 无 *
* 输出参数: *
* ucCode:键码 *
* *
**************************************************************************/
uchar KeyScanf()
{
uchar ucCounter;
uchar ucCode;
bit bKeyPress;
do
{
ucCode = KeyCode();
bKeyPress = 1 ;
for(ucCounter = 0 ; ucCounter < 50 ; ucCounter++) //重复扫描50次,以消抖
{
if( ucCode != KeyCode())
{
bKeyPress = 0;
break;
}
}
}while(bKeyPress == 0);
return(ucCode);
}
/*************************************************************************
* 函数名称: LEDLight() *
* 函数用途: 点亮LED *
* 输入参数: *
* ucLEDData: LED显示数据 *
* ucPort : 锁存器273的编号 *
* 输出参数: *
* 无 *
* *
**************************************************************************/
void LEDLight( uchar ucLEDData , uchar ucPort)
{
#if CHIP82C55DIP==0
CKCON=MOVXClock;
#endif
if(ucPort == 1) //uc273U1
{
uc273U1 = uc273U1 & ucLEDData;
PortB8255 = uc273U1;
DLKCS1;
}
else //uc273U2
{
uc273U2 = uc273U2 & ucLEDData;
PortB8255 = uc273U2;
DLKCS2;
}
#if CHIP82C55DIP==0
CKCON=0x01;
#endif
}
/*************************************************************************
* 函数名称: LEDCLR() *
* 函数用途: 熄灭LED *
* 输入参数: *
* ucLEDData: LED显示数据 *
* ucPort : 锁存器273的编号 *
* 输出参数: *
* 无 *
* *
**************************************************************************/
void LEDCLR( uchar ucLEDData , uchar ucPort)
{
#if CHIP82C55DIP==0
CKCON=MOVXClock;
#endif
if(ucPort == 1) //uc273U1
{
uc273U1 = uc273U1 | ucLEDData;
PortB8255 = uc273U1;
DLKCS1;
}
else //uc273U2
{
uc273U2 = uc273U2 | ucLEDData;
PortB8255 = uc273U2;
DLKCS2;
}
#if CHIP82C55DIP==0
CKCON=0x01;
#endif
}
/*************************************************************************
* 函数名称: DelayWithKeyScanf() *
* 函数用途: 带扫描键盘功能的延时 *
* 输入参数: *
* unCounter: 定时值 *
* 输出参数: *
* 无 *
* *
**************************************************************************/
uint DelayWithKeyScanf(uint unCounter)
{
uchar ucKeyCode;
uchar ucPrimary;
ucKeyCode = KeyScanf();
while(unCounter != 0 && (ucKeyCode == KeyScanf())) //按键不变则延时
{
ucPrimary=10;
while(ucPrimary--);
unCounter--;
}
return(unCounter);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -