迅维网

查看: 2189|回复: 3
打印 上一主题 下一主题

矩阵键盘控制lcd显示计算器

[复制链接]
跳转到指定楼层
1#
发表于 2016-2-21 09:59:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 山东 来自 山东

马上注册,获取阅读精华内容及下载权限

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

x
#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]);

        


2#
发表于 2016-2-21 10:10:57 | 只看该作者 来自: 中国 来自 中国
LZ用的是什么单片机?51还是PIC?IO脚怎么定义。

点评

51  详情 回复 发表于 2016-2-21 10:12
51  详情 回复 发表于 2016-2-21 10:12
回复 支持 反对

使用道具 举报

3#
发表于 2016-2-21 10:12:19 | 只看该作者 来自: 山东 来自 山东
letstone 发表于 2016-2-21 10:10
LZ用的是什么单片机?51还是PIC?IO脚怎么定义。

51

回复 支持 反对

使用道具 举报

4#
发表于 2016-2-21 10:12:20 | 只看该作者 来自: 山东 来自 山东
letstone 发表于 2016-2-21 10:10
LZ用的是什么单片机?51还是PIC?IO脚怎么定义。

51

回复 支持 反对

使用道具 举报

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

本版积分规则

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图 AI维修
助手



芯片搜索

快速回复