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

📄 protocol.c

📁 利用89S51将6*6键盘转换成PS/2协议
💻 C
字号:
//接收子函数
#include <head.c>
#include <math.h>
volatile unsigned char bdata s_buf,r_buf; //发送缓冲区、接收缓冲区
volatile unsigned char data  last_s;      //上次发送字节
extern bit scan_on;              //扫描状态,main_t.c中定义
sbit s_buf0=s_buf^0;
sbit r_buf7=r_buf^7;
//新添加的变量
unsigned char data send_delay,delay_count;
volatile unsigned char bdata parity_buf;
sbit parity_buf0=parity_buf^0;
volatile unsigned char data first_delay,old_delay;//拍发速率、延迟时间
volatile unsigned char bdata scan_v,temp1,temp2;
sbit c0=scan_v^5;
sbit c1=scan_v^6;
sbit a0=scan_v^0;
sbit a1=scan_v^1;
sbit a2=scan_v^2;
sbit b0=scan_v^3;
sbit b1=scan_v^4;
sbit temp1_0=temp1^0;
sbit temp1_1=temp1^1;
sbit temp1_2=temp1^2;
sbit temp2_0=temp2^0;
sbit temp2_1=temp2^1;

void set_scan_v(unsigned char vv)//设置扫描速度(拍发速率、延迟时间)
//根据PS2协议,通过vv得到延缓时间first_delay和拍发速率old_delay的值
//系统缺省设置:拍发速率=10个/s±20%,延时=500ms±20%
//根据默认值是SCAN_V_DEFAULT 0x2c 00101100  first_delay=220,old_delay=44
/*每计数220个对应延时500ms,每1/440 s计数一次,如果系统频率为11MHz,也就是计数器每计到25000,
	增加一次计数值send_delay*/
{
 scan_v=vv;
 temp1=0;
 temp1_0=c0;
 temp1_1=c1;
 first_delay=(1+temp1)*60;
 first_delay=first_delay/6*Frequence;
 temp1=0;
 temp2=0;
 temp1_0=a0;
 temp1_1=a1;
 temp1_2=a2;
 temp2_0=b0;
 temp2_1=b1;
 old_delay=(8+temp1)*(1<<temp2);  
 old_delay=old_delay/6*Frequence;
/* unsigned char i,j;
  double cps;
  float code repeat_rate[32]={2.0,2.1,2.3,2.5,2.7,3.0,3.3,3.7,4.0,4.3,4.6,5.0,5.5,6.0,6.7,7.5,
8.0,8.6,9.2,10.0,10.9,12.0,13.3,15.0,16.0,17.1,18.5,20.0,21.8,24.0,26.7,30.0};
  i=(vv>>5)&0x03;
  j=vv&0x1f;
  first_delay=(unsigned char)((4/(i+1))*(Frequence/(12*TIMER_COUNT)));
  cps = 1 /((8 + (vv & 0x07)) * exp(log(2) * ((vv >> 3) & 0x03)) * 0.00417);
// old_delay=(unsigned char)(((repeat_rate[j]))*(Frequence/(12*TIMER_COUNT)));
*/
}

void set_default()//设置缺省值
{
  KBCLK=1;
  KBDATA=1;
  clr_buf();
  set_scan_v(SCAN_V_DEFAULT);//SCAN_V_DEFAULT==0X2C,在head.c中定义
}

bit parity()//计算parity_buf中一个字节的奇偶校验值
 {
  bit PARITY=1;
  unsigned char data c;
  for(c=0;c<8;c++)
    {
      PARITY^=parity_buf0;
      parity_buf=parity_buf>>1;
    }
  return PARITY; 
 }
 
void delay()//reentrant       //延时24us  
 {
   unsigned char data t=DELAY;
   for(;--t;);
 }

 void sleep()       //延时16us
 {
   unsigned char data t=SLEEP;
   for(;--t;);
 }

unsigned char receive(void)      //接收子函数
//返回接收到的字节,接收错误则返回0
{
    unsigned char data i;
    bit PARITY;
    ET1=0;  //定时器开
    r_buf=0;//清空接收缓存
    while(!KBCLK);//等待KBCLK变高
    delay(); 
    if(KBDATA)    //KBDATA应该为低,表示接收到起始位,如果此时KBDATA为高,
    	            //则退出并发送错误状态字0xfe 
     { send(0xfe);
       return 0;}
    delay();
    sleep();
    KBCLK=0;      //KBCLK由键盘控制,产生时钟信号
    for(i=0;i<8;i++)//将KBDATA上的数据在KBCLK的上升沿存入接收缓冲区r_buf7中
      {
        delay();
        sleep();
        KBCLK=1;
        sleep();
        if(!KBCLK) return 0; //如果KBCLK被拉低,表明主机取消发送
		r_buf7=KBDATA;
        if(i!=7)
           r_buf=r_buf>>1;
        delay();
        KBCLK=0;
      }
    delay();
    sleep();
    KBCLK=1;
    sleep();
    if(!KBCLK) return 0;   //如果KBCLK被拉低,表明主机取消发送    
    PARITY=KBDATA;         //接收奇偶校验位
    delay();
    KBCLK=0;
    delay();
    sleep();
    KBCLK=1;
	//停止位
    delay();
    if(!KBDATA) {send(0xfe);return 0;}//接收停止位,此时KBDATA应该为高,否则发送0xfe报错
    KBDATA=0;//发送应答位,表明已经收到主机数据
    sleep();
    KBCLK=0;
    sleep();
    delay();
    KBCLK=1; 
    sleep();
    KBDATA=1;//将KBCLK和KBDATA置高
    sleep();
    ET1=1;   //开中断
    parity_buf=r_buf;
    if(PARITY==parity())
           return r_buf;
    else {send(0xfe);return 0;}//判断奇偶校验位是否正确
	//缺错误处理 *
	//给主机时间抑制下次的通信
	sleep();
    delay();
}

bit send(unsigned char c)       //发送子函数
//返回1表示发送成功,返回0表示发送失败
/*当时钟线和数据线均为高电平时,允许键盘发送数据,系统将接收数据;
当时钟线被拉为低电平时,表明系统禁止数据传输。发送时序包含1个低
电平触发的起始位、8位数据位、1个奇校验位和1个高电平的结束位*/
{
    unsigned char data i;
    bit PARITY;
	KBCLK=1;
	if(!KBCLK)//主机禁止键盘发送数据
	  return 0;
    ET1=0;               //关闭中断
    parity_buf=c;
    PARITY=parity();//计算c的奇偶校验值
    last_s=c;       //保存上一次发送字节
    s_buf=c;        //发送数据缓冲

⌨️ 快捷键说明

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