📄 keyboard.c
字号:
#include"reg52.h"
#include "intrins.h"
#include "string.h"
#include "key.h" //按键通码与ascii对照表
#define uchar unsigned char
#define uint unsigned int
#define cmd_word 0xff //复位命令
sbit Clk_Line = P3^3; //时钟线
sbit Data_Line=P3^4; //键盘数据线
uchar key=0; //按键最终值
uint Key_Value=0;
uchar Int_Time=0;
uchar save=0;
uchar display[40];
uint num = 0;
uchar blank;
uchar flag;
uchar comf = 0x01;
//**************************************************************************
void init(void);
void delay(uint us); //us=12大约100us
void command(uchar cmd);
void interrupt1_receive(void);
void getkey(void) ;////内部中断0 用来处理缓冲区里的数据
void keyprocess(void);
void lcdclr(void);
//**************************************************************************
//Port Definitions**********************************************************
sbit LcdRs = P1^0;
sbit LcdRw = P1^1;
sbit LcdEn = P1^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
sbit LcdLight = DBPort^4;
void Delay1ms(unsigned int count)
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
while(DBPort&0x80); //或do{ACC=DBPort;} while(ACC_7==1); 忙信号??为1忙
LcdEn=0;
Delay1ms(1);
return ACC;
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND 0x00 // Command
#define LCD_DATA 0x01 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(unsigned char style, unsigned char input)
{
LcdRs=style;
LcdRw=0; _nop_();
LcdEn=1; _nop_();
DBPort=input; _nop_();
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//移动光标或屏幕************************************************************
#define LCD_CURSOR 0x02
#define LCD_SCREEN 0x08
#define LCD_LEFT 0x00
#define LCD_RIGHT 0x04
void LCD_Move(unsigned char object, unsigned char direction)
{
if(object==LCD_CURSOR)
LCD_Write(LCD_COMMAND,0x10|direction);
if(object==LCD_SCREEN)
LCD_Write(LCD_COMMAND,0x18|direction);
}
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
Delay1ms(80);
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
Delay1ms(10);
LCD_Write(LCD_COMMAND,0x38);
Delay1ms(10);
LCD_SetDisplay(LCD_SHOW|LCD_CURSOR); //开启显示, 无光标
//LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}
//************************************************************************
void GotoXY(unsigned char x, unsigned char y)//y是行 ,x是列
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
void LCD_LoadChar(unsigned char user[8], unsigned char place)
{
unsigned char i;
LCD_Write(LCD_COMMAND,0x40|(place*8));
for(i=0; i<8; i++)
LCD_Write(LCD_DATA,user[i]);
}
//************************************************************************
void lcdclr(void)
{
uchar clrstr[17];
uchar i = 0;
while(i < 16)
{
clrstr[i++] = ' ';
}
clrstr[i] = 0;
GotoXY(0, 0);
Print(clrstr); //在LCD上显示按键值
GotoXY(0, 1);
Print(clrstr); //在LCD上显示按键值
}
//************************************************************************
void main(void)
{
uchar thir=2;
init(); //初始化
LCD_Initial();
command(cmd_word);
delay(150);
while(1)
{
EX1=1;
while(EX1) ;
getkey();
keyprocess();
}
}
void init(void)
{
EA = 1;
IT1 = 1; //外部中断1是下降沿触发方式
}
void getkey(void)
{
uchar i=0;
//static uint num = 0;
save = Key_Value;
for(i=0;i<49;i++)
{
if(noshift[i][0] == save) //普按键的通码在缓冲区的第一位
{
key = noshift[i][1]; //搜索到字母后进行相应的处理
P2 = key;
if(num == 32)
{
//num = 0;
while(num)
{
display[--num] = 0;
}
blank = 0;
lcdclr();
}
display[num++] = key;
flag = 0;
break;
}
}
}
void keyprocess(void)
{
delay(10);
if((save == back)&&num)
{
flag = 0;
if(num == 16 && blank)
{
while(--blank)
{
display[--num] = 0;
GotoXY(num,0);
Print(" ");
}
}
else
{
display[--num] = 0;
if(num<16)
GotoXY(num,0);
else
GotoXY(num-16,1);
Print(" ");
}
}
if(num<=16)
{
if(save == enter)
{
flag = 0;
blank = 17 - num;
while( num < 16 )
{
display[num++] = ' ';
}
flag = 1;
}
else
{
GotoXY(0, 0);
Print(display); //在LCD上显示按键值
}
}
else
{
GotoXY(0, 1);
Print(display+16);
}
if(flag == 1)
{
GotoXY(0, 1);
}
}
void delay(uint us) //us=12大约100us
{
while(us--) ;
}
void interrupt1_receive(void) interrupt 2
{
_nop_();
if(Data_Line)
Key_Value|=0x8000;
Int_Time++;
if(Int_Time==11)
{
Key_Value>>=6;
Int_Time=0;
EX1=0;
}
Key_Value>>=1;
}
void command(uchar cmd)
{
uchar parity;
uchar i;
comf = 0x01;
parity=0;
Clk_Line=1;
Data_Line=1;
delay(100);
Clk_Line=0;
delay(20);
Data_Line=0;
Clk_Line = 1;
for(i=0;i<8;i++)
{
Clk_Line = 1;
while(Clk_Line);
Data_Line = 0;
if(cmd & (comf<<1))
{
Data_Line = 1;
parity++;
}
}
while(!Clk_Line) ;
while(Clk_Line) ;
if((parity&0x01))
Data_Line=0;
else Data_Line=1;
while(!Clk_Line) ;
while(Clk_Line) ;
Data_Line=1;
while(!Clk_Line);
while(Data_Line) ;
while(Clk_Line) ;
while(!Clk_Line) ;
while(!Data_Line);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -