发个帖 LCD1602四线驱动 亲测成功~

2020-01-17 19:03发布

本帖最后由 lycreturn 于 2012-10-29 15:39 编辑

       小弟新手,第一次发帖,还有很多地方不懂,希望前辈 大侠们多多指点~
       板子是学校电子CAD时候发的,平时没怎么用,前几天拿出来 看到上面有块1602液晶 四线制驱动的(DB7--P1^3   DB6--P1^2    DB5--P1^1   DB4--P1^0 )
片机 STC89c52  RS--P2^6   EN--P2^7  RW接地(只写模式)  以前没玩过1602 4线驱动  就去网上找了不少资料  把程序烧写进去 但是都失败了  最多也就显示
乱码  后来又琢磨了一两天 终于调试成功  既然写成功  我就把我的心得分享给大家~
     程序是 网上资料+我的理解 写的  在这里感谢那些提供资料的人  现在把我的程序分享给大家


#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
                                                                 
sbit en=P2^7;  // 液晶使能端  下降沿有效
sbit rs=P2^6;  // 命令--数据选择端 rs=0 写命令  rs=1 写数据

uchar code table1[]=" 4_LINE DRIVER  ";
uchar code table2[]="FOR LCD1602  OK!";

void delay(uint x)        //延时 x 毫秒
{
  uint i,j;
  for(i=x;i>0;i--)
      for(j=110;j>0;j--);
}
void write_1602(uchar cd,dat)    //cd=0 写命令  cd=1 写数据
{
  uchar i;
  rs=cd;
  for(i=0;i<2;i++)  //循环两次 写完一个数据/命令
  {   
       en=1;
       P1=(P1&0xf0)|((dat>>4)&0x0f); //P1高四位数据不改动
       delay(3);                //先送高四位数据 再送低四位数据
       en=0;       
       dat<<=4;         //低四位左移到高四位
  }
}
void init()
{                                                                                          
  write_1602(0,2);               //设置4位数据接口           
  write_1602(0,0x28);           //显示方式设置
  write_1602(0,0x0e);           //设置开显示,不显示光标
  write_1602(0,0x06);           //默认(0x06)写入新数据后光标右移 屏幕不移动
  write_1602(0,0x01);           //显示清0,数据指针清0           
}
void main()
{   
  init();            
  while(1)
  {
   uchar num;
   write_1602(0,0x80);             //第一行
   for(num=0;num<16;num++)
    {      
       write_1602(1,table1[num]);
       delay(3);
    }
    write_1602(0,0x80+0x40); //第二行
    for(num=0;num<16;num++)
    {
       write_1602(1,table2[num]);
       delay(3);
    }
    while(1);
  }
}

   接下来说说我的程序为什么要那么写~
我第一次写成功时  液晶4线设置 初始化程序是这样的  
write_1602(0,0x28);
delay(3);       
write_1602(0,0x28);
delay(3);
write_1602(0,0x28);
delay(3);
en=1;                 
en=0;
write_1602(0,0x28);
这样初始化 觉得很奇怪  于是改变了一下       
write_1602(0,0x28);
delay(3);
en=1;                 
en=0;
write_1602(0,0x28);
这样也可以初始化成功   但是如果没有 en=1; en=0; 液晶显示乱码 为什么呢?
分析一下en=1; en=0;的意思  就会知道 这是一个en下降沿 会把P1低四位数据送入液晶  当我们执行完第一个命令write_1602(0,0x28);时
P1低四位为1000    也就是说en=1; en=0; 把半个数据写入了液晶(因为一个完整数据或命令需要写两次)  那意思是说四线初始化成功需要
写一个半数据(写三次)? 但是写完一个数据只需要两次哒   难道是因为高4位数据写入之后 四线模式设置成功了然后后面的低4位数据
被作为了一个新的数据 也就是说 0x28的低4位1000作为了一个新数据的高4位~ 而en=1; en=0;写入了刚才数据的低4位(也是1000) 这样
的话 后面的数据才会被正常写入  为了验证我的猜想  于是我把初始化程序改为这样
write_1602(0,0x22);
  rs=0;
  en=1;
  P1=(P1&0xf0)|0x00;        //P1低位送入0000         
  en=0;
//write_1602(0,0x28);
结果我很满意  液晶确实只显示了一行  5x7点阵   因为液晶显示一行 5x7点阵的命令为write_1602(0,0x20);(N=0,F=0,具体看1602数据手册)
这样的话  0x22的低4位和P1=(P1&0xf0)|0x00;的四位组合成了一个新数据   看来我的猜想是正确的  于是我的总结是--LCD1602四线设置需要单独设置
这样我们也可以理解 液晶乱码的问题了 乱码说明你已经4线初始化成功  只是数据没有正确写入而已 因为如果没有en=1; en=0;   第一次写
write_1602(0,0x28);时低4位被作为一个新数据的高4位写下一个数据时数据的高4位被作为了上一个数据的低4位 这样你的数据完全被打乱了 但四线初始化
是成功了的  但显示的就是乱码咯~霍霍~~~~~~~

然后呢 我又把初始化这样改了一下
rs=0;
  en=1;
  P1=(P1&0xf0)|0x02;                 
  en=0;  
write_1602(0,0x28);
结果很明显  液晶正常工作  而这里对液晶四线设置只用了半个数据(0010)就已经成功了  之后便可以正常写入数据    所以我认为液晶4线制需要
单独设置所以在最后我用write_1602(0,2);设置四线模式  大家也应该明白为什么了吧~~~~~

以上是小弟的见解  有什么不对的  还希望高手指点~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
38条回答
yklstudent
1楼-- · 2020-01-18 17:23
lycreturn 发表于 2012-10-29 19:50
看不大懂  请问一下 你有没有亲自做实验成功过   还有这个可不可以用51单片机做  目前还没用过其他的单片 ...

玩玩差不多 做产品用就要慎重了
52robot
2楼-- · 2020-01-18 21:55
 精彩回答 2  元偷偷看……
lycreturn
3楼-- · 2020-01-19 00:52
52robot 发表于 2012-10-29 20:45
小虾在09年的时候做的一些驱动,共享给大家
【M16 ICCAVR PROTEUS每天一练】之液晶专辑(8位数据线驱动16 ...

恩  非常不错  用74hc595 3线  74hcl64 2线驱动 可以理解    但直接用单片机IO口  2线(3线 )驱动   我还真不懂
52robot
4楼-- · 2020-01-19 04:40
lycreturn 发表于 2012-10-29 20:49
恩  非常不错  用74hc595 3线  74hcl64 2线驱动 可以理解    但直接用单片机IO口  2线(3线 )驱动   我 ...

直接的我还真没试过,如果你搞出来的话记得通知一声
lycreturn
5楼-- · 2020-01-19 06:10
52robot 发表于 2012-10-29 20:55
直接的我还真没试过,如果你搞出来的话记得通知一声

你这样的高手都还没弄出来 像我这种小虾不行啊~    不过有空可以试一下
lycreturn
6楼-- · 2020-01-19 08:27
哎~~怎么没影响了呢?  大家都不玩4线液晶的么~   多少谈谈自己的见解撒~

一周热门 更多>