⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2051模拟pc键盘程序.txt

📁 2051制作的键盘模拟程序
💻 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 + -