PS2键盘的设计---C51程序

发布者:CaptivatingGaze最新更新时间:2016-11-09 来源: eefocus关键字:PS2键盘  C51程序 手机看文章 扫描二维码
随时随地手机看文章
#include

#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
#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
#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 }
//--------------------------------------------------------------------------------------------------
// 函数名称: 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();
    }
}

关键字:PS2键盘  C51程序 引用地址:PS2键盘的设计---C51程序

上一篇:四相步进电机proteus仿真及程序
下一篇:矩阵式键盘扫描c程序

推荐阅读最新更新时间:2024-03-16 15:20

C51全局初始化及精确延时程序,51单片机精确延时程序
/********************************************************************************************************* * Initialization Program * QiZhao,2007 * All Rights Reserved * File : initial.h * By : QiZhao * Contact :zq1987731@163.com * * Version : V2.1 γ * Corrector : QiZhao * Date : 2008.2.1 (Last modified) * * Remarks :
[单片机]
P10点阵屏C51单片机程序
P10点阵屏C51程序 1/4扫描,四扫下行,1路16行,数据低OE高(04-P16-08) 适用于HUB12接口单色P10 串口模式0,普通左移,亮度速度可调,6个IO口,用的STC8F1K08,最多231个字 制作出来的实物图如下: 单片机源程序如下: #include STC8.H #include intrins.h #include string.h #define DATA P30 // #define CLOCK P31 //↑ ↓ #define ADDR_A P32 //↑ #define
[单片机]
P10点阵屏<font color='red'>C51</font>单片机<font color='red'>程序</font>
C51脉冲宽度检测程序
/********************************************** 315无线模块 PT2262 1.5M 270KHz 可以测出脉冲宽度 起始时间 5000us 高电平时间 490us 低 电平 时间 160us HH=1 LL=0 LH=F ***********************************************/ #include reg51.h typedef unsigned int uint; long plu; void delay(uint); main() { TMOD=0x09; //0x0000 1001b ET0=1;
[单片机]
C51单片机之定时器T2读秒程序+电路图
数码管部分的电路图 51单片机程序: #include reg52.h #define UCHAR unsigned char #define UINT unsigned int //sbit KEY=P3^2; UCHAR table = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; UINT conter; UCHAR timer; void inittime(void) { timer=0; conter=0; RCAP2L=0x00; RCAP2H=0x4
[单片机]
<font color='red'>C51</font>单片机之定时器T2读秒<font color='red'>程序</font>+电路图
C51填坑记:中断处理导致主程序函数参数改变
1.现象 平台:keil c51,中颖SH79F7019A 现象:在增加了一个中断处理逻辑后,发现主程序异常,断点调试发现某个函数的参数被改变了,程序使用了错误的数据导致逻辑出错。 2.排查 初步分析,可能原因如下: 1.参数寄存器(R0-R7)的值,被中断函数改变。 2.堆栈溢出。 2.1参数寄存器 首先排查参数寄存器(中断里面调用了函数,有参数传递)。通过仿真器观察中断函数汇编代码,发现在进入中断之前是对R0-R7进行了压栈操作的。进一步将中断有关的函数全部用“using”关键字知道不同的寄存器组,发现问题没有得到改善。到此可以排除参数寄存器原因。 2.2堆栈溢出 排除寄存器之后,进一步
[单片机]
<font color='red'>C51</font>填坑记:中断处理导致主<font color='red'>程序</font>函数参数改变
128x64液晶KS0108驱动程序(C51)
128x64液晶KS0108驱动程序(C51) /*------------------------------------------------------------------------------------------ 12864.c 128X64驱动程序 2.0 鞠春阳 ===========================================================================================*/ #include "absacc.h" #include "intrins.h" //自定义库 在"C:\comp51\UserLib"文件夹中 #i
[单片机]
CS5532 C51驱动程序
//The program for CS5532-ASZ //This is a 24bit ADC and PGIA //Made by OurWay and 2006/03/21 //#include reg51.h //#include intrins.h //根据实际情况定义 //sbit SDI5532 = P2^1; //sbit SDO5532 = P2^2; //sbit CLK5532 = P2^3; //sbit CS5532 = P2^0; //sbit ACC7 = ACC^7; //sbit ACC0 = ACC^0; //#define BYTE unsigned char //#define WOR
[单片机]
掉电保护和看门狗复位C51程序
这个是一个硬件看门狗和用at24c02保存掉电数据的程序,希望对大家有所帮助已经测试通过的. #include reg51.h #include "IIC.h" #define ADDR 0x20 //存储地址 sbit led1=P2^7; //掉电现象 sbit led2=P2^6; //看门狗复位现象 sbit WDI=P2^5; //喂狗位 uint watch=100; //喂狗次数 uchar wbuf,rbuf; //写数据读数据变量 bit flag=0; //掉电标志 /*******外部中断,下降沿触发**************/ void intinit() { EA=1; EX0
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved