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

📄 ps2键盘设计---c51.txt

📁 PS2键盘设计---C51程序
💻 TXT
字号:
PS2键盘的设计---C51程序

#include <reg51.H>
#define Frequence 11   //晶振频率单位是MHZ
#define DELAY 10*Frequence/6 //发送程序延时
#define SLEEP 8*Frequence/6  //发送程序延时
sbit KBCLK="P3"^0; //键盘时钟线
sbit KBDATA="P3"^1; //键盘数据线

bit bat(void);  //基本保证测试无错误返回0,有错返回1
unsigned char buf_length(); //返回缓冲区数据个数
bit command_s();  //键盘命令检查,有命令要接受返回1
void clr_buf(void); //清键盘缓冲区
void del_head(); //删除缓冲区头
unsigned char exist(unsigned char); 
//检查键盘缓冲区中是否有与参数相等数,有则返回位置,无则返回255

//bit emputy(); //检查键盘缓冲区是否空,是返回1
unsigned char get_head(); //取键盘缓冲区头,头指针不变

unsigned char get_head_f();
//取缓冲区头对应标记,标记为0表示对应键已经松下

bit insert(unsigned char,unsigned char);
//插入缓冲区,并设置对应标记,成功则返回1

void ini_timer01(); //定时器初始化
void receive_process(); //接收键盘命令并处理
void reset(); //软件复位
unsigned char scankb(unsigned char); //扫描第N行,返回列直
void send_buf();   //发送缓冲区扫描码

bit send_code(unsigned char _KeyNo,bit flag); 
//发送按键扫描码,flag=0发送断开码,flag=1发送接通码

bit send(unsigned char); //发送数据

void set_default(); //设置缺省值
void set_timer1(); //复位定时器1

void set_scan_v(unsigned char); //设置扫描速度(拍发速率、延迟时间)
void set_flag(unsigned char); //设置缓冲区对应标记
void set_led(unsigned char); //设置LED
void secret(unsigned char);
void scan(void);
unsigned char get_end();
bit emputy(void);

//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
#define KEY P1
unsigned char key_code;           //键值
unsigned char key_buf[8];         //按键缓冲区
unsigned char key_COUNT;          //按键计数器
unsigned char COUNT_TI;           //定时中断计数
//-----------------------变量声明---------------------------------------------------------------------
void system_init(void );         //初始化,设置定时器0的工作方式,供主程序调用
void TIMER0_SCANkey();           //定时器0中断处理函数
bit judge_hitkey();              //判断是否有键按下,有返回1,没有返回0
unsigned char scan_key();             //扫描键盘,返回键值(高四位代表行,低四位代表列)
void key_manage(unsigned char keycode); //按键处理
//...........每个按键对应一个处理程序
//--------------------------------------------------------------------------------------------------
// 函数名称: scan_key
// 函数功能: 扫描键盘,返回键值(高四位代表行,低四位代表列)
//            无键按下返回0
//--------------------------------------------------------------------------------------------------
unsigned char scan_key()              //扫描键盘,返回键值(高四位代表行,低四位代表列)
  {
   unsigned char scancode,keycode,keycode_line,keycode_row;
   scancode="0xF0";                      //列置低,行置高
   KEY="scancode";                       //输入扫描码,扫描行
   keycode_line=KEY;
   scancode="0xF0";                        //列置高,行置低
   KEY="scancode";                       //输入扫描码,扫描列
   keycode_row=KEY;
   keycode=(((keycode_line<<4)&0xF0)|(keycode_row&0x0F));
   return(keycode);
   }
//--------------------------------------------------------------------------------------------------
// 函数名称: Timer0_init()
// 函数功能: 初始化设置
//            设定INT0的工作方式
//--------------------------------------------------------------------------------------------------
void Timer0_init(void )  
             {
              TMOD="0x20"; //定时器0工作在方式2的定时模式
              ET0=1;     //定时器0中断允许
              TH0=0;
              TL0=0;
              TR0=1;     //定时器0开始计数
              EA="1";      //系统中断允许
              }
//--------------------------------------------------------------------------------------------------
// 函数名称: TIMER0_intrupt
// 函数功能: 定时器0中断处理程序 按键定时查询
//--------------------------------------------------------------------------------------------------
void TIMER0_SCANkey() interrupt 1 using 1
              {
               EA="0";                        //系统中断禁止
      if((++COUNT_TI)%30==0)
      {
      switch(COUNT_TI/30)
      {
       case 1:if(scan_key()==0) 
               COUNT_TI=0;          //无键按下,计数值归零
        break;
       case 2:break;
       case 3:if(scan_key()==0)
              COUNT_TI=0;           //无键按下,计数值归零,上次按键未扰动
        else 
        key_code=scan_key();  //又有效建,获取键值
       break;
          default:if(scan_key()==0)    //等待按键释放
              key_manage(key_code);  //有一个有效按键,调用按键处理程序
        }
     }
  EA=1;
      }
//--------------------------------------------------------------------------------------------------
// 函数名称: key_manage
// 函数功能: 有效按键处理
//            按键计数器加1,缓存区数据后移1位
//--------------------------------------------------------------------------------------------------
void key_manage(unsigned char keycode)
      {
      unsigned char i;
   for(i=7;i>=0;i--)
   {
    key_buf[i]=key_buf[i-1];       //缓冲区内数据后移1位
   }
   key_buf[0]= keycode;            //将键值送入缓冲区
      key_COUNT++;                   //按键计数器加一
   }


 

//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
#define KEY P1
sbit  DATA="P3"^1;       //数据线
sbit  CLK="P3"^2;        //时钟线
unsigned char key_buf[8];         //按键缓冲区
unsigned char key_COUNT;          //按键计数器
//--------------------------------------------------------------------------------------------------
// 函数名称: delay
// 入口参数: N
// 函数功能:延时子程序,实现(16*N+24)us的延时 
// 系统采用11.0592MHz的时钟时,延时满足要求,其它情况需要改动
//--------------------------------------------------------------------------------------------------
  void delay(unsigned  int N)  
  {
  int i; 
  for(i=0;i<N;i++);
  }
//--------------------------------------------------------------------------------------------------
// 函数名称: CAL_jiaoyan
// 函数功能: 计算校验位
//--------------------------------------------------------------------------------------------------
bit CAL_jiaoyan(unsigned char byte_data)
   {
   //
    }
//--------------------------------------------------------------------------------------------------
// 函数名称: SEND_byte
// 函数功能: 发送一子节数据
//--------------------------------------------------------------------------------------------------
void SEND_byte(unsigned char byte_data)
      {
  unsigned char i,temp;
   if(CLK==0)             //时钟线为低

   temp="byte"_data;
   CLK="1";
   DATA="0";
   delay(0);
   CLK="0";           //发送起始位
   for(i=0;i<8;i++)
      {
            delay(0);
         CLK="1";  
   DATA=(temp&0x01);  //发送数据
            byte_data=byte_data>>1;  
   delay(0);
   CLK=0; 
    }
      delay(0);
         CLK="1";  
   DATA=CAL_jiaoyan(byte_data); //发送校验位
          delay(0);
   CLK=0; 
             delay(0);
         CLK="1";  
   DATA=1;                     //发送结束位
          delay(0);
   CLK=0;  
   }
//--------------------------------------------------------------------------------------------------
// 函数名称: RECEIVE_byte
// 函数功能: 接收一子节数据
//--------------------------------------------------------------------------------------------------
unsigned char  RECEIVE_byte()
      {
     unsigned char byte_data,i;
   CLK="0";
   delay(0);
   CLK="1";                   //接收起始位,丢弃
   for(i=0;i<8;i++)
      {
            delay(0);
         CLK="0";  
   delay(0);
   CLK=1;
   byte_data=byte_data>>1;
   if(DATA=1)
            byte_data=byte_data|0x80;
   else 
   byte_data=byte_data&0x7F; //接收8位数据
     }
   for(i=0;i<2;i++)
      {
            delay(0);         //接收校验位和结束位
         CLK="0";  
   delay(0);
   CLK=1;
   }   
   return(byte_data);
 }
//--------------------------------------------------------------------------------------------------
// 函数名称: manage
// 函数功能: 主机命令处理函数
//--------------------------------------------------------------------------------------------------
void manage(unsigned char rec_data)
    {
 }
//--------------------------------------------------------------------------------------------------
// 函数名称: SEND_keydata
// 函数功能: 发送按键值到主机
//--------------------------------------------------------------------------------------------------
void SEND_keydata()
     {
  unsigned char ASCII_code;       //
  // ASCII_code=judge_key(key_buf[key_COUNT]);  //判断键值,按键编码成ASCII码
  SEND_byte(ASCII_code);
  key_COUNT--;
  }
//--------------------------------------------------------------------------------------------------
// 函数名称: 主程序
// 函数功能: 循环查询主机状态
//--------------------------------------------------------------------------------------------------
void main()
    {
 unsigned char rec_data;
 while(1)
 {
 if(CLK==0&&DATA==0)
    {
 rec_data=RECEIVE_byte();       //接收主机键盘
    manage(rec_data);              //指令处理函数
 }
 if(key_COUNT!=0&&CLK==1)     //有按键等待处理
                                       //线路空闲
   SEND_keydata();
    }
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -