PS2键盘的设计---C51程序
2016-11-09 来源:eefocus
#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();
}
}
下一篇:矩阵式键盘扫描c程序