微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 矩阵键盘控制lcd显示计算器哪出错了

矩阵键盘控制lcd显示计算器哪出错了

时间:10-02 整理:3721RD 点击:
#include <reg52.h>
#include <intrins.h>
#define PORT P0
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define NULL 0
uint shuzu[4];
uchar dis_buf,x,fuhao;
uint ad=0,rt;
ulong date,date1,date2,pass;
void display();
void display1();
void calculate();
uchar  a[9]={' ',' ',' ',' ',' ',' ',' ',' ',' '};
uchar code key_code[]={0xeb,0x77,0x7b,0x7d,0xb7,0xbb,0xbd,0xd7,0xdb,0xdd,
0x7e,0xbe,0xde,0xee,0xed,0xe7};        //4*4矩阵接键,分别显示0123456789ABCD#*
sbit EN=P2^7; //1602使能控制线
sbit RS=P2^6; //1602数据/指令选择控制线
sbit RW=P2^5; //1602读写控制线
/**延时处理程序,单位ms**/
void delayms (uint ms)         
{
   uint i;
   while(ms--)
  {
    //for(i=0;i<112;i++)  //11.0592M晶体
        for(i=0;i<120;i++)   //12M晶体
        {;}
  }
}
//*****lcd1602驱动******//
/**1602忙状态检测**/
void lcdbusy()
{
do{
    EN=0;
    RS=0;
    RW=1;
    PORT=0xff;
    EN=1;
        _nop_();
        }
  while(PORT&0x80);
    EN=0;
}
/**1602写命令函数**/
void lcdwcmd(uchar cmd)
{
  lcdbusy();
  RS=0;
  RW=0;
  EN=1;
  PORT=cmd;
  EN=0;
}
/**1602写数据函数**/
void lcdwdata(uchar dat)
{
  lcdbusy();
  RS=1;
  RW=0;
  EN=1;
  PORT=dat;
  EN=0;
}
/**LCD数据指针位置程序**/
void lcdpos(bit x, uchar y)
{                                               
        if(x)lcdwcmd(y|0xc0);        //x=1,第二行显示;x=0,第一行显示                0<=x<16
        else lcdwcmd(y|0x80);        //数据指针=80+地址码(00H~27H,40H~67H)
}
/**1602初使化**/
  void lcdint()
{
          lcdwcmd(0x38);                //设置LCD为16X2显示,5X7点阵,八位数据接口
        lcdwcmd(0x0c);                //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
        lcdwcmd(0x06);                //LCD开显示及光标设置(光标不闪烁,不显示"_")
        lcdwcmd(0x01);                //清除LCD的显示内容
}
/**按键扫描程序**/
void keyscan()
{
  uchar scan1,scan2,keycode,j,key;
  P1=0xf0;
  scan1=P1;
if(scan1!=0xf0)
  {
   delayms(100);
   scan1=P1;
   if(scan1!=0xf0)
   {
    P1=0xff;
    P1=0x0f;
    scan2=P1;
    keycode=scan1|scan2;
    for(j=0;j<16;j++)
    {
           if(keycode==key_code[j])
         {
          key=j;
      dis_buf=key;                     //键值入显示缓存
          dis_buf=dis_buf&0x0f;
          if(dis_buf==10)dis_buf=dis_buf-15;
          if(dis_buf==11)dis_buf=dis_buf-14;
          if(dis_buf==12)dis_buf=dis_buf-18;
          if(dis_buf==13)dis_buf=dis_buf-14;
          if(dis_buf==14)dis_buf=dis_buf-1;
          dis_buf=dis_buf+0x30;
          P1=0xf0;                                                 //判断是否按键已经按下
          while(P1!=0xf0);                                 
          }
     }
    }
         else dis_buf=240;                                  //        没有按键按下的时候给dis_buf为240
   }
}       
/**********求 data1  和  data2 的十进制值*******/
void jisuan1()
{
        date1=a[7]*10000000+a[6]*1000000+a[5]*100000+a[4]*10000+a[3]*1000+a[2]*100+a[1]*10+a[0];
}
void jisuan2()
{
        date2=a[7]*10000000+a[6]*1000000+a[5]*100000+a[4]*10000+a[3]*1000+a[2]*100+a[1]*10+a[0];
}
/**********将 十进制数转化为字符串  *************/
void change()
{
        pass=date;
        if(pass==0)
        a[0]=0;
        for(rt=0;pass!=0;rt++)
        {
                a[rt]=pass%10;
                pass/=10;
        }
       
         for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case 0:
                                                 a[rt]='0';break;
                                        case 1:
                                                 a[rt]='1'; break;
                                        case 2:
                                                 a[rt]='2'; break;
                                        case 3:
                                                 a[rt]='3'; break;
                                        case 4:
                                                 a[rt]='4'; break;
                                        case 5:
                                                 a[rt]='5';break;
                                        case 6:                  
                                                 a[rt]='6';break;
                                        case 7:
                                                 a[rt]='7'; break;
                                        case 8:
                                                 a[rt]='8';break;
                                        case 9:
                                                 a[rt]='9'; break;
                                        default:
                                                 a[rt]=' ';
                                 }
                      }
}
/**主函数**/

void main()
{
  lcdint();
   while(1)
  {
   keyscan();
   if(dis_buf!=240)                                                  // 当有键按下的时候
          {
            x=x+1;                                                                  // 每按下一次键更新一次显示
           calculate();
                                                                                  // 数据的更新
        if(ad==0)          
        {
                if(x==2)         {a[0]=dis_buf;a[1]=0x20;}         
           if(x==3)     {a[1]=a[0];a[0]=dis_buf;}
           if(x==4)         {a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==5)         {a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==6)         {a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==7)         {a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==8)         {a[6]=a[5];a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==9)         {a[7]=a[6];a[6]=a[5];a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
                }
                                                                                  // 数据的更新
                if(ad==1)          
                {       
                if(x==2)         {a[0]=dis_buf;a[1]=0x20;}         
           if(x==3)     {a[1]=a[0];a[0]=dis_buf;}
           if(x==4)         {a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==5)         {a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==6)         {a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==7)         {a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==8)         {a[6]=a[5];a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
           if(x==9)         {a[7]=a[6];a[6]=a[5];a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=dis_buf;}
                }
       display();
           dis_buf=240;                                                                        //         执行完一次键值后重新给键值240
           }
   }
  }
void calculate()
   {       
               if(dis_buf==0x2b)                                  //当按键的码值是0x7e(键盘上的a键)
                     {
                          lcdpos(1,0);                                   //  则在下面一行的开始显示“+”
                   lcdwdata(0x2b);
                            display1();                                        // 上一组数据全部搬到上面一行显示
                        for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case '0':
                                                 a[rt]=0;
                                                break;
                                        case '1':
                                                 a[rt]=1;break;
                                        case '2':
                                                 a[rt]=2;break;
                                        case '3':
                                                 a[rt]=3; break;
                                        case '4':
                                                 a[rt]=4;break;
                                        case '5':
                                                 a[rt]=5;break;
                                        case '6':
                                                 a[rt]=6; break;
                                        case '7':
                                                 a[rt]=7;break;
                                        case '8':
                                                 a[rt]=8;break;
                                        case '9':
                                                 a[rt]=9;break;
                                        default:
                                                 a[rt]=0;
                                                 }
                                        fuhao=1;
                        }
                                jisuan1();
                        for(rt=0;rt<10;rt++)
                         a[rt]=' ';       
                                ad=1;
                                x=1;
                         }       
                          if(dis_buf==0x2d)                                  //------------------------
                     {
                          lcdpos(1,0);                                   //  则在下面一行的开始显示“-”
                   lcdwdata(0x2d);
                            display1();                                        // 上一组数据全部搬到上面一行显示
                        for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case '0':
                                                 a[rt]=0;
                                                break;
                                        case '1':
                                                 a[rt]=1;break;
                                        case '2':
                                                 a[rt]=2;break;
                                        case '3':
                                                 a[rt]=3; break;
                                        case '4':
                                                 a[rt]=4;break;
                                        case '5':
                                                 a[rt]=5;break;
                                        case '6':
                                                 a[rt]=6; break;
                                        case '7':
                                                 a[rt]=7;break;
                                        case '8':
                                                 a[rt]=8;break;
                                        case '9':
                                                 a[rt]=9;break;
                                        default:
                                                 a[rt]=0;
                                                 }
                                           fuhao=2;
                        }
                                jisuan1();
                        for(rt=0;rt<10;rt++)
                         a[rt]=' ';       
                                ad=1;
                                x=1;
                         }       
                          if(dis_buf==0x2a)                                  //********************************
                     {
                          lcdpos(1,0);                                   //  则在下面一行的开始显示“*”
                   lcdwdata(0x2a);
                            display1();                                        // 上一组数据全部搬到上面一行显示
                        for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case '0':
                                                 a[rt]=0;
                                                break;
                                        case '1':
                                                 a[rt]=1;break;
                                        case '2':
                                                 a[rt]=2;break;
                                        case '3':
                                                 a[rt]=3; break;
                                        case '4':
                                                 a[rt]=4;break;
                                        case '5':
                                                 a[rt]=5;break;
                                        case '6':
                                                 a[rt]=6; break;
                                        case '7':
                                                 a[rt]=7;break;
                                        case '8':
                                                 a[rt]=8;break;
                                        case '9':
                                                 a[rt]=9;break;
                                        default:
                                                 a[rt]=0;
                                                 }
                                        fuhao=3;
                        }
                                jisuan1();
                        for(rt=0;rt<10;rt++)
                         a[rt]=' ';       
                                ad=1;
                                x=1;
                         }       
                          if(dis_buf==0x2f)                                  //     //////////////////
                     {
                          lcdpos(1,0);                                   //  则在下面一行的开始显示“/”
                   lcdwdata(0x2f);
                            display1();                                        // 上一组数据全部搬到上面一行显示
                        for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case '0':
                                                 a[rt]=0;
                                                break;
                                        case '1':
                                                 a[rt]=1;break;
                                        case '2':
                                                 a[rt]=2;break;
                                        case '3':
                                                 a[rt]=3; break;
                                        case '4':
                                                 a[rt]=4;break;
                                        case '5':
                                                 a[rt]=5;break;
                                        case '6':
                                                 a[rt]=6; break;
                                        case '7':
                                                 a[rt]=7;break;
                                        case '8':
                                                 a[rt]=8;break;
                                        case '9':
                                                 a[rt]=9;break;
                                        default:
                                                 a[rt]=0;
                                                 }
                                  fuhao=4;
                        }
                                jisuan1();
                        for(rt=0;rt<10;rt++)
                         a[rt]=' ';       
                                ad=1;
                                x=1;
                         }       
                   if(dis_buf==0x3d)                                //  当按键的码值是0xed(键盘上的#键)
                     {
                          lcdpos(0,0);                                 //         则在上面一行的开始显示“=”
                  lcdwdata(0x3d);
                          lcdpos(1,0);
                          lcdwdata(' ');
                          for(rt=0;rt<10;rt++)
                        {
                                switch(a[rt])
                                {
                                         case '0':
                                                 a[rt]=0;break;
                                        case '1':
                                                 a[rt]=1;break;
                                        case '2':
                                                 a[rt]=2;break;
                                        case '3':
                                                 a[rt]=3;break;
                                        case '4':
                                                 a[rt]=4;break;
                                        case '5':
                                                 a[rt]=5;break;
                                        case '6':
                                                 a[rt]=6;break;
                                        case '7':
                                                 a[rt]=7;break;
                                        case '8':
                                                 a[rt]=8;break;
                                        case '9':
                                                 a[rt]=9;break;
                                        default:
                                                 a[rt]=0;break;
                                                 }
                        }
                                jisuan2();
                         switch(fuhao)
                         {
                          case 1:
                          date=date1+date2;
                          break;
                           case 2:
                          date=date1-date2;
                          break;
                           case 3:
                          date=date1*date2;
                          break;
                           case 4:
                          date=date1/date2;
                          break;
                          }
                          for(rt=0;rt<10;rt++)
                            a[rt]=' ';
                        change();
                        ad=2;
                   };
               
   }
/**显示程序1(在1602下面一行显示)**/
  void display()
  {
     lcdpos(1,15);
         lcdwdata(a[0]);
         lcdpos(1,14);
         lcdwdata(a[1]);
         lcdpos(1,13);
         lcdwdata(a[2]);
         lcdpos(1,12);
         lcdwdata(a[3]);
         lcdpos(1,11);
         lcdwdata(a[4]);
         lcdpos(1,10);
         lcdwdata(a[5]);
         lcdpos(1,9);
         lcdwdata(a[6]);
         lcdpos(1,8);
         lcdwdata(a[7]);


  }
  /**显示程序2(在上面一行显示)**/
    void display1()
  {
    lcdpos(0,15);
         lcdwdata(a[0]);
         lcdpos(0,14);
         lcdwdata(a[1]);
         lcdpos(0,13);
         lcdwdata(a[2]);
         lcdpos(0,12);
         lcdwdata(a[3]);
         lcdpos(0,11);
         lcdwdata(a[4]);
         lcdpos(0,10);
         lcdwdata(a[5]);
         lcdpos(0,9);
         lcdwdata(a[6]);
         lcdpos(0,8);
         lcdwdata(a[7]);
       
  }

按下按键的时候,直接串口输出当前键值,你就知道哪个错了。

是哪里出错啊?
就帖个程序是几个意思

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top