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

📄 keyboard.c

📁 S52单片机对PS/2键盘的主从通信
💻 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 + -