数码之家

 找回密码
 立即注册
搜索
查看: 3093|回复: 1

[C51] 单片机原理 C51 ,PROTUES仿真 键盘扫描 矩阵键盘电路

[复制链接]
发表于 2021-1-5 22:18:06 | 显示全部楼层 |阅读模式
本帖最后由 玛德陛下 于 2021-1-5 22:32 编辑



做的例8.34  



但是没有用8255, 按照上次做的数码管仿真改动了一下,

用 了51的P1,P2 口 和P0口的0,1。



编程语法之类的BUG 找了半个小时,最终还是通过了编译
加载 HEX 运行如图。
没有运行起来



硬件错误了,P0口得上拉电阻



但显示 如图了,任意按键就熄灭了。

但最终还是找到问题了,检测 按键 得屏蔽 P0的 2-7 口。



动态图

       

       


  1. #include<reg51.h>

  2. void delay(unsigned int);
  3. void display();
  4. unsigned char checkkey();
  5. unsigned char keyscan();

  6. unsigned char disbuffer[8]={0,0,0,0,0,0,0,0};


  7. void main()
  8. {

  9.        
  10.        
  11. unsigned char key;
  12.        

  13.        
  14.        
  15.                        
  16.                                
  17.                
  18.         while(1){   
  19.                 key=keyscan();
  20.     if(key!=0xff)
  21.     {
  22.       disbuffer[0]=disbuffer[1];               
  23.                         disbuffer[1]=disbuffer[2];               
  24.                         disbuffer[2]=disbuffer[3];               
  25.                         disbuffer[3]=disbuffer[4];               
  26.                         disbuffer[4]=disbuffer[5];               
  27.                         disbuffer[5]=disbuffer[6];               
  28.                         disbuffer[6]=disbuffer[7];               
  29.                         disbuffer[7]=key;               
  30.                 }display();
  31.                
  32.                        
  33.                        
  34.                        

  35.         }
  36. }
  37.        
  38. //----------延时函数----------------
  39. void delay(unsigned int i)
  40. {
  41.         unsigned int j;
  42.         for (j=0;j<i;j++){}
  43.         }
  44. //-----------显示函数---------------
  45.        
  46.        
  47.         void display ()
  48.         {
  49.                 unsigned char codevalue[16]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  50.                 unsigned char chocode[8]= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  51.                
  52.                 unsigned char  i,p,temp;
  53.                 for (i=0;i<8;i++)
  54.                 {
  55.                         temp=chocode[i];
  56.                         P2=temp;
  57.                         p=disbuffer[i];
  58.                         temp=codevalue[p];
  59.                         P1=temp;
  60.                         delay(20);
  61.                
  62.                        
  63.                 }
  64.         }
  65.        
  66.        

  67. //------------检测有没有键按下函数---------------

  68. unsigned char checkkey()
  69. {
  70.   unsigned char i;
  71.   P1=0x00;
  72.   i=P0;
  73.   i=i&0x03;  //屏蔽P0.2-7
  74.   if (i==0x03)return(0xff);
  75. else return (0);
  76. }




  77. //------------------键盘扫描函数--------------------

  78. unsigned char keyscan()
  79. {
  80.          unsigned char scancode; //列扫描码
  81.          unsigned char codevalue; //返回的编码
  82.         unsigned char m;          //行首编码
  83.         unsigned char k;           //行检测码   
  84.         unsigned char  i,j;
  85.         if(checkkey()==0xff)return(0xff); //检测有无键按下
  86.         else
  87.         {
  88.                 delay(20);
  89.                 if(checkkey()==0xff)
  90.                          return(0xff); //延时有无键按下
  91.                 else
  92.                 {
  93.                         scancode = 0xfe;    //列扫描码初值11111110
  94.                         for(i=0;i<8;i++)
  95.                         {
  96.                                 k=0x01;
  97.                                 P1=scancode;         //扫描 P1口
  98.                                 m=0x00;
  99.                                 for(j=0;j<2;j++)
  100.                                 {
  101.                                         if((P0&k)==0)   //检测行
  102.                                         {
  103.                                                 codevalue=m+i;  //按下 ,计算编码
  104.                                                 while(checkkey()!=0xff); //等按键释放
  105.                                         }
  106.                                         else
  107.                                         {
  108.                                                 k=k<<1;   //行左移
  109.                                            m=m+8;   //下一行行首编码
  110.                                         }
  111.                                 }
  112.                                 scancode=scancode<<1;  //列扫描码左移,扫描下一列
  113.                         }
  114.                 }
  115.                 return(codevalue);
  116.         }
  117. }
复制代码

  
代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 3家元 +44 收起 理由
jf201006 + 20 謝謝分享
wska + 20
zidian + 4

查看全部打赏

 楼主| 发表于 2021-1-5 22:55:02 | 显示全部楼层


改了一下,键盘 行扫描 复用 P2的0,1口。


仿真没有影响 显示如图。

  1. #include<reg51.h>

  2. void delay(unsigned int);
  3. void display();
  4. unsigned char checkkey();
  5. unsigned char keyscan();

  6. unsigned char disbuffer[8]={0,0,0,0,0,0,0,0};


  7. void main()
  8. {

  9.        
  10.        
  11. unsigned char key;
  12.        

  13.        
  14.        
  15.                        
  16.                                
  17.                
  18.         while(1){   
  19.                 key=keyscan();
  20.     if(key!=0xff)
  21.     {
  22.       disbuffer[0]=disbuffer[1];               
  23.                         disbuffer[1]=disbuffer[2];               
  24.                         disbuffer[2]=disbuffer[3];               
  25.                         disbuffer[3]=disbuffer[4];               
  26.                         disbuffer[4]=disbuffer[5];               
  27.                         disbuffer[5]=disbuffer[6];               
  28.                         disbuffer[6]=disbuffer[7];               
  29.                         disbuffer[7]=key;               
  30.                 }display();
  31.                
  32.                        
  33.                        
  34.                        

  35.         }
  36. }
  37.        
  38. //----------延时函数----------------
  39. void delay(unsigned int i)
  40. {
  41.         unsigned int j;
  42.         for (j=0;j<i;j++){}
  43.         }
  44. //-----------显示函数---------------
  45.        
  46.        
  47.         void display ()
  48.         {
  49.                 unsigned char codevalue[16]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  50.                 unsigned char chocode[8]= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  51.                
  52.                 unsigned char  i,p,temp;
  53.                 for (i=0;i<8;i++)
  54.                 {
  55.                         temp=chocode[i];
  56.                         P2=temp;
  57.                         p=disbuffer[i];
  58.                         temp=codevalue[p];
  59.                         P1=temp;
  60.                         delay(20);
  61.                
  62.                        
  63.                 }
  64.         }
  65.        
  66.        

  67. //------------检测有没有键按下函数---------------

  68. unsigned char checkkey()
  69. {
  70.   unsigned char i;
  71.   P1=0x00;
  72.   i=P2;
  73.   i=i&0x03;  //屏蔽P2.2-7
  74.   if (i==0x03)return(0xff);
  75. else return (0);
  76. }




  77. //------------------键盘扫描函数--------------------

  78. unsigned char keyscan()
  79. {
  80.          unsigned char scancode; //列扫描码
  81.          unsigned char codevalue; //返回的编码
  82.         unsigned char m;          //行首编码
  83.         unsigned char k;           //行检测码   
  84.         unsigned char  i,j;
  85.         if(checkkey()==0xff)return(0xff); //检测有无键按下
  86.         else
  87.         {
  88.                 delay(20);
  89.                 if(checkkey()==0xff)
  90.                          return(0xff); //延时有无键按下
  91.                 else
  92.                 {
  93.                         scancode = 0xfe;    //列扫描码初值11111110
  94.                         for(i=0;i<8;i++)
  95.                         {
  96.                                 k=0x01;
  97.                                 P1=scancode;         //扫描 P1口
  98.                                 m=0x00;
  99.                                 for(j=0;j<2;j++)
  100.                                 {
  101.                                         if((P2&k)==0)   //检测行
  102.                                         {
  103.                                                 codevalue=m+i;  //按下 ,计算编码
  104.                                                 while(checkkey()!=0xff); //等按键释放
  105.                                         }
  106.                                         else
  107.                                         {
  108.                                                 k=k<<1;   //行左移
  109.                                            m=m+8;   //下一行行首编码
  110.                                         }
  111.                                 }
  112.                                 scancode=scancode<<1;  //列扫描码左移,扫描下一列
  113.                         }
  114.                 }
  115.                 return(codevalue);
  116.         }
  117. }
  118.        
  119.        
复制代码
代码 如上。

应该是键盘扫描 有个首先有个按键 判断,基本不占时间,所以扫描显示没有什么影响,
但具体到 实际电路 不知道效果怎么样。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 2家元 +40 收起 理由
ljlun + 20 谢谢分享
wska + 20

查看全部打赏

回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-14 21:23 , Processed in 0.717601 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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