?? 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 + -