📄 ps2.txt
字号:
PS2键盘控制LCD1602(基于51单片机)
这个是主函数:
#include <reg52.h>
#include "LCD1602_4.h"
#include "ps2.h"
unsigned char key_bit=0,key_mem[10]={0};
void main()
{
unsigned char temp="0",i=0,j=0,y=0;
LCD_init(); //1602初始化
EA=1; //开总中断
IT0=1;
EX0=1; //开INT0中断
LCD_write_string(0,0,"Ready Go!"); //说明初始化成功
while(1)
{
if(BF) //如果有按键按下则放进缓冲区
{
j+=getchar(keycode); //去掉断码
if(j==2)
{
key_mem[key_bit]=ps2_key;//放进缓冲器
key_bit++;
j=0;
}
BF=0; //再开中断
EX0=1;
}
while(key_bit!=0) //缓冲区如果有键码,则显示
{
if(temp>0x0f && keycode!=102)//液晶换行
{
temp=0;
if(y==0)y++;
else {y=0;CLEARSCREEN;} //显示满屏幕则清屏
}
if(keycode==102) //如果有BackSpace按下则删掉前一个键
{
temp--;
LCD_write_char(temp,y,' ');
LCD_set_xy(temp,y);
}
else
{
LCD_write_char(temp,y,key_mem[0]);//显示缓冲区的键码
temp++;
}
for(i=0;i<key_bit;)
{
key_mem=key_mem[i+1];
i++;
}
key_bit--;
if(BF==1)break;
}
}
}
以下是1602的头函数:
//=========================1602液晶头文键=================//
#ifndef LCD1602_4_H
#define LCD1602_4_H
#include <reg52.h>
#include <intrins.h>
#define MSB 0x80 //读忙位
#define HIGH 1
#define LOW 0
//*****************************************
#define DATA_MODE 0x28 //LCD模式设置,0x28位四位数据线模式
#define OPEN_SCREEN 0x0f //打开LCD显示,有光标;0x0c没有光标
#define DISPLAY_ADDRESS 0x80 //写地址指令
#define CLEARSCREEN LCD_en_com(0x01) //清屏
//***********//LCD1602的接线//*****************************
#define LCDIO P0 //LCD1602的高四位接在P0口的高四位
sbit LCD1602_RS=P0^0; //RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
sbit LCD1602_RW=P0^1; //RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
sbit LCD1602_EN=P0^2; //E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
//**********************************************************************
void LCD_en_com(unsigned char command); //写命令指令
void LCD_en_dat(unsigned char temp); //写数据指令
void LCD_set_xy(unsigned char x, unsigned char y); //设置显示地址:X为横轴(0-15),Y为纵轴(0-1).
void LCD_write_char(unsigned x,unsigned char y,unsigned char dat); //写一个字符
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s);//写一个字符串
void LCD_write_int(unsigned char x,unsigned char y,unsigned int intdat); //写无字符型整形数
void LCD_init(void); //lcd初始化
void LCD_Read_BF(void); //LCD读忙信号
//**********************************************************************
/*
LCD1602.c
Created by Zhengxihui
email: zhengxihui0506@126.com
May 2007
*/
void LCD_Read_BF(void)
{
LCD1602_RW=HIGH; //RW 1
LCD1602_RS=LOW; //RS 0
LCD1602_EN=HIGH; //EN 1 读忙信号
LCDIO=LCDIO&0x0F|0xf0;
while(LCDIO&MSB);
LCD1602_EN=LOW;
}
void LCD_en_write(void) //EN端产生一个高电平脉冲,写LCD
{
LCD1602_EN=HIGH;
_nop_();
LCD1602_EN=LOW;
}
//*************************************
void LCD_en_com(unsigned char command)
{
LCD_Read_BF();
LCD1602_RS=LOW; //RS 0 写命令
LCD1602_RW=LOW; //RW 0
LCDIO&=0x0F;
LCDIO=command&0xf0 | LCDIO&0x0f; //先发送高四位数据
LCD_en_write();
command=command<<4;
LCDIO&=0x0F;
LCDIO=command&0xf0 | LCDIO&0x0f; //发送低四位数据
LCD_en_write();
}
//*********************************
void LCD_en_dat(unsigned char dat)
{
LCD_Read_BF();
LCD1602_RS=HIGH; //RS 1 写数据
LCD1602_RW=LOW; //RW 0
LCDIO &=0x0F;
LCDIO=dat&0xf0 | LCDIO&0x0f; //先发送高四位数据
LCD_en_write();
dat=dat<<4;
LCDIO &=0x0F;
LCDIO=dat&0xf0 | LCDIO&0x0f; //发送低四位数据
LCD_en_write();
}
//**************设置显示地址:X为横轴(0-15),Y为纵轴(0-1)********************
void LCD_set_xy(unsigned char x,unsigned char y)
{
unsigned char address;
x&=0x0f;
if(!y)
address=0x80+x;
else
address=0xc0+x;
LCD_en_com(address);
}
//***************写一个字符:X为横轴(0-15),Y为纵轴(0-1)**********
void LCD_write_char(unsigned x,unsigned char y,unsigned char dat)
{
LCD_set_xy(x,y);
LCD_en_dat(dat);
}
//****************写一个字符串***************************************
void LCD_write_string(unsigned char x,unsigned char y,const unsigned char *s)
{
LCD_set_xy(x,y);
while(*s)
{
LCD_en_dat(*s);
s++;
}
}
//****************写一个无字符整数***************************************
void LCD_write_int(unsigned char x,unsigned char y,unsigned int intdat)
{
unsigned char i="0",temp[5];
while(intdat/10 || intdat%10)
{
temp=intdat%10;
intdat/=10;
i++;
}
LCD_set_xy(x,y);
while(i)
{
i--;
LCD_en_dat(temp+0x30);
}
}
//*****//LCD的初始化函数(刚上电的时候一定要调用一次)//*********************
void LCD_init(void)
{
LCD_en_com(DATA_MODE); //设计四位数据线模式
LCD_en_com(DATA_MODE); //设计四位数据线模式
LCD_en_com(OPEN_SCREEN); //打开LCD显示
LCD_en_com(DISPLAY_ADDRESS);//设计首地址
CLEARSCREEN; //清屏
}
#endif
以下是PS2的驱动头函数:
//===========================ps2.h头文件=============================//
#ifndef PS2_H
#define PS2_H
sbit keydata="P3"^3;
sbit clk="P3"^2;
unsigned char times="0";
unsigned char i="0";
unsigned char keycode="0",ps2_key; //ps2_key用于存放接收到的键码
static unsigned char BF="0"; //标识是否有字符被收到
unsigned char code noshift[80][2]=
{
1 , 8,// { f9 }
3 , 4,// { f5 }
4 , 2,// { f3 }
5 , 0,// { f1 }
6 , 1,// { f2 }
7 ,11,// { f12 }
9 , 9,// { f10 }
13 ,25,// { tab }
20 ,27,// { ctrl }
17 ,28,// { alt }
41 ,29,// { space }
31 ,30,// { win }
12 , 3,// { f4 }
11 , 5,// { f6 }
10 , 7,// { f8 }
14 ,96,// { ` }
22 ,49,// { 1 }
28 ,97,// { a }
30 ,50,// { 2 }
33 ,99,// { c }
38 ,51,// { 3 }
37 ,52,// { 4 }
46 ,53,// { 5 }
47 ,31,// { winright}
54 ,54,// { 6 }
61 ,55,// { 7 }
62 ,56,// { 8 }
50 ,98,// { b }
35 ,100,// { d }
36 ,101,// { e }
43 ,102,// { f }
52 ,103,// { g }
51 ,104,// { h }
59 ,106,// { j }
58 ,109,// { m }
49 ,110,// { n }
21 ,113,// { q }
45 ,114,// { r }
27 ,115,// { s }
44 ,116,// { t }
60 ,117,// { u }
42 ,118,// { v }
29 ,119,// { w }
34 ,120,// { x }
53 ,121,// { y }
26 ,122,// { z }
65 ,44,// { , }
66 ,107,// { k }
67 ,105,// { i }
68 ,111,// { o }
69 ,48,// { 0 }
70 ,57,// { 9 }
73 ,46,// { . }
74 ,47,// { / }
75 ,108,// { l }
76 ,59,// { ; }
77 ,112,// { p }
78 ,45,// { - }
82 ,39,// { ' }
85 ,61,// { = }
84 ,91,// { [ }
91 ,93,// { ] }
88 ,26,// { caps }
93 ,92,// { \ }
90 ,32,// { enter }
120,10,// { f11 }
102,12,// { back }
224,13,// { home }
105,14,// { end }
125,15,// { pageup }
122,16,// { pagedown }
117,17,// { up }
114,18,// { down }
107,19,// { left }
116,20,// { right }
113,21,// { del }
112,22,// { insert }
225,23,// { pause }
118,24,// { esc }
131, 6,// { f7 }
};
unsigned char code addshift[47][2]=
{
14,126, // { ~ }
22, 33, // { ! }
30, 64, // { @ }
38, 35, // { # }
37, 36, // { $ }
46, 37, // { % }
54, 94, // { ^ }
61, 38, // { & }
62, 42, // { * }
70, 40, // { ( }
69, 41, // { ) }
78, 95, // { _ }
85, 43, // { + }
93,124, // { | }
84,123, // { { }
91,125, // { } }
76, 58, // { : }
82, 34, // { " }
65, 60, // { < }
73, 62, // { > }
74, 63, // { ? }
28 ,65,// { a }
50 ,66,// { b }
33 ,67,// { c }
35 ,68,// { d }
36 ,69,// { e }
43 ,70,// { f }
52 ,71,// { g }
51 ,72,// { h }
67 ,73,// { i }
59 ,74,// { j }
66 ,75,// { k }
75 ,76,// { l }
58 ,77,// { m }
49 ,78,// { n }
68 ,79,// { o }
77 ,80,// { p }
21 ,81,// { q }
45 ,82,// { r }
27 ,83,// { s }
44 ,84,// { t }
60 ,85,// { u }
42 ,86,// { v }
29 ,87,// { w }
34 ,88,// { x }
53 ,89,// { y }
26 ,90,// { z }
};
unsigned char getchar(unsigned char k) //转换键码为ASCII码
{
unsigned char j;
if(!i)
for(j=0;j<80;j++)
{
if(noshift[j][0]==k)
{ps2_key=noshift[j][1];return 1;}
}
else
for(j=0;j<47;j++)
{
if(addshift[j][0]==k)
{ps2_key=addshift[j][1];return 1;}
}
return 0;
}
void Keyboard_out(void) interrupt 0
{
if(times<9)
{
keycode=keycode>>1; //因键盘数据是低>>高,结合上一句所以右移一位
if(keydata) keycode="keycode" | 0x80; //当键盘数据线为1时为1到最高位
}
times++;
if(times>10)
{
times=0;
if(keycode==0xe0 || keycode==0xf0){}//return;}
else if((keycode==18 || keycode==89) && i==0)
{i=1;}
else if((keycode==18 || keycode==89) && i==1)
{i=0;}
else {EX0=0;BF=1;} //关中断等显示完后再开中断
//当中断11次后表示一帧数据收完,清变量准备下一次接收
//(注:如这里不用BF和关中断直接调Decode()
//则所Decode中所调用的所有函数要声明为再入函数)
}
// while(!clk); //等待PS/2CLK拉高
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -