关于4*4矩阵键盘与LCD1602显示问题

2020-02-05 08:54发布

LCD显示正常,就是在键盘输入的时候出现问题,一个按键按下会在液晶上显示多个数字,按住按键不放,会一直显示那个按键值……但是我需要的是输入一个按键只显示一个按键值!求牛人帮忙,谢谢了……
   
  程序代码:
#include<reg52.h>
#include <intrins.h>
#include <stdlib.h>       
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit BEEP = P3^7;
sbit RS = P2^0;         /*0:指令寄存器 1:数据寄存器*/
sbit RW = P2^1;         /*0:写选择 1:读选择*/
sbit EN = P2^2;         /*下降沿时LCD执行命令*/
uchar a[10] = {0,1,2,3,4,5,6,7,8,9};/*存随机数*/
uchar code dis1[] = {" Random Keyboard"};
uchar code dis2[] = {"    Design      "};
uchar code dis3[] = {"   Designed By  "};
uchar code dis4[] = {"     YYY        "};
uchar code dis5[] = {"  Please Enter  "};
uchar code dis6[] = {"  The Password  "};
uchar code dis7[] = {"0123456789"};                /*随机数显示*/
uchar code dis8[] = {"Enter:**********"};
/*******************************************************/
/**********************延时函数************************/
/*******************************************************/

void Delay(uint t)
{
        uint i,j;
        while(t--)
        for(i=0;i<75;i++);
                for(j=0;j<28;j++);       
}
/*******************************************************/
/*******************键盘扫描函数***********************/
/*******************************************************/
uchar Keys_Scan(void)
{
    uchar i, j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f};
    for(j = 0; j < 4; j++) { //循环四次
      P1 = Buffer[j];         //在P1高四位分别输出一个低电平
      temp = 0x01;            //计划先判断P1.0位
      for(i = 0; i < 4; i++) { //循环四次
        if(!(P1 & temp))      //从P1低四位,截取1位
          return (i + j * 4); //返回取得的按键值
        temp <<= 1;           //判断的位,左移一位
    } }
    return 16;                //判断结束,没有键按下,返回16
}


/*******************************************************/
/******************1602初始化函数*********************/
/*******************************************************/
/*************************************************************************
** 函数功能:LCD忙检查                                                                                                 **
** 入口参数:                                                                                                                         **
** 出口参数:LCD_Status                                                                                                     **
*************************************************************************/
uchar LCD_Busy()
{
        uchar LCD_Status;
        RS = 0;
        RW = 1;
        EN = 1;
        Delay(1);
           LCD_Status = P0;
        EN = 0;
        return LCD_Status;
}
/*************************************************************************
** 函数功能:向LCD写数据                                                                                                **
** 入口参数:dat                                                                                                                    **
** 出口参数:                                                                                                                        **
*************************************************************************/
void Write_Data(uchar dat)
{
        LCD_Busy();
        RS=1;
        RW=0;
        EN=0;
        P0=dat;
        EN=1;
        Delay(1);
        EN=0;       
}
/**************************************************************************
** 函数功能:向LCD写命令                                                                                                 **
** 入口参数:cmd                                                                                                                 **
** 出口参数:                                                                                                                         **
**************************************************************************/
void Write_LCD_Com(uchar cmd)
{
        LCD_Busy();
        RS=0;
        RW=0;
        EN=0;
        P0=cmd;
        EN=1;
        Delay(1);
        EN=0;       
}
/**************************************************************************
** 函数功能:设定LCD的显示位置                                                                                 **
** 入口参数:P                                                                                                                         **
** 出口参数:                                                                                                                         **
**************************************************************************/
void Set_LCD_POS(uchar p)
{
        Write_LCD_Com(0x80|p);       
}
/**************************************************************************
** 函数功能:按指定位置显示一个字符                                                                                 **
** 入口参数:X,Y,DData                                                                                                         **
** 出口参数:                                                                                                                         **
**************************************************************************/
void Display_LCD_OneChar(uchar X, uchar Y, uchar DData)
{
        Y &= 0x1;
        X &= 0xF;         /*限制X不能大于15,Y不能大于1*/
        if (Y) X |= 0x40; /*当要显示第二行时地址码+0x40;*/
        X |= 0x80;                   /*算出指令码*/
        Write_LCD_Com(X);   /*发命令字*/
        Write_Data(DData); /*发数据*/
}
/**************************************************************************
** 函数功能:在LCD上显示字符串                                                                                 **
** 入口参数:p,s                                                                                                                 **
** 出口参数:                                                                                                                         **
**************************************************************************/
void Display_LCD_String(uchar p,uchar *s)
{
        uchar i;
        Set_LCD_POS(p);
        for(i=0;i<16;i++)
        {
                Write_Data(s[i]);
                Delay(1);        
        }
}
/*************************************************************************
** 函数功能:LCD初始化                                                                                                        **
** 入口参数:                                                                                                                        **
** 出口参数:                                                                                                                        **
*************************************************************************/
void Init_LCD()
{       
        /* 开机画面初始化 */
        Write_LCD_Com(0x38);/*设置液晶工作模式,16*2行显示,5*7点阵,8位数据*/
        Delay(1);
        Write_LCD_Com(0x01);/*清屏*/
        Delay(1);
        Write_LCD_Com(0x06);/*整屏不移动,光标自动右移*/         
        Delay(1);
        Write_LCD_Com(0x0c);/*开显示不显示光标*/
        Delay(1);
        Display_LCD_String(0x00, dis1);       
        Display_LCD_String(0x40, dis2);
                  
        Delay(2000);
        Write_LCD_Com(0x38);
        Delay(1);
        Write_LCD_Com(0x01);
        Delay(1);
        Write_LCD_Com(0x06);         
        Delay(1);
        Write_LCD_Com(0x0c);
        Delay(1);
        Display_LCD_String(0x00, dis3);
        Display_LCD_String(0x40, dis4);

        Delay(2000);
        Write_LCD_Com(0x38);
        Delay(1);
        Write_LCD_Com(0x01);
        Delay(1);
        Write_LCD_Com(0x06);         
        Delay(1);
        Write_LCD_Com(0x0c);
        Delay(1);
        Display_LCD_String(0x00, dis5);
        Display_LCD_String(0x40, dis6);
        Delay(2000);
        Write_LCD_Com(0x38);
        Delay(1);
        Write_LCD_Com(0x01);
        Delay(1);
        Write_LCD_Com(0x06);         
        Delay(1);
        Write_LCD_Com(0x0c);
        Delay(1);
        }               

/*******************************************************/
/******************随机数产生函数*********************/
/*******************************************************/
void Random_Num()
{
        int i,j,k,m,b[10] = {0,1,2,3,4,5,6,7,8,9};
        for(i=0;i<10;i++)
        {
                k = TL0; /*取定时器的值*/
                m = k%(10-i);
/*在0~9的表中选一个数后,将后面的向前移,在9个数中随机选1个,依次循环*/
                a[i] = b[m];
                for(j=m;j<10;j++)
                        b[j] =b[j+1];
        }
}


void Osinit()
{
        uchar i;       
        Init_LCD();         /*调用液晶屏初始化子函数*/
    Delay(100);
        Write_LCD_Com(0x80+0x06);               
        for(i=0;i<10;i++)
          {
                Write_Data(dis7[a[i]]);        /*初次使用默认0123456789*/
        }
        Display_LCD_String(0x40, dis8);
}

void Beep()
{
        char i;
        for(i=0;i<100;i++)
        {
                BEEP = ~BEEP;
                Delay(1);
        }
        BEEP = 1;
}

void main(void)
{   int count=0;
    int Key_Num;                /*扫描得到的键号*/
    int Key_Temp;                /*键号暂存*/       
        Osinit();
        while(1)
        {Key_Temp=Keys_Scan();       
     Key_Num=Key_Temp;
         
         if(Key_Num==15)          
         {count=0;
          Display_LCD_String(0x40, dis8);}
         
     if((Key_Num>=0)&&(Key_Num<10))        /*数字键处理分支*/
                {
                       
                        if(count<10)                                        /*可以输入10位密码*/
                        {   
                            Write_LCD_Com(0xc0+0x06+count);
                                Write_Data(dis7[[Key_Num]]);
/*显示密码*/
                                count++;
                                if(count==10)
                        }               
                }

         }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。