📄 2051模拟pc键盘程序.txt
字号:
2051模拟PC键盘程序
2051模拟PC键盘程序之主程序
#include <reg52.h>
#include <INTRINS.H>
#include <alignfir.h>
#include <alignkey.h>
#include <time.h>
#include <adtlc549.h>
#include <key.h>
#define TRUE 1
#define FALSE 0
#define T0_0P1MS11MHZ 164 /*256-11.0592/12*100*/
#define T0_0P05MS11MHZ 210 /*256-11.0592/12*50*/
#define BATGLASSMAX 8
code unsigned char BAT_GLASS[BATGLASSMAX]=
{
0x83, /*10-11.20v*/
0x84, /*-11.30v*/
0x85, /*-11.50v*/
0x86, /*-11.70v*/
0x88, /*-11.90v*/
0x8a, /*-12.10v*/
0x8c, /*-12.30v*/
0x8e /*>12.30v*/
};
code unsigned char BAT_PCCODE[BATGLASSMAX]=
{
0x4f, /*'a'*/
0x56, /*'b'*/
0x5e, /*'c'*/
0x08, /*'d'*/
0x10, /*'e'*/
0x18, /*'f'*/
0x20, /*'g'*/
0x28 /*'h'*/
};
/*
0x00-0x0F NoKey F9 F7 F5 F3 F1 F2 F12 d F10 F8 F6 F4 TABLE ' Y
0x10-0x1F e Alt LeftShift P Ctrl Q 1 z f q z S A W 2 [
0x20-0x2F g C X D E 4 3 \ h Space V F T R 5 ]
0x30-0x3F i N B H G Y 6 ^ j r M J U 7 8 -
0x40-0x4F k , K I O 0 9 ` l . / L ; P - a
0x50-0x5F m s ' t [ = b n CapsLock RightShift Enter ] u \ c v
0x60-0x6F U V w x y z BackSpace { | END } Left Home ~Δo
0x70-0x7F Ins Del Down 5 Right Up Esc NumLock F11 + PageDown - * PageUp
ScallLock T
*/
sbit ioKeyData=P3^0;
sbit ioKeyClk =P3^1;
sbit WatchDog =P3^2;
sbit iACOn =P3^3;
unsigned char T0_Task=0;
unsigned char T0_Data;
bit T0_Crc;
unsigned char T0_BitPoint;
unsigned char T0_Count;
//unsigned char PcResetCount;
//bit PcResetBit,PcResetFlag;
unsigned char ADHold;
bit ACOnFlag;
/*使用T0工作在100uS下的中断为模拟按键扫描值的发送*/
void Timer0_Init(unsigned char t0data)
{
TMOD|=0x2; /*T0自动装载方式.*/
TH0=t0data;
TL0=t0data;
TR0=1;
ET0=1;
PT0=1;
T0_Task=0;
// PcResetCount=0;
// PcResetBit=0;
// PcResetFlag=1; /*检测上电
复位PC发出的RESET用*/
}
void Timer0_Int(void) interrupt 1 using 1{ /*T0中断*/
/* if(PcResetCount>0){
PcResetCount--;
if(PcResetCount==0)PcResetBit=1;
}
*/
switch(T0_Task){
case 0: if(Align_BackFirNum()){
T0_Data=Align_ReadFirBuf(0);
if(ioKeyClk==0){
break; /*PC占用,退出*/
}
ioKeyData=0;
ioKeyClk =0;
T0_Task++;
}
break;
case 1: ioKeyClk=1;
T0_Crc=1;
T0_BitPoint=1;
T0_Count=8;
T0_Task++;
break;
case 2: if(ioKeyClk==0){
T0_Task=0;
break; /*PC占用,退出*/
}
if(T0_Data&T0_BitPoint){
ioKeyData=1;
T0_Crc=~T0_Crc;
}
else ioKeyData=0;
ioKeyClk=0;
T0_Task++;
break;
case 3: ioKeyClk=1;
T0_Count--;
T0_BitPoint<<=1;
if(T0_Count==0)T0_Task++;
else T0_Task--;
break;
case 4: if(ioKeyClk==0){
T0_Task=0;
break; /*PC占用,退出*/
}
ioKeyData=T0_Crc; /*crc bit*/
ioKeyClk=0;
T0_Task++;
break;
case 5: ioKeyClk=1;
T0_Task++;
break;
case 6: if(ioKeyClk==0){
T0_Task=0;
break; /*PC占用,退出*/
}
ioKeyData=1; /*stop bit*/
ioKeyClk=0;
T0_Task++;
break;
case 7: ioKeyClk=1;
T0_Count=5;
T0_Task++;
break;
case 8: T0_Count--;
if(T0_Count==0)T0_Task++;
break;
case 9: if(ioKeyClk){
T0_Data=Align_PopFirBuf();
T0_Task=0;
}
break;
}
}
/*返回电池对应PC的码*/
unsigned char Key_GetPcBatCode(unsigned char Bat_AD)
{
unsigned char i;
for(i=0;i<(BATGLASSMAX-1);i++){
if(Bat_AD<=BAT_GLASS)return(BAT_PCCODE); /*i*/
}
return(BAT_PCCODE);
}
/********************************************************************/
void main()
{
Align_Firinit(20); /*环行队列初始化,作为按键发送缓
冲*/
Align_Keyinit(16); /*环行队列初始化,作为按键发送缓
冲*/
key_init();
Timer0_Init(T0_0P1MS11MHZ);
Timer1_Init(T2_10MS11MHZ);
EA=1;
ACOnFlag=iACOn;
if(ACOnFlag){
Align_PushFirHead(0x1c); /*acon=1*/
}
else {
Align_PushFirHead(0x32); /*acon=0*/
}
ACOnTimer=20;
while(1){
WatchDog=~WatchDog;
if(ACOnFlag!=iACOn){
ACOnFlag=~ACOnFlag;
if(ACOnFlag){
Align_PushFirHead(0x1c); /*acon=1*/
}
else {
Align_PushFirHead(0x32); /*acon=0*/
}
ACOnTimer=20;
}
if(ACOnTimer==1){
ACOnTimer=0;
Align_PushFirHead(0xf0);
Align_PushFirHead(0x1c);
Align_PushFirHead(0xf0);
Align_PushFirHead(0x32);
}
/*
if(PcResetFlag){
if(ioKeyClk)PcResetCount=180;
if(PcResetBit){
PcResetCount=0;
PcResetFlag=0;
Align_PushFirHead(0xaa);
}
}
*/
if(SysTimer==0){
SysTimer=160;
/*160*10MS*/
/*返回电池对应PC的码*/
ADHold=Key_GetPcBatCode(AD_Once());
Align_PushFirBuf(ADHold);
ADFreeTimer=8;
}
if((ADHold>0)&&(ADFreeTimer==0)){
Align_PushFirBuf(0xf0);
Align_PushFirBuf(ADHold);
ADHold=0;
}
if(Align_BackKeyNum()){ /*发送键值*/
Align_PushFirBuf(Align_PopKeyBuf());
}
}
}
/***************************************************************/
2051模拟PC键盘程序之键扫描
/*按键扫描模块*/
/*在定时器0中调用KECHECK.C,检查按键值
定时器每10MS中断一次.
按标准键盘标准压入按键或释放按键值*/
/*按键缓冲区中,D7=0代表键值存储,D7=1代表保持时间,也代表按键松开*/
/*
0x00-0x0F NoKey F9 F7 F5 F3 F1 F2 F12 d F10 F8 F6 F4 TABLE ' Y
0x10-0x1F e Alt LeftShift P Ctrl Q 1 z f q z S A W 2 [
0x20-0x2F g C X D E 4 3 \ h Space V F T R 5 ]
0x30-0x3F i N B H G Y 6 ^ j r M J U 7 8 -
0x40-0x4F k , K I O 0 9 ` l . / L ; P - a
0x50-0x5F m s ' t [ = b n CapsLock RightShift Enter ] u \ c v
0x60-0x6F U V w x y z BackSpace { | END } Left Home ~Δo
0x70-0x7F Ins Del Down 5 Right Up Esc NumLock F11 + PageDown - * PageUp
ScallLock T
*/
/***************************************************************/
#include <reg52.h>
#include <alignkey.h>
#define LINEBIT 0xe /*扫描行线
输入位*/
#define KEYAMPL 5 /*按键保持
时间放大5倍*/
sbit kColOut0=P1^4;
sbit kColOut1=P1^5;
sbit kEnter =P3^7;
unsigned char KeyTask=0; /*按键扫描任务号*/
unsigned char kHoldCount; /*按键保持时间倍数的寄存器*/
unsigned char kHoldValue;
unsigned char kHoldTime;
#define KEYMAX 9
code unsigned char KeyScanTable[KEYMAX]={2,4,8,10,12,16,17,18,19};
code unsigned char KeyPcTable[KEYMAX] ={6,4,12,3,11,2,0x6b,0x74,0x5a};
unsigned char CoderTask=0; /*编码器扫描任务号*/
unsigned char CHoldValue=18;
unsigned char cHoldOld;
unsigned char cHoldScan=18;
#define CODERIO 0x30
unsigned char Key_GetScanCode(unsigned char d)
{
unsigned char i=0;
while(d!=KeyScanTable)i++;
kHoldValue=KeyPcTable;
return(kHoldValue); /*返回PC扫描码*/
}
/***********************************************************
键盘始终使用P1口中的口/
入口:colbits,使用P1口中的位,1有效.
bits,使用P1口中的位,1有效.
***********************************************************/
void key_init()
{
kColOut0=0;
kColOut1=0;
KeyTask=0;
CoderTask=0;
CHoldValue=P3&CODERIO;
}
void key_Scan()
{
unsigned char mTempLine;
switch(KeyTask){
case 0:
/*开始检查有无按键按下*/
if(((P1|(~LINEBIT))!=0xff)|(kEnter==0))KeyTask++;
break;
case 1: /*进行按键
去抖*/
KeyTask++;
break;
case 2: /*进行按键
去抖*/
KeyTask++;
break;
case 3:
/*进行按键扫描,保存键值*/
mTempLine=~(P1|(~LINEBIT));
if(mTempLine){
/*COL 1*/
kColOut1=1;
if((P1|(~LINEBIT))!=0xff){
kHoldCount=KEYAMPL;
kHoldTime=0;
Align_PushKeyBuf(Key_GetScanCode
(0*8+mTempLine));
kColOut1=0;
KeyTask++;
break;
}
/*COl 2*/
kColOut0=1;
kColOut1=0;
if((P1|(~LINEBIT))!=0xff){
kHoldCount=KEYAMPL;
kHoldTime=0;
Align_PushKeyBuf(Key_GetScanCode
(1*8+mTempLine));
kColOut0=0;
KeyTask++;
break;
}
kColOut0=0;
kColOut1=0;
}
else {
if(kEnter==0){
Align_PushKeyBuf(Key_GetScanCode(19));
kHoldCount=KEYAMPL;
kHoldTime=0;
KeyTask++;
break;
}
}
KeyTask=0;
/*未通过去抖*/
break;
case 4:
/*进行按键按下保持的时间计算*/
if(((P1|(~LINEBIT))==0xff)&&(kEnter==1))KeyTask++;
else {
kHoldCount--;
if(kHoldCount==0){
kHoldCount=KEYAMPL;
kHoldTime++;
if(kHoldTime>0x7f)kHoldTime=0x7f;
}
}
break;
case 5: /*进行按键
去抖*/
KeyTask++;
break;
case 6: /*进行按键
去抖*/
KeyTask++;
break;
case 7:
/*保存按键时间,释放值*/
if(((P1|(~LINEBIT))!=0xff)|(kEnter==0))KeyTask-=3;
else {
Align_PushKeyBuf(0xf0);
Align_PushKeyBuf(kHoldValue);
KeyTask=0;
}
break;
}
}
void Coder_Scan()
{
unsigned char mTemp;
switch(CoderTask){
case 0:
/*开始检查有无按键按下*/
if(CHoldValue!=(P3&CODERIO))CoderTask++;
break;
case 1:
/*进行按键扫描,保存键值*/
mTemp=P3&CODERIO;
if(mTemp!=CHoldValue){
switch(CHoldValue){
case 0x20: if(mTemp==0x0)cHoldScan=18; /*->*/
else if(mTemp==0x30)cHoldScan=17; /*<-*/
break;
case 0x0: if(mTemp==0x10)cHoldScan=18; /*->*/
else if(mTemp==0x20)cHoldScan=17; /*<-*/
break;
case 0x10: if(mTemp==0x30)cHoldScan=18; /*->*/
else if(mTemp==0x0)cHoldScan=17; /*<-*/
break;
case 0x30: if(mTemp==0x20)cHoldScan=18; /*->*/
else if(mTemp==0x10)cHoldScan=17; /*<-*/
break;
}
CHoldValue=mTemp;
cHoldOld=Key_GetScanCode(cHoldScan);
Align_PushKeyBuf(cHoldOld);
CoderTask++;
}
CoderTask=0;
break;
case 2:
/*自动释放*/
Align_PushKeyBuf(0xf0);
Align_PushKeyBuf(cHoldOld);
CoderTask=0;
break;
}
}
2051模拟PC键盘之定时
/***************************************************************
设置定时器2为系统时钟中断,单位10MS
注意:此中断定时精度不大,提供给时钟要求不高的地方,如键盘,
长时定时(如>0.1S),超时判断,闪烁处理,蜂鸣器等等.
如需精确定时,请使用T0
***************************************************************/
#include <reg52.h>
#include <key.h>
#define T2_10MS6MHZ 0 /*65536-(10*1000)/(12/6) */
#define T2_10MS11MHZ 1 /*65536-(10*1000)/(12/11.0584) */
#define T2_10MS12MHZ 2 /*65536-(10*1000)/(12/12) */
#define T2_10MS22MHZ 3 /*65536-(10*1000)/(12/22.1184) */
#define T2_10MS24MHZ 4 /*65536-(10*1000)/(12/24) */
#define T2_10MS33MHZ 5 /*65536-(10*1000)/(12/33.1752) */
#define T2_10MS40MHZ 6 /*65536-(10*1000)/(12/40) */
code unsigned int Time2Const[7]={
60536, /*65536-(10*1000)/(12/6) */
56321, /*65536-(10*1000)/(12/11.0584) */
55536, /*65536-(10*1000)/(12/12) */
47104, /*65536-(10*1000)/(12/22.1184) */
45536, /*65536-(10*1000)/(12/24) */
37890, /*65536-(10*1000)/(12/33.1752) */
32203 /*65536-(10*1000)/(12/40) */
};
unsigned char SysTimer;
unsigned char ADFreeTimer;
unsigned char ACOnTimer;
unsigned char T1L,T1H;
void Timer1_Init(unsigned char TimeCode){
union datastru{
unsigned int r_int;
unsigned char r_char;
}Data_Stru;
TMOD|=0x10;
Data_Stru.r_int=Time2Const[TimeCode];
T1H=TH1 = Data_Stru.r_char;
T1L=TL1 = *(&Data_Stru.r_char+1);
TR1=1;
ET1=1;
SysTimer=100;
ADFreeTimer=8;
ACOnTimer=0;
}
void timer1(void) interrupt 3 { /*T2中断*/
TH1=T1H;
TL1=T1L;
TR1=1;
if(SysTimer)SysTimer--;
if(ACOnTimer)ACOnTimer--;
/*按键检查*/
key_Scan();
/*编码器检查*/
Coder_Scan();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -