找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1860|回复: 0
打印 上一主题 下一主题
收起左侧

1602显示器显示规划优化体会 附单片机程序+仿真图

[复制链接]
跳转到指定楼层
楼主
    1602显示器成本低廉使用简单,是单片机理想的显示设备。但是,1602显示器同时只能显示32个字符的内容,显示信息明显偏少,而且自然显示的话显示内容很快就会超出显示范围而看不见。直到第一行显示满64个字符后才回到第二行开头显示重现显示内容。为了避免出现显示内容超出显示范围而不可见,程序要适时换行,但在程序中使用显示器的地方有很多个模块,其中有些还是中断模块,各模块实际往显示器送了多少个字符很难判断,很难适时换行导致显示内容进入不可见显示区而影响显示效果,特别是有些时候要输入数字,还会用到退格键删除内容,这更增加了显示控制的难度。有的程序员为了避免出现这种情况就采用固定地点显示方法,就只在显示器几个固定地方显示内容,这样虽然不会出现显示内容不可见的情况,但往往只能安排少数几个显示地点,会出现很多显示单元没利用,使本来不多的显示资源便显紧张,影响程序运行效果,特别是一些显示数据刷新率高的场合,往往前一个数据还没看清,下一下数据已将其履盖。所以固定地点显示的方法也不是最优。根据本人的体会,要充分利用1602显示器的显示资源,要固定地点显示与自然显示方法相结合,在显示器中的一些特定区域设为固定显示点,如将显示器的每行两端两到四个显示单元作为固定显示点,用于较固定的显示需求,其余地方作为自然显示区,编写一个专门显示模块,统一管理显示资源,正确设置显示光标,使显示内容能在自然显示区内合理显示,而又不会影响其他区域的显示。这样就能最大限度发挥显示器的作用。
    为了说明本方法对显示器的使用,本人设计了一个简单的例子。在本例中,有一个简单的算术测试程序,在100个时间单位内,单片机不断出一些简单的算术题,由用户答题,正确则正确答题数加分,错误则错题数加分,在显示器的左上角实时显示答对题数字,左下角实时显示答错题数字,右上角则实时显示所剩的时间数字,右下角则用于输入数字显示用,支持退格删除字符。

下面是程序运行时的截图:


单片机源程序如下:
  1. #include<reg51.h>
  2. sbit kx0=P2^0;
  3. sbit kx1=P2^1;
  4. sbit kx2=P2^2;
  5. sbit kx3=P2^3;
  6. sbit ky0=P2^4;
  7. sbit ky1=P2^5;
  8. sbit ky2=P2^6;
  9. sbit ky3=P2^7;

  10. sbit rs=P3^5;
  11. sbit rw=P3^6;
  12. sbit E=P3^7;
  13. #define StartA 3
  14. #define StartB 3
  15. #define EndA  13
  16. #define EndB  13
  17. char shifkey,ok,error,xl,yl;
  18. int Timenum,temp;
  19. //===========================================================
  20. void delay(int ii){int i;for(i=0;i<ii;i++);}
  21. //===========================================================
  22. void writeCmd(unsigned char c){E=0;rw=0;rs=0;delay(50);delay(50);P1=c;delay(50);E=1;delay(50);E=0; }
  23. void writeDat(unsigned char c){E=0;rw=0;rs=1;delay(50);delay(50);P1=c;delay(50);E=1;delay(50);E=0;}
  24. void Putxychar(char x,char y,char c){if(y>0)writeCmd(0x80+0x40+x);else writeCmd(0x80+x);writeDat(c);}
  25. void Prtstr(char *cp){char i=0;while(cp[i]!=0){writeDat(cp[i]);i++;}}
  26. void Mplaychar(char c)
  27. {int i;Putxychar(xl,yl,c);
  28. xl++;
  29. if((xl>=EndA)&&(yl==0)){xl=StartB;yl=1;for(i=StartA;i<EndA;i++)Putxychar(i,1,' ');}
  30. else if(xl>=EndB){xl=StartA;yl=0;for(i=StartB;i<EndB;i++)Putxychar(i,0,' ');}
  31. }
  32. void Mplaystr(char *cp){char i=0;while(cp[i]!=0){Mplaychar(cp[i]);i++;}}
  33. //-----------------------------------------------------------
  34. void dispnum(int x,int y,int num)
  35. {if(y>0)writeCmd(0x80+0x40+x);else writeCmd(0x80+x);
  36. writeDat((num%100)/10+0x30);writeDat((num%100)%10+0x30);
  37. }
  38. //===========================================================
  39. void Timeinit()
  40. {EA=1;ET1=1;TMOD|=0x20;
  41. TH1=0;TL1=0;TR1=1;
  42. }
  43. //=========================================================
  44. void Time1Pro()interrupt 3
  45. {temp++;
  46. if(temp==3000){temp=0;if(Timenum>0)Timenum--;dispnum(14,0,Timenum);}
  47. }
  48. //==========================================================
  49. int KeyDown()
  50. {char v,x,y;
  51. x=4;y=4;
  52. P2=0x0f;v=P2;
  53. if(v!=0x0f){if(kx0==0)x=0;if(kx1==0)x=1;if(kx2==0)x=2;if(kx3==0)x=3;
  54.              P2=0xf0;if(ky0==0)y=0;if(ky1==0)y=1;if(ky2==0)y=2;if(ky3==0)y=3;
  55.              }
  56. return x*4+y;
  57. }
  58. //==========================================================
  59. unsigned int GetNum()
  60. {char w,pos=0,key;
  61. unsigned int num;
  62.   w=0;
  63.   writeCmd(0x80+0x40+EndB+1);
  64.   Prtstr("  ");
  65.   writeCmd(0x80+0x40+EndB+1);
  66.   while(1)
  67.   {key=KeyDown();
  68.    if(key<12)
  69.    {key=KeyDown();while(key==KeyDown());
  70.     if(key<10){Putxychar(EndB+pos+1,1,key+0x30);pos++;if(w==0)num=key;else num=num*10+key;w++;}
  71.         else if(key==10){num=num/10;if(pos>0)pos--;Putxychar(EndB+pos+1,1,' ');writeCmd(0x80+0x40+EndB+pos+1);}
  72.         else if(key==11)return num%100;
  73.    }
  74.    }
  75. }
  76. //=========================================================
  77. void Game()
  78. {int a,b,c;
  79.   while(Timenum)
  80.   {a=rand()%10;
  81.    b=rand()%10;
  82.    Mplaychar(a+0x30);
  83.    Mplaychar('+');
  84.    Mplaychar(b+0x30);
  85.    Mplaychar('=');
  86.    c=GetNum();
  87.    if((c%100)/10)Mplaychar((c%100)/10+0x30);
  88.    Mplaychar((c%100)%10+0x30);
  89.    Mplaychar(';');
  90.    if(c==(a+b)){dispnum(0,0,++ok);}
  91.    else{{dispnum(0,1,++error);}}
  92.   }
  93.   }
  94. //##########################################################
  95. void main()
  96. {int i;
  97. Timeinit();
  98. Timenum=100;
  99. Putxychar(2,0,'[');
  100. Putxychar(2,1,'[');
  101. Putxychar(13,0,']');
  102. Putxychar(13,1,']');
  103. ……………………

  104. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

附件有完整程序及proteus设计:
P7.zip (109.73 KB, 下载次数: 7)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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