找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 136|回复: 1
打印 上一主题 下一主题
收起左侧

关于单片机驱动ps2键盘

[复制链接]
跳转到指定楼层
楼主
ID:1092316 发表于 2024-4-6 09:09 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我只要简单的功能,按下一个按键,执行一个功能,如按下9,P30输出低电平。第二代码报错,第一个不会用。PS2读电脑键盘实验 数码管显示 只看楼主

*                 ID:487236 楼主
*                 2019-8-7 20:50 查看1538 回复0 收藏
*                 /****************************************************************************************
*                         PS2 读电脑键盘实验                              *
*                 连接方法 : P0口与J12连接 拔开跳线帽用杜邦线连接左针与P3.2右针与P1.6连接       *
*                 使用方法:用外部中断读取PS2键盘的数据 并在数码管上显示,此程序只处理数字键盘。    *
*                                                                            *
*                 其余按键功能用户可以自行扩展,为了程序简单便于阅读和学习,程序中没有使用奇偶校验,    *
*                 校验程序请自行添加。       *                                      *
*                                                                  *
*                 *****************************************************************************************/
*                 
*                 #include<reg52.h>   
*                 
*                 sbit LS138A=P2^2;
*                 sbit LS138B=P2^3;
*                 sbit LS138C=P2^4;
*                 
*                 sbit BEEP = P1^5;
*                 
*                 sbit Key_Data = P1^6 ; //定义键盘引脚
*                 sbit Key_CLK = P3^2; //使用外部中断
*                 
*                 /******************************************************************/
*                 /*      函数声明            */
*                 /******************************************************************/
*                 void Decode(unsigned char ScanCode);//解码子程序
*                 void delay(unsigned int i);  //函数声名
*                 void display();
*                 void beep();
*                 
*                 
*                 // 此表为 LED 的字模    // 0  1  2  3  4  5  6 7  8  9  A  b  c  d  E  -  L P  U  Hidden_ (20)
*                 unsigned char code Disp_Tab[] = { ~0xC0,~0xF9,~0xA4,~0xB0,~0x99,~0x92,~0x82,~0xF8,~0x80,~0x90,~0x88,~0x83,~0xC6,~0xA1,~0x86,~0xbf,~0xc7,~0x8c,~0xc1, ~0xff,~0xf7 };
*                 bit BF;            
*                 unsigned char KeyV;
*                 unsigned char LedNumVal;
*                 int KEY_val,IntNum;
*                 
*                 /******************************************************************/
*                 /*      主函数            */
*                 /******************************************************************/
*                 void main()
*                 {
*                 
*                 IT1 = 0;          //设外部中断1为低电平触发
*                 EA = 1;           //外部中断开
*                 EX0 = 1;          //开中断
*                 
*                 while(1)
*                 {
*                  if (BF)
*                   {
*                   if (KeyV != 240)beep();
*                     
*                    Decode(KeyV);  //解码
*                    
*                     }
*                   else
*                   EA = 1; //开中断   
*                     display();
*                 }
*                 
*                 }
*                 
*                 /******************************************************************/
*                 /*      外部中断读入信息          */
*                 /******************************************************************/
*                 void Keyboard_out(void) interrupt 0
*                 {
*                 if ((IntNum > 0) && (IntNum < 9))
*                  {
*                   KeyV = KeyV >> 1;      //因键盘数据是低>>高,结合上一句所以右移一位
*                   if (Key_Data)
*                     KeyV = KeyV | 0x80;    //当键盘数据线为1时到最高位
*                   }
*                   IntNum++;
*                   while (!Key_CLK);      //等待PS/2CLK拉高
*                 
*                   if (IntNum > 10)
*                    {
*                      IntNum = 0;      //当中断11次后表示一帧数据收完,清变量准备下一次接收
*                      BF = 1;        //标识有字符输入完了
*                       EA = 0;        //关中断等显示完后再开中断
*                       }
*                 
*                 }
*                 
*                 /******************************************************************/
*                 /*      解码信息            */
*                 /******************************************************************/
*                 void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码
*                 {
*                 
*                     switch (ScanCode)
*                         {
*                         case 0x70 :     // 当收到0xF0,Key_UP置1表示断码开始
*                           KEY_val = 0;
*                           break;
*                 
*                         case 0x69 :     
*                           KEY_val = 1;
*                           break;
*                 
*                         case 0x72 :     
*                           KEY_val = 2;
*                           break;
*                 
*                         case 0x7A :     
*                           KEY_val = 3;
*                           break;
*                 
*                         case 0x6B :     
*                           KEY_val = 4;
*                           break;
*                 
*                         case 0x73 :     
*                           KEY_val = 5;
*                           break;
*                 
*                         case 0x74 :     
*                           KEY_val = 6;
*                           break;
*                 
*                         case 0x6c :     
*                           KEY_val = 7;
*                           break;
*                 
*                         case 0x75 :     
*                           KEY_val = 8;
*                           break;
*                 
*                         case 0x7d :     
*                           KEY_val = 9;
*                           break;
*                 
*                        case 0x71 :
*                           
*                         //  dot = 0X7F;
*                           break;
*                  
*                   }
*                    
*                 
*                 BF = 0; //标识字符处理完了   
*                 }
*                 
*                 
*                 /***************************************************************************************/
*                 void display( )
*                 {
*                  unsigned char i;
*                  unsigned int LedOut[8];
*                 
*                  LedNumVal = KEY_val ;
*                 
*                    //显示键值
*                    LedOut[0]=Disp_Tab[KeyV%10000/1000];
*                  LedOut[1]=Disp_Tab[KeyV%1000/100];
*                  LedOut[2]=Disp_Tab[KeyV%100/10];
*                  LedOut[3]=Disp_Tab[KeyV%10];
*                    
*                    //显示对应的字符
*                    LedOut[4]=Disp_Tab[LedNumVal%10000/1000];   //千位
*                  LedOut[5]=Disp_Tab[LedNumVal%1000/100];//百位带小数点
*                  LedOut[6]=Disp_Tab[LedNumVal%100/10];       //十位
*                  LedOut[7]=Disp_Tab[LedNumVal%10];     //个位
*                     
*                  
*                    for( i=0; i<8; i++)
*                    {   P0 = LedOut[i ];
*                        
*                     switch(i)              
*                      {   
*                         case 0:LS138A=0; LS138B=0; LS138C=0; break;   
*                       case 1:LS138A=1; LS138B=0; LS138C=0; break;      
*                       case 2:LS138A=0; LS138B=1; LS138C=0; break;
*                       case 3:LS138A=1; LS138B=1; LS138C=0; break;
*                         case 4:LS138A=0; LS138B=0; LS138C=1; break;
*                         case 5:LS138A=1; LS138B=0; LS138C=1; break;
*                         case 6:LS138A=0; LS138B=1; LS138C=1; break;
*                         case 7:LS138A=1; LS138B=1; LS138C=1; break;
*                        
*                      }
*                     
*                       delay(50);
*                     }
*                 
*                 }
*                 
*                 /***************************************************************************************
*                 延时程序                                                   *
*                 ****************************************************************************************/
*                 void delay(unsigned int i)
*                 {
*                   char j;
*                   for(i; i > 0; i--)
*                   for(j = 200; j > 0; j--);
*                 }
*                 
*                 /***************************************************************************************
*                 蜂铃器发声                                                   *
*                 ****************************************************************************************/
*                 void beep()
*                 {
*                 unsigned char i;
*                 for (i=0;i<255;i++)
*                  {
*                  delay(5);
*                  BEEP=!BEEP;     //BEEP取反
*                  }
*                 BEEP=1;        //关闭蜂鸣器
*                 }
*                 














单片机学习笔记(八)PS/2电脑键盘 只看楼主

*                 ID:108531 楼主
*                 2016-3-12 16:47 查看3765 回复1 收藏
PS/2键盘是一种编码键盘,只需要一根数据线和一根时钟线就可以完成数据的输入。
实验程序设计为,按键盘上的"J"键,继电器闭合。
C语言源程序:
#include <reg52.h> //52单片机头文件包含
#include <intrins.h>//常用移位函数头文件包含
sbit key_data=P1^5; //定义键盘接口的数据脚
sbit key_clk=P3^2;//定义键盘接口的时钟脚
sbit JDQ=P2^4; //定义继电器连接引脚
bit BF=0; //定义位变量BF
unsigned char keyv=0; //定义无符号字符变量keyv并赋初值0
unsigned int intNum=0;//定义无符号整型变量intNum并赋初值0
unsigned char key_up=1;//定义无符号字符变量key_up并赋初值1
void ldedata(unsigned char scandata);//按键数据处理函数
void main() //主函数
{
    EA=1; //打开总中断
    EX0=1;//打开0号中断
    IT0=1;//中断方式为下降沿触发方式
    do{    //do-while循环
        if(BF)   //如果有键按下
            ldedata(keyv);//处理按键数据
        else
            EA=1;//否则打开中断
    }while(1); //总为真不断循环
}
void key_scan() interrupt 0  //中断函数键盘输入key_scan 中断入口0
{
    if((intNum>0)&&(intNum<9))    //如果intNum>0并且intNum<9 就执行if里面的语句
    {
        keyv=keyv>>1;     //将字符变量keyv右移一位
        if(key_data)      //判断key_data 是否为真 即是否有数据
            keyv=keyv|0x80;    //有就将keyv与0x80进行或运算再赋值给keyv
    }
    intNum++;//将intNum的值自加1
    while(!key_clk)//键值是否处理完
    if(intNum>10)//判断intNum是否大于10
    {
        intNum=0;//将intNum赋值为0
        BF=1;//将BF赋值为1
        EA=0;//关闭总中断
    }
}
void ldedata(unsigned char scandata) //键盘数据处理函数
{
    if(!key_up) //键盘松开时
    {
        switch(scandata){ //处理键盘数据
        case 0xf0://没按下任何键
            key_up=1;//按下
            break;//跳出
        case 0x12://左边SHIFT
            break;//跳出
        case 0x59://右边SHIFT
            break;//跳出
        default://缺省处理
            P1=~scandata;//将按下的键码输出给P2口驱动灯亮,因发光二极采用共阳级,所以取反输出
            if(scandata==0x3b)//当按下J键时
                JDQ=0;//打开继电器
            if(scandata==0x29){//当按下空格键时
                JDQ=1;//关闭继电器
            }
            break;//跳出
        }
    }
    else{ //否则
        key_up=0;//按键按下
        switch(scandata){//处理按键
        case 0x12://左边SHIFT
            break;//跳出
        case 0x59://右边SHIFT
            break;//跳出
        }    
    }
    BF=0;//标识字符表示处理完了
}
//实验结果 按下键盘j键继电器打开 按下空格键继电器关闭



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:301191 发表于 2024-4-8 00:59 | 只看该作者
顶一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表