找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2121|回复: 5
收起左侧

LCD1602如何连续输入?附单片机程序

[复制链接]
ID:652716 发表于 2020-1-22 15:39 | 显示全部楼层 |阅读模式
#include"reg52.h"
#define led P0           //定义led数码管连在P0口
#define key P3                          //定义矩阵键盘连在P3口
#define LCD1602_D P0              //lcd I/O口连在P0口
#define uchar unsigned char
#define uint unsigned int
sbit E=P3^4;                              //定义lcd端口
sbit RW=P3^6;
sbit RS=P3^5;
void LcdWriteCom(uchar com);          //函数声明
void WriteDat(uchar dat);
void Lcdxs(uchar x,uchar y,uchar dat);
uchar code lcd[]={0x2f,0x2a,0x2d,0x2b,0x3d,0x39,0x36,0x33,0x30,0x38,0x35,0x32,0x2e,0x37,0x34,0x31};    //   123+456-789*#0/=
                          //   /        *         -          +           =        9        6          3           0        8         5         2           .        7         4         1
uchar a,c;                                       
void delay(uint i)           //延时函数
{
  while(i--)
  {;}
}
void keydownup()        //矩阵按键扫描程序
{
char b=0;
key=0x0f;
if(key!=0x0f)
{
  delay(1000);                 //延时消抖
  if(key!=0x0f)
  {
   key=0x0f;                           //检测列  使高四位为低,低四位为高,判断低四位是否有低电平出现(有则key!=0x0f)
   switch(key)
   {
    case 0x07:a=0;break;
        case 0x0b:a=1;break;
        case 0x0d:a=2;break;
        case 0x0e:a=3;break;
   }
   key=0xf0;                          //检测行  使高四位为高,低四位为低,判断高四位是否有低电平出现(有则key!=0xf0)
   switch(key)
   {
    case 0x70:a=a;   break;
        case 0xb0:a=a+4; break;
        case 0xd0:a=a+8; break;
        case 0xe0:a=a+12;break;
   }
   while((b<50)&&key!=0xf0)           //判断按键按下后是否松开  超时或者按键松开则跳出循环
   {
    delay(1000);
        b++;
   }
  }
}
}
void LcdWriteCom(uchar com)                    //写指令函数
{
E=0;                                 //允许使能
RS=0;                                 //指令
RW=0;                                 //写入
LCD1602_D=com;
delay(1);
E=1;                                   //写入时序
delay(1);
E=0;
}
void WriteDat(uchar dat)                       //写数据函数
{
E=0;                                 //允许使能
RS=1;                                 //数据
RW=0;                                 //写入
LCD1602_D=dat;
delay(1);
E=1;                                   //写入时序
delay(1);
E=0;
}
void Lcdxs(uchar x,uchar y,uchar dat)          //显示一个字符的函数
{
uchar t;
if(y==1)
   t=0x80+x;
else
   t=0xc0+x;
LcdWriteCom(t);
WriteDat(dat);
}
void main()
{
LcdWriteCom(0x38);          //开显示
LcdWriteCom(0x0c);          //开显示不开光标
LcdWriteCom(0x06);          //写一个指针加1
LcdWriteCom(0x01);          //清屏
delay(100);
while(1)
{
  keydownup();                //矩阵按键扫描程序
  Lcdxs(0,1,lcd[a]);    //显示按键按下后数组中对应的值

}
}
怎么改,让他连续输入

回复

使用道具 举报

ID:97554 发表于 2020-1-23 14:55 | 显示全部楼层

lcdxs(0,1,lcd[a])

设置一个变量K,按键每按一下K+1

lcdxs(0,k,lcd[a])
回复

使用道具 举报

ID:155507 发表于 2020-1-23 19:21 | 显示全部楼层
我给你来个程序参考

  1. #include<reg52.h>
  2. #include<math.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define lcddata P1

  6. sbit LCDRS   = P3^3;
  7. sbit LCDRW   = P3^4;
  8. sbit LCDEN   = P3^5;
  9. sbit beep    = P3^7;
  10. sbit zhongduan   = P3^2;
  11. sbit kaifang =  P0^6;
  12. sbit cifang  = P0^7;
  13. sbit qingling=P0^5;
  14. sbit kaiguan=P0^4;

  15. uchar keyscan1(void);
  16. void keyscan(void);
  17. void count(void);
  18. void anjianshibie();
  19. void write_com(uchar i);
  20. void write_data(uchar i);
  21. void write_string(uchar *s);
  22. void write_num(long n);
  23. void lcdwrite_float(float n);
  24. void lcd_init(void);
  25. void xinxing();

  26. void delayms(uint z)
  27. {
  28.         uint x,y;
  29.         for(x=z;x>0;x--)
  30.            for(y=110;y>0;y--);
  31. }

  32. uchar code table[]=
  33. {
  34.         1,2,3,0x2b-0x30,                         // 1,   2,   3,    +
  35.         4,5,6,0x2d-0x30,                         // 4,   5,   6,    -
  36.         7,8,9,0x2a-0x30,                         // 7,   8,   9,    x
  37.         0,0x3d-0x30,0x2e-0x30,0x2f-0x30          // 0,   =,   清零, /
  38. };
  39. uchar code table1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
  40.         0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  41.         0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  42.         0x01,0x18,0x1c,0x1e,0x1e,0x1e,0x1e,0x1e,
  43.         0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
  44.         0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
  45.         0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
  46.         0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00
  47. };
  48. uchar num='N',flag=0,flag1=0,flag2=0,fuhao=0,temp=0,shu[18]={0},beepflag=1,y=0,j;
  49. float a=0,b=0,c=0,d,point=0;

  50. void main()
  51. {        
  52.         xinxing();
  53.         delayms(1000);
  54.         write_com(0x01);
  55.         write_com(0x80);
  56.         EA=1;          //全局中断开
  57.         EX0=1;         //外部中断0开
  58.         IT0=0;         //电平触发(边沿触发IT0=1;)
  59.         while(1)
  60.         {     
  61.                 keyscan();  
  62.                 anjianshibie();         
  63.         }
  64. }

  65. /*按键检测*/
  66. uchar keyscan1(void)  //键盘扫描函数,使用行列反转扫描法
  67. {
  68.         unsigned char cord_h,cord_l;//行列值中间变量
  69.         P2=0x0f;            //行线输出全为0
  70.         cord_h=P2&0x0f;     //读入列线值
  71.         if(cord_h!=0x0f)    //先检测有无按键按下
  72.         {
  73.                 delayms(10);        //去抖
  74.                 if((P2&0x0f)!=0x0f)
  75.                 {
  76.                         if(beepflag==1)  //若开声音则每一次按键均鸣叫
  77.                         {
  78.                                 beep=0;
  79.                                 delayms(50);
  80.                                 beep=1;
  81.                         }
  82.                         cord_h=P2&0x0f;  //读入列线值
  83.                         P2=cord_h|0xf0;  //输出当前列线值
  84.                         cord_l=P2&0xf0;  //读入行线值
  85.                         while((P2&0xf0)!=0xf0); //等待松开并输出
  86.                         return(cord_h+cord_l);  //键盘最后组合码值
  87.                 }
  88.         }
  89.         return(0xff);     //返回该值
  90. }
  91. void keyscan()
  92. {
  93.         switch(keyscan1())
  94.         {
  95.         case 0xEE:num=0;break;
  96.         case 0xDE:num=1;break;
  97.         case 0xBE:num=2;break;
  98.         case 0x7E:num=3;break;
  99.         case 0xED:num=4;break;
  100.         case 0xDD:num=5;break;
  101.         case 0xBD:num=6;break;
  102.         case 0x7D:num=7;break;
  103.         case 0xEB:num=8;break;
  104.         case 0xDB:num=9;break;
  105.         case 0xBB:num=10;break;
  106.         case 0x7B:num=11;break;
  107.         case 0xE7:num=12;break;
  108.         case 0xD7:num=13;break;
  109.         case 0xB7:num=14;break;
  110.         case 0x77:num=15;break;   
  111.         }
  112. }
  113. /*按键识别函数*/
  114. void anjianshibie()
  115. {
  116.         if(num==0||num==1||num==2||num==4||num==5||num==6||num==8||num==9||num==10||num==12||num==14)
  117.         {
  118.                 if(temp>=2)
  119.                 {
  120.                         write_com(0x01);
  121.                         write_string("math error");
  122.                 }
  123.                 else
  124.                 {
  125.                         if(flag==0)
  126.                         {
  127.                                 if(num==14)
  128.                                 {flag2=1;}
  129.                                 if(num!=14&&flag2==0)
  130.                                 {a=a*10+table[num];}
  131.                                 if(num!=14&&flag2==1)
  132.                                 {
  133.                                         y++;
  134.                                         point=table[num]*pow(0.1,y);
  135.                                         a=a+point;         
  136.                                 }                                                                                  
  137.                                 write_data(0x30+table[num]);
  138.                                 delayms(5);
  139.                         }
  140.                         if(flag==1)
  141.                         {
  142.                                 if(num==14)
  143.                                 {flag2=1;}
  144.                                 if(num!=14&&flag2==0)
  145.                                 {b=b*10+table[num];}
  146.                                 if(num!=14&&flag2==1)
  147.                                 {
  148.                                         y++;
  149.                                         point=table[num]*pow(0.1,y);
  150.                                         b=b+point;         
  151.                                 }                                                                                  
  152.                                 write_data(0x30+table[num]);
  153.                                 delayms(5);                       
  154.                         }
  155.                 }
  156.                 num='N';           //一定要加这个,否则会出现满屏的按键对应的数
  157.         }
  158.         if(num==3||num==7||num==11||num==15)
  159.         {
  160.                 flag=1;
  161.                 flag2=0;
  162.                 y=0;
  163.                 temp++;//判断运算符号按下的个数
  164.                 switch(num)
  165.                 {
  166.                 case 3:fuhao=1;break;                 //加
  167.                 case 7:fuhao=2;break;                 // 减
  168.                 case 11:fuhao=3;break;             // 乘
  169.                 case 15:fuhao=4;break;                 // 除
  170.                 }
  171.                 write_data(0x30+table[num]);
  172.                 num='N';                       
  173.         }
  174.         if(num==13)           //13等号,14清零
  175.         {              
  176.                 temp=0;     //temp清零
  177.                 flag=0;
  178.                 flag2=0;     
  179.                 if(flag1==0)
  180.                 {write_com(0x80+0x40);}
  181.                 write_data(0x30+table[num]);
  182.                 delayms(5);                  
  183.                 count();           //计算c的值
  184.                 /*     if(c==0)
  185.                         {
  186.                                 write_com(0x80+0x41);//如果c为零,直接在等号后边显示出来
  187.                                 write_data(0x30);
  188.                         }
  189.                 if(c>0)
  190.                         {
  191.                                 d=c;
  192.                         }
  193.                 if(c<0)
  194.                         {
  195.                                 d=0-c;
  196.                                 write_data(0x2d);        //把小数点显示出来
  197.                         }  */
  198.                 lcdwrite_float(c);
  199.                 flag1++;                                                                         
  200.                 num='N';
  201.         }
  202.         if(kaifang==0)
  203.         {
  204.                 delayms(10);
  205.                 if(kaifang==0)                //去抖
  206.                 {
  207.                         if(beepflag==1)  //若开声音则每一次按键均鸣叫
  208.                         {
  209.                                 beep=0;
  210.                                 delayms(50);
  211.                                 beep=1;
  212.                         }
  213.                         temp++;
  214.                         flag=1;
  215.                         flag2=0;
  216.                         y=0;
  217.                         write_data(0xe8);
  218.                         fuhao=5;
  219.                 }
  220.                 while(!kaifang);        //按键释放
  221.         }
  222.         if(cifang==0)
  223.         {
  224.                 delayms(10);                          // 去抖
  225.                 if(cifang==0)
  226.                 {
  227.                         if(beepflag==1)  //若开声音则每一次按键均鸣叫
  228.                         {
  229.                                 beep=0;
  230.                                 delayms(50);
  231.                                 beep=1;
  232.                         }
  233.                         temp++;
  234.                         flag=1;
  235.                         flag2=0;
  236.                         y=0;
  237.                         write_data(0x5e);
  238.                         fuhao=6;
  239.                 }
  240.                 while(!cifang);        // 按键释放
  241.         }
  242.         if(qingling==0)
  243.         {
  244.                 delayms(10);                          // 去抖
  245.                 if(qingling==0)
  246.                 {
  247.                         if(beepflag==1)  //若开声音则每一次按键均鸣叫
  248.                         {
  249.                                 beep=0;
  250.                                 delayms(50);
  251.                                 beep=1;
  252.                         }
  253.                         write_com(0x01);
  254.                         a=0;
  255.                         b=0;
  256.                         c=0;
  257.                         point=0;
  258.                         flag=0;
  259.                         flag1=0;
  260.                         flag2=0;
  261.                         temp=0;
  262.                         fuhao=0;
  263.                         j=0;
  264.                         num='N';
  265.                 }
  266.                 while(!qingling);        // 按键释放
  267.         }
  268.         /*if(kaiguan==0)
  269. {
  270. delayms(10);                          // 去抖
  271. if(kaiguan==0)
  272. {
  273.         beepflag=~beepflag;
  274. }
  275. while(!cifang);        // 按键释放
  276. }*/
  277. }       

  278. /*计算函数*/
  279. void count()
  280. {      
  281.         if(fuhao==1)    //如果符号键是+,执行加法运算
  282.         {
  283.                 c=a+b;
  284.                 a=c;
  285.                 b=0;
  286.         }                 
  287.         if(fuhao==2)                           // 如果符号键是-,执行减法运算
  288.         {
  289.                 c=a-b;
  290.                 a=c;
  291.                 b=0;
  292.         }                                                                                                            
  293.         if(fuhao==3)   //如果符号键是*执行乘法运算
  294.         {        
  295.                 c=a*b;
  296.                 a=c;
  297.                 b=0;
  298.         }
  299.         if(fuhao==4)      //如果符号键是/ 执行除法运算               
  300.         {
  301.                 if(b==0)
  302.                 {
  303.                         write_com(0x01);
  304.                         write_string("math error");                   //被除数不能为零,否则输出math error
  305.                 }
  306.                 else
  307.                 {
  308.                         c=a/b;
  309.                         a=c;
  310.                         b=0;
  311.                 }         //这么设置就可连续运算                                                                                                                                                                                                           
  312.         }
  313.         if(fuhao==5)
  314.         {
  315.                 if(b<0)
  316.                 {
  317.                         write_com(0x01);
  318.                         write_string("math error");
  319.                 }
  320.                 else
  321.                 {
  322.                         c=sqrt(b);

  323.                 }
  324.         }
  325.         if(fuhao==6)
  326.         {
  327.                 float x=a;
  328.                 c=a;
  329.                 for(;b>1;b--)
  330.                 {                                       
  331.                         c=x*a;
  332.                         x=c;
  333.                 }
  334.         }                                    
  335. }

  336. /*写命令*/
  337. void write_com(uchar i)
  338. {
  339.         LCDEN=0;
  340.         LCDRS=0;
  341.         lcddata=i;
  342.         delayms(5);
  343.         LCDEN=1;
  344.         delayms(5);
  345.         LCDEN=0;
  346. }
  347. /*******写数据***********/
  348. void write_data(uchar i)
  349. {
  350.         LCDEN=0;
  351.         LCDRS=1;
  352.         lcddata=i;
  353.         delayms(5);
  354.         LCDEN=1;
  355.         delayms(5);
  356.         LCDEN=0;
  357. }
  358. /*写字符串*/
  359. void write_string(uchar *s)
  360. {
  361.         while(*s)
  362.         {
  363.                 write_data(*s);
  364.                 s++;
  365.                 delayms(5);
  366.         }
  367. }
  368. /*******初始化液晶*******/
  369. void lcd_init(void)
  370. {
  371.         LCDEN=0;
  372.         LCDRW=0;
  373.         //write_com(0x01); //显示清屏
  374.         // write_com(0x01); //显示清屏
  375.         write_com(0x38);//设置成1602显示
  376.         delayms(5);
  377.         write_com(0x38);//设置成1602显示
  378.         delayms(5);
  379.         write_com(0x38);//设置成1602显示
  380.         delayms(5);
  381.         // write_com(0x0f); //开显示 0x0e-->显示开,光标开
  382.         write_com(0x0c);//显示开
  383.         write_com(0x06); //设置光标移动方向增量方式,并指定显示不移动
  384.         write_com(0x01);
  385. }
  386. /*开机界面*/
  387. void xinxing()
  388. {
  389.         uchar mingzi[]="by 51Hei"        ;
  390.         uchar num1;                                                        //循环变量
  391.         lcd_init();                                                         //初始化
  392.         write_com(0x40);                                       
  393.         for(num1=0;num1<64;num1++)
  394.         {
  395.                 write_data(table1[num1]);
  396.         }

  397.         write_com(0x85);                               
  398.         for(num1=0;num1<4;num1++)
  399.         {
  400.                 write_data(num1);
  401.         }
  402.         write_com(0xc5);                                       
  403.         for(num1=4;num1<8;num1++)
  404.         {
  405.                 write_data(num1);
  406.         }
  407.         write_com(0x80+0x4a);
  408.         for(num1=0;num1<6;num1++)
  409.         {
  410.                 write_data(mingzi[num1]);
  411.         }
  412.        
  413. }
  414. void waibu(void) interrupt 0 //using 1
  415. {
  416.         if(zhongduan==0)                    //如果检测到低电平
  417.         {
  418.                 delayms(10);        //延时,去抖动,一般为10ms
  419.                 if(zhongduan==0)                //如果去抖动之后还是低电平,说明按下了
  420.                 {
  421.                         if(beepflag==1)  //若开声音则每一次按键均鸣叫
  422.                         {
  423.                                 beep=0;
  424.                                 delayms(50);
  425.                                 beep=1;
  426.                         }
  427.                         beepflag=~beepflag;     //进入中断程序执行程序  
  428.                 }
  429.                 while(!zhongduan);          //等待释放,如果没有释放,则一直等待
  430.         }

  431. }
  432. /******显示7位小数*********/
  433. void lcdwrite_float(float n)
  434. {
  435.         uchar i=0;
  436.         long nxtemp;
  437.         if(n==0)
  438.         {
  439.                 write_data('0');
  440.                 return;
  441.         }       
  442.         if(n<0)
  443.         {
  444.                 write_data('-');
  445.                 n=0-n;
  446.         }          
  447.         nxtemp=n;
  448.         n=n;//+0.000002;
  449.         write_num(nxtemp);
  450.         if((n-nxtemp)>0)
  451.         {       
  452.                 write_data('.');
  453.                 nxtemp=(n-nxtemp)*10000000;
  454.                 //        n=n-1;
  455.                 //        nxtemp=n;
  456.                 //        if(nxtemp%10!=0)
  457.                 write_data(nxtemp/1000000+0x30);//显示第7位小数
  458.                 //        if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0)||(nxtemp%1000000/100000!=0))
  459.                 write_data(nxtemp%1000000/100000+0x30);//显示第6位小数
  460.                 //        if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0)||(nxtemp%1000000%100000/10000!=0))
  461.                 write_data(nxtemp%1000000%100000/10000+0x30);//显示第5位小数
  462.                 //        if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0)||(nxtemp%1000000%100000%10000/1000!=0))
  463.                 write_data(nxtemp%1000000%100000%10000/1000+0x30);//显示第4位小数
  464.                 //        if((nxtemp%1000000%100000%10000%1000%100/10!=0)||(nxtemp%1000000%100000%10000%1000/100!=0))
  465.                 write_data(nxtemp%1000000%100000%10000%1000/100+0x30);//显示第3位小数
  466.                 //        if((nxtemp%1000000%100000%10000%1000%100/10!=0))
  467.                 write_data(nxtemp%1000000%100000%10000%1000%100/10+0x30);//显示第2位小数
  468.                 write_data(nxtemp%10+0x30);//显示第1位小数        */

  469.         }
  470.         else
  471.         return;
  472. }
  473. /*显示多位数*/
  474. void write_num(long n)
  475. {
  476.         //        uchar length=0,j=0,a[8]={0,0,0,0,0,0,0,0};
  477.         long nx;
  478.         /*        if(n==0)
  479.         {
  480.                 write_data('0');
  481.                 return;
  482.         }       
  483.         if(n<0)
  484.         {
  485.                 write_data('-');
  486.                 n=0-n;
  487.         } */
  488.         //        nx=n;       
  489.         //        for(j=0;j<8;j++)
  490.         //        {
  491.         //                if(nx>=1)
  492.         //                        length++;
  493.         //                nx/=10;
  494.         //        }
  495.         nx=n;
  496.         if(nx==0)
  497.         {
  498.                 write_data('0');
  499.         }
  500.         else
  501.         {
  502.                 while(nx>0)
  503.                 {
  504.                         shu[j]=nx%10;                        //把n的每一位放进数组
  505.                         nx=nx/10;
  506.                         j++;   
  507.                 }                         
  508.                 for(;j>0;j--)
  509.                 {                                                                 //显示整数n的每一位
  510.                         write_data(shu[j-1]+0x30);
  511.                         delayms(5);
  512.                 }
  513.         }
  514. }


复制代码
回复

使用道具 举报

ID:652716 发表于 2020-1-23 20:24 | 显示全部楼层
杨雪飞 发表于 2020-1-23 14:55
lcdxs(0,1,lcd[a])

设置一个变量K,按键每按一下K+1

lcdxs(0,1,lcd[a])
if语句判读是否按下
按下k+1,没按下k不变
a=k+1;
lcdxs(0,k,lcd[a])
回复

使用道具 举报

ID:584814 发表于 2020-2-1 07:55 | 显示全部楼层
1602的三线接在了P3口,高低端都占了些,而P3又定义成矩阵键盘并且还以高低口有无信号做为标志,这样肯定不好玩。建议将1602的三线换到P1或P2试试。
回复

使用道具 举报

ID:692513 发表于 2020-2-17 20:39 | 显示全部楼层
angmall 发表于 2020-1-23 19:21
我给你来个程序参考

请问一下硬件是如何连接的,比如P0、P1口要连接什么
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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