找回密码
 立即注册

QQ登录

只需一步,快速开始

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

LCD1602点不亮,单片机P0处是倒着接的,逆序函数也不行 求分析

[复制链接]
跳转到指定楼层
楼主
在做一个关于门禁的项目的时候发现LCD1602点不亮,因为自己的做的板子和开发板不一样P0处是倒着接的,所以用了一个逆序函数,但还是不行。原函数(不存在逆序函数)的可以在开发板上显示。不存在接触不良问题,电位10K和4.7k都试过了。请大家帮我看看程序有没有问题,谢谢啦。

单片机源程序如下:
  1. /*********************************************************************************
  2. * 【外部晶振】: 11.0592mhz        
  3. * 【主控芯片】: STC89C52
  4. * 【编译环境】: Keil μVisio3        
  5. * 【程序功能】: LCD1602显示                                                                                   
  6. * 【使用说明】: 正确接上LCD1602液晶并调节好对比度
  7. *  说明:免费开源,不提供源代码分析.
  8. **********************************************************************************/
  9. #include <reg52.h>

  10. /*=================================================
  11. *自定义数据类型
  12. =================================================*/
  13. typedef unsigned char uchar;
  14. typedef unsigned int uint;

  15. #define LCD1602_DB P0        //LCD1602数据总线

  16. <font color="#ff0000">sbit LCD1602_RS = P2^5;         //RS端
  17. sbit LCD1602_RW = P2^6;         //RW端
  18. sbit LCD1602_EN = P2^7;         //EN端</font>
  19. //sbit DU = P2^6;//
  20. //sbit WE = P2^7;//数码管位选段选用于关闭数码管显示

  21. unsigned char swapbit(unsigned char udata)                //<font color="#ff0000">逆位显示</font>
  22. {
  23.   unsigned char ii,tmp=0;
  24.   for(ii=0;ii<8;ii++)
  25.   {
  26.     tmp<<=1;
  27.     if(udata&0x01)
  28.     {
  29.       tmp|=0x01;
  30.     }
  31.     udata>>=1;
  32.   }
  33.   return tmp;
  34. }


  35. /*=================================================
  36. *函数名称:Read_Busy
  37. *函数功能:判断1602液晶忙,并等待
  38. =================================================*/
  39. void Read_Busy()
  40. {
  41.         uchar busy;
  42.         LCD1602_DB = 0xff;//复位数据总线
  43.         LCD1602_RS = 0;          //拉低RS
  44.         LCD1602_RW = 1;          //拉高RW读
  45.         do
  46.         {
  47.                 LCD1602_EN = 1;//使能EN
  48.                 busy = swapbit(LCD1602_DB);//读回数据
  49.                 LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  50.         }while(busy); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
  51. }
  52. /*=================================================
  53. *函数名称:LCD1602_Write_Cmd
  54. *函数功能:写LCD1602命令
  55. *调用:Read_Busy();
  56. *输入:cmd:要写的命令
  57. =================================================*/
  58. void LCD1602_Write_Cmd(uchar cmd)
  59. {
  60.         Read_Busy();         //判断忙,忙则等待
  61.         LCD1602_RS = 0;
  62.         LCD1602_RW = 0;        //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
  63.         LCD1602_DB = swapbit(cmd);//写入命令
  64.         LCD1602_EN = 1;         //拉高使能端 数据被传输到LCD1602内
  65.         LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  66. }
  67. /*=================================================
  68. *函数名称:LCD1602_Write_Dat
  69. *函数功能:写LCD1602数据
  70. *调用:Read_Busy();
  71. *输入:dat:需要写入的数据
  72. =================================================*/
  73. void LCD1602_Write_Dat(uchar dat)
  74. {
  75.         Read_Busy();
  76.         LCD1602_RS = 1;
  77.         LCD1602_RW = 0;
  78.         LCD1602_DB = swapbit(dat);
  79.         LCD1602_EN = 1;
  80.         LCD1602_EN = 0;
  81. }
  82. /*=================================================
  83. *函数名称:LCD1602_Dis_OneChar
  84. *函数功能:在指定位置显示一个字符
  85. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();        
  86. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  87.                 dat:需要显示的数据以ASCLL形式显示
  88. =================================================*/
  89. /*
  90. void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
  91. {
  92.         if(y)        x |= 0x40;
  93.         x |= 0x80;
  94.         LCD1602_Write_Cmd(x);
  95.         LCD1602_Write_Dat(dat);               
  96. }
  97. */
  98. /*=================================================
  99. *函数名称:LCD1602_Dis_Str
  100. *函数功能:在指定位置显示字符串
  101. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
  102. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  103.                 *str:需要显示的字符串
  104. =================================================*/
  105. void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
  106. {
  107.         if(y) x |= 0x40;
  108.         x |= 0x80;
  109.         LCD1602_Write_Cmd(x);
  110.         while(*str != '\0')
  111.         {
  112.                 LCD1602_Write_Dat(*str++);
  113.         }
  114. }
  115. /*=================================================
  116. *函数名称:Init_LCD1602
  117. *函数功能:1602初始化
  118. *调用:        LCD1602_Write_Cmd();
  119. =================================================*/
  120. void Init_LCD1602()
  121. {
  122.         LCD1602_Write_Cmd(0x38); //设置16*2显示,5*7点阵,8位数据接口
  123.         LCD1602_Write_Cmd(0x0c); //开显示
  124.         LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
  125.         LCD1602_Write_Cmd(0x01); //清除显示
  126. }

  127. void main()
  128. {
  129. //        int n;
  130.         uchar TestStr[] = {"welcome!"};
  131.         uchar str[] = {"LCD1602 display"};
  132.         //DU = 0;
  133.         //WE = 0;//关闭数码管显示
  134.         Init_LCD1602();//1602初始化
  135.         LCD1602_Dis_Str(0, 0, &TestStr[0]);        //显示字符串
  136.         LCD1602_Dis_Str(0, 1, &str[0]);        //显示字符串
  137. //        LCD1602_Dis_OneChar(15, 1, 0xff); //显示一个黑方格  请查表
  138.         while(1);
  139. }
复制代码

IMG_20190502_192746.jpg (4.04 MB, 下载次数: 27)

IMG_20190502_192746.jpg

6B2M9GOF9RP30ENP[R1PGVA.png (13.98 KB, 下载次数: 26)

6B2M9GOF9RP30ENP[R1PGVA.png

OV8D48STACZ9X$3IJ1H2BTD.png (93.02 KB, 下载次数: 26)

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

使用道具 举报

沙发
ID:96682 发表于 2019-5-2 22:45 | 只看该作者
把 LCD1602 倒过来 PCB 布线不是与单片机端口对应了么,把简单的问题复杂化。

搞不定切断线路用飞线方式解决
回复

使用道具 举报

板凳
ID:213173 发表于 2019-5-3 07:07 | 只看该作者
楼主的问题不在逆序函数,在于判忙函数,修改一下就好了。注:仿真不完全代表实际电路有效!



  1. /*********************************************************************************
  2. * 【外部晶振】: 11.0592mhz        
  3. * 【主控芯片】: STC89C52
  4. * 【编译环境】: Keil μVisio3        
  5. * 【程序功能】: LCD1602显示                                                                                   
  6. * 【使用说明】: 正确接上LCD1602液晶并调节好对比度
  7. *  说明:免费开源,不提供源代码分析.
  8. **********************************************************************************/
  9. #include <reg52.h>

  10. /*=================================================
  11. *自定义数据类型
  12. =================================================*/
  13. typedef unsigned char uchar;
  14. typedef unsigned int uint;

  15. #define LCD1602_DB P0        //LCD1602数据总线

  16. //<font color="#ff0000">
  17. sbit LCD1602_RS = P2^5;         //RS端
  18. sbit LCD1602_RW = P2^6;         //RW端
  19. sbit LCD1602_EN = P2^7;         //EN端</font>
  20. //sbit DU = P2^6;//
  21. //sbit WE = P2^7;//数码管位选段选用于关闭数码管显示

  22. unsigned char swapbit(unsigned char udata)  //<font color="#ff0000">逆位显示</font>
  23. {
  24.   unsigned char ii,tmp=0;
  25.   for(ii=0;ii<8;ii++)
  26.   {
  27.     tmp<<=1;
  28.     if(udata&0x01)
  29.     {
  30.       tmp|=0x01;
  31.     }
  32.     udata>>=1;
  33.   }
  34.   return tmp;
  35. }
  36. /*=================================================
  37. *函数名称:Read_Busy
  38. *函数功能:判断1602液晶忙,并等待
  39. =================================================*/
  40. bit Read_Busy()
  41. {
  42.         unsigned char LCD_Status;
  43.         LCD1602_RS = 0;
  44.         LCD1602_RW = 1;
  45.         LCD1602_EN = 1;
  46.         LCD_Status = swapbit(LCD1602_DB);
  47.         LCD1602_EN = 0;
  48.         return LCD_Status;
  49. }
  50. /*
  51. void Read_Busy()
  52. {
  53.         uchar busy;
  54.         LCD1602_DB = 0xff;//复位数据总线
  55.         LCD1602_RS = 0;          //拉低RS
  56.         LCD1602_RW = 1;          //拉高RW读
  57.         do
  58.         {
  59.                 LCD1602_EN = 1;//使能EN
  60.                 busy = swapbit(LCD1602_DB);//读回数据
  61.                 LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  62.         }while(busy); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
  63. }*/
  64. /*=================================================
  65. *函数名称:LCD1602_Write_Cmd
  66. *函数功能:写LCD1602命令
  67. *调用:Read_Busy();
  68. *输入:cmd:要写的命令
  69. =================================================*/
  70. void LCD1602_Write_Cmd(uchar cmd)
  71. {
  72. //        Read_Busy();         //判断忙,忙则等待
  73.         while((Read_Busy()&0x80)==0x80);//判忙
  74.         LCD1602_RS = 0;
  75.         LCD1602_RW = 0;        //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
  76.         LCD1602_DB = swapbit(cmd);//写入命令
  77.         LCD1602_EN = 1;         //拉高使能端 数据被传输到LCD1602内
  78.         LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
  79. }
  80. /*=================================================
  81. *函数名称:LCD1602_Write_Dat
  82. *函数功能:写LCD1602数据
  83. *调用:Read_Busy();
  84. *输入:dat:需要写入的数据
  85. =================================================*/
  86. void LCD1602_Write_Dat(uchar dat)
  87. {
  88. //        Read_Busy();
  89.         while((Read_Busy()&0x80)==0x80);//判忙
  90.         LCD1602_RS = 1;
  91.         LCD1602_RW = 0;
  92.         LCD1602_DB = swapbit(dat);
  93.         LCD1602_EN = 1;
  94.         LCD1602_EN = 0;
  95. }
  96. /*=================================================
  97. *函数名称:LCD1602_Dis_OneChar
  98. *函数功能:在指定位置显示一个字符
  99. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();        
  100. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  101.                 dat:需要显示的数据以ASCLL形式显示
  102. =================================================*/
  103. /*
  104. void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
  105. {
  106.         if(y)        x |= 0x40;
  107.         x |= 0x80;
  108.         LCD1602_Write_Cmd(x);
  109.         LCD1602_Write_Dat(dat);
  110. }
  111. */
  112. /*=================================================
  113. *函数名称:LCD1602_Dis_Str
  114. *函数功能:在指定位置显示字符串
  115. *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
  116. *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
  117.                 *str:需要显示的字符串
  118. =================================================*/
  119. void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
  120. {
  121.         if(y) x |= 0x40;
  122.         x |= 0x80;
  123.         LCD1602_Write_Cmd(x);
  124.         while(*str != '\0')
  125.         {
  126.                 LCD1602_Write_Dat(*str++);
  127.         }
  128. }
  129. /*=================================================
  130. *函数名称:Init_LCD1602
  131. *函数功能:1602初始化
  132. *调用:    LCD1602_Write_Cmd();
  133. =================================================*/
  134. void Init_LCD1602()
  135. {
  136.         LCD1602_Write_Cmd(0x38); //设置16*2显示,5*7点阵,8位数据接口
  137.         LCD1602_Write_Cmd(0x0c); //开显示
  138.         LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
  139.         LCD1602_Write_Cmd(0x01); //清除显示
  140. }

  141. void main()
  142. {
  143. // int n;
  144.         uchar TestStr[] = {"welcome!"};
  145.         uchar str[] = {"LCD1602 display"};
  146.         //DU = 0;
  147.         //WE = 0;//关闭数码管显示
  148.         Init_LCD1602();//1602初始化
  149.         LCD1602_Dis_Str(0, 0,TestStr);    //显示字符串
  150.         LCD1602_Dis_Str(0, 1,str);        //显示字符串
  151. //        LCD1602_Dis_OneChar(15, 1, 0xff); //显示一个黑方格  请查表
  152.         while(1);
  153. }
复制代码



回复

使用道具 举报

地板
ID:293387 发表于 2019-5-3 14:28 | 只看该作者
你的P0口是否接有拉电阻。

1ad5ad6eddc451da7124d17db6fd5266d1163252.jpg (26.42 KB, 下载次数: 29)

1ad5ad6eddc451da7124d17db6fd5266d1163252.jpg
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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