打印

菜鸟求教关于矩阵键盘扫描的疑惑?

[复制链接]
1796|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sinianzain|  楼主 | 2012-10-4 09:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sinianzain 于 2012-10-4 09:30 编辑

#include<reg52.h>
#include<string.h>
#include<intrins.h>     
#include"delay1ms.h"
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS=P2^4;     
sbit LCD_RW=P2^5;        
sbit LCD_EN=P2^6;      
void Init_LCD(void);  
uchar R_Key(void);
void Write_Com(uchar com);
void Write_Dat(uchar dat);
void Write_Char(uchar row,uchar site,uchar ch);      
void Write_String(uchar row,uchar site,uchar *str);

/*--------------------------------------------
                   主函数
--------------------------------------------*/
void main(void)
{
uchar disp,i,j;
Init_LCD();
Write_String(0,0,"Press any key!");/
while(1)
{
    disp=R_Key();
    if(disp)  
   {
        if(!i&&!j)     //每次光标到第一位是清屏(第一次只要能到该步,说明已经按键得到有效值,所以可以清屏)
        Write_Com(0x01);
        Write_Char(i,j,disp);
        j++;
        if(j==16)
       {
              j=0;
              i++;
              if(i==2)
                     i=0;
       }
   }
}
}
/*--------------------------------------------
                   初始化函数
--------------------------------------------*/
void Init_LCD(void)
{  
LCD_RW=0;                 //写操作模式
LCD_EN=0;                 //LCD不使能,在写命令和数据中均有使能步骤
Write_Com(0x38);      //工作模式(DL=1,8位接口;N=1,两行显示;F=0,5*7点阵)
Write_Com(0x0f);      //显示开关(D=1,显示开;C=1,光标开;B=1,闪烁开)
Write_Com(0x06);     //输入方式(I/D=1,数据操作后AC自增1;S=0,画面不移动)
Write_Com(0x01);    //清屏
}
/*--------------------------------------------
            写指令函数(按写的时序图)
--------------------------------------------*/
void Writ_Com(uchar com)
{
LCD_RS=0;
P0=com;  
_nop_();  
LCD_EN=1;
delay1ms(1);
LCD_EN=0;
}
/*--------------------------------------------
          写数字符串函数(按写的时序图)
--------------------------------------------*/
void Write_String(uchar row,uchar site,uchar *str)
{
    if(row==0)
        Write_Com(0x80+site);     //如果row为0,表示显示在第一行
    else
        Write_Com(0xc0+site);     //row为1(其他数字也行),显示在第二行
   while(*str)
        Write_Dat(*str++);
}
/*--------------------------------------------
          写数字符函数(按写的时序图)
--------------------------------------------*/
void Write_Char(uchar row,uchar site,uchar ch)
{

if(row==0)
    Write_Com(0x80+site);  
else
   Write_Com(0xc0+site);   
Write_Dat(ch);
}
/*--------------------------------------------
          写数数据函数(按写的时序图)
--------------------------------------------*/
void Writ_Dat(uchar dat)
{

LCD_RS=1;
P0=dat;
_nop_();
LCD_EN=1;
delay1ms(1);
LCD_EN=0;
}
/*--------------------------------------------
        按键发送字符串函数(按写的时序图)
--------------------------------------------*/
uchar R_Key(void)
{      
    static uchar row,rank,temp;

P1=0xff;
P1=0xf0;
if(P1!=0Xf0)
{
    delay1ms(10);
    if(P1!=0xf0)      
    row=P1;
    P1=0x0f;         
    if(P1!=0xf0)
    {
        delay1ms(10);
        if(P1!=0x0f)  
            rank=P1;   
    }
    temp=row|rank;
}

switch(temp)
{
   case 0x7e:return '0'; break;
case 0xbe:return '1'; break;
case 0xde:return '2'; break;
case 0xee:return '3'; break;
case 0x7d:return '4'; break;
case 0xbd:return '5'; break;
case 0xdd:return '6'; break;
case 0xed:return '7'; break;
case 0x7b:return '8'; break;
case 0xbb:return '9'; break;
case 0xdb:return 'A'; break;
case 0xeb:return 'B'; break;
case 0x77:return 'C'; break;
case 0xb7:return 'D'; break;
case 0xd7:return 'E'; break;
case 0xe7:return 'F'; break;
default  :return  0 ; break;
}
}


想用按键给LCD1602输入字符,输满后清屏。但是上面的程序只要按下一个按键,整个LCD上便全部显示那一个字符。把矩阵键盘扫描换成下列语句便达到了实验的目的。上面的矩阵键盘扫描用的是自己以前写的,估计当时没学好,肯定有不对的地方才会这样,请前辈指点,谢谢!

/*--------------------------------------------
        按键发送字符串函数(按写的时序图)
--------------------------------------------*/
uchar R_Key(void)
{      
   unsigned char row,rank,temp;   //行列值中间变量
   P1=0x0f;                                //行线输出全为0
   row=P1&0x0f;                         //读入列线值
   if(row!=0x0f)                          //先检测有无按键按下
   {
   delay1ms(10);                //去抖
   if((P1&0x0f)!=0x0f)
   {
   row=P1&0x0f;        //读入列线值
   P1=row|0xf0;         //输出当前列线值
   rank=P1&0xf0;       //读入行线值
   while((P1&0xf0)!=0xf0);//等待松开并输出  
   temp=row+rank;         //键盘最后组合码值  
   }
    }
switch(temp)
{
   case 0x7e:return '0'; break;
case 0xbe:return '1'; break;
case 0xde:return '2'; break;
case 0xee:return '3'; break;
case 0x7d:return '4'; break;
case 0xbd:return '5'; break;
case 0xdd:return '6'; break;
case 0xed:return '7'; break;
case 0x7b:return '8'; break;
case 0xbb:return '9'; break;
case 0xdb:return 'A'; break;
case 0xeb:return 'B'; break;
case 0x77:return 'C'; break;
case 0xb7:return 'D'; break;
case 0xd7:return 'E'; break;
case 0xe7:return 'F'; break;
default  :return  0 ; break;
}
}

相关帖子

沙发
sinianzain|  楼主 | 2012-10-4 09:56 | 只看该作者
想让前辈们说说两个扫描程序,感觉都对的啊。

使用特权

评论回复
板凳
forgot| | 2012-10-4 09:58 | 只看该作者
有什么问题吗?

使用特权

评论回复
地板
sinianzain|  楼主 | 2012-10-4 10:08 | 只看该作者
3# forgot 您好!我用第一个程序中的扫描时,按键按下,LCD上全屏显示按键对应的字符;用后面那个扫描时按哪个按键就出现单独的对应字母,直到满屏后清屏。为什么第一个扫描会出现这样的结果呢?我以前矩阵按键都是用的第一个个扫描,用在结合数码管上没出现什么问题。所以请前辈帮分析指点。

使用特权

评论回复
5
nongfuxu| | 2012-10-4 17:02 | 只看该作者
没有看明白LZ到底问题出在哪里。

使用特权

评论回复
6
菜鸟同学| | 2012-10-4 19:00 | 只看该作者
break纯属多余。

使用特权

评论回复
7
与时俱进| | 2012-10-4 22:01 | 只看该作者
都RETURN了,后面的break确实多余。

使用特权

评论回复
8
sinianzain|  楼主 | 2012-10-5 10:42 | 只看该作者
6# 菜鸟同学
对,多于了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

17

帖子

0

粉丝