找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3900|回复: 19
收起左侧

求帮忙看看单片机LCD1602显示一排白块的问题

[复制链接]
ID:1019715 发表于 2022-5-7 15:37 | 显示全部楼层 |阅读模式
烧写程序给板子上电之后,1602只显示这一行白块,应该不是对比度的问题?因为调可调电阻只是亮度变了下,程序在proteus上仿真是能实现运行的,大佬们帮忙看看,本人小白不太懂。。
IMG_20220506_164801.jpg
单片机源程序如下:
  1. #include <reg52.h>

  2. unsigned long int fre;
  3. unsigned char time;
  4. unsigned int count;
  5. unsigned int count1;

  6. sbit   LCD_RS=P1^0;          //片选信号
  7. sbit   LCD_RW=P1^1;          //读写信号
  8. sbit   LCD_E=P1^2;           //使能信号

  9. #define LCD_DB  P0        //数据信号

  10. unsigned char character[10]={0};//在屏幕上显示的字符串
  11. unsigned char character_1[]={"fre= Hz"};
  12. unsigned char FLAG = 0;  //是否分频选择标志

  13. void LCD_init(void);//初始化函数   
  14. void LCD_write_command(unsigned char command);//写指令函数         
  15. void LCD_write_data(unsigned char dat);//写数据函数           
  16. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  17. void delay_n40us(unsigned int n);//延时函数
  18. void timer_init();            //中断初始化函数  

  19. //-----------------------------延时函数---------------------------
  20. void delay_n40us(unsigned int n)                  //延时函数
  21. {
  22.         unsigned int i;
  23.         unsigned char j;            
  24.         for(i=n;i>0;i--)
  25.         for(j=0;j<2;j++);         
  26. }
  27. void delay_1s()
  28. {
  29.         unsigned int i,j;
  30.         for(i = 0;i<100;i++)
  31.                 for(j = 0;j<1000;j++);
  32. }
  33. //---------------------lcd1602液晶显示函数--------------------                                    
  34. void LCD_init(void)         //液晶初始化函数
  35. {
  36.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  37.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  38.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  39.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  40.         LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  41.         LCD_write_command(0x06);//设定输入方式,增量不移位
  42.         LCD_write_command(0x01);//清除屏幕显示         
  43.         LCD_write_command(0x80);//数据指针起点
  44.         delay_n40us(100);//清屏延时
  45. }
  46. void LCD_write_command(unsigned char dat)  //写命令函数
  47. {
  48.         LCD_DB=dat;
  49.         LCD_RS=0;//指令         
  50.         LCD_RW=0;//写入         
  51.         LCD_E=1; //使能         
  52.         LCD_E=0;
  53.         delay_n40us(1);//写命令延时   
  54. }         
  55. void LCD_write_data(unsigned char dat)          //写数据函数
  56. {
  57.         LCD_DB=dat;
  58.         LCD_RS=1;//数据         
  59.         LCD_RW=0;//写入         
  60.         LCD_E=1;//使能  
  61.         LCD_E=0;
  62.         delay_n40us(1);         //写数据延时
  63. }
  64. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)//显示一个字符
  65. {
  66.         unsigned char address;
  67.         if(y==1)
  68.                  address=0x80+x;         //显示在第一排的时候的x的地址
  69.         else
  70.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  71.         LCD_write_command(address);         //输入地址
  72.         LCD_write_data(dat);                 //输入数据
  73. }
  74. void LCD_disp_num(unsigned char x,unsigned char y,unsigned char dat)//显示一个数字
  75. {
  76.         unsigned char address;
  77.         if(y==1)
  78.                  address=0x80+x;         //显示在第一排的时候的x的地址
  79.         else
  80.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  81.         LCD_write_command(address);         //输入地址
  82.         LCD_write_data(dat+48);                 //输入数据
  83. }
  84. void dis_num(void)
  85. {
  86.         unsigned char i=0,j=0,k=0;
  87.         LCD_write_command(0x01);//清除屏幕显示
  88.         character[0] = fre/10000000;
  89.         character[1] = fre/1000000%10;
  90.         character[2] = fre/100000%10;
  91.         character[3] = fre/10000%10;
  92.         character[4] = fre/1000%10;
  93.         character[5] = fre/100%10;
  94.         character[6] = fre/10%10;
  95.         character[7] = fre%10;
  96.     character[8] = 'H';
  97.         character[9] = 'z';
  98.         for(i = 0;i<4;i++)                 //显示“fre=”
  99.         {
  100.                  LCD_disp_char(i+0,1,character_1[i]);
  101.         }
  102.         for(i = 0;i<10;i++)         //判断第一个不为0的数
  103.         {
  104.                 if(character[i]!=0)
  105.                         break;
  106.         }
  107.         k = 8-i;
  108.         for(j = 0;j<k;j++)         //显示所有的数字
  109.         {
  110.                         LCD_disp_num(4+j,1,character[i++]);        
  111.         }
  112.     for(i = 5;i<7;i++)         //显示“Hz”
  113.         {
  114.                  LCD_disp_char(j+4,1,character_1[i]);
  115.                 j++;
  116.         }
  117. }
复制代码


回复

使用道具 举报

ID:262 发表于 2022-5-7 16:17 | 显示全部楼层
来看一下51hei论坛里面解决此问题的痛苦经历吧:
51hei搜索框输入"1602 方块"或者"1602 黑块"或者"1602 白块"或者"1602 格":

这个是io口设置问题,最终搞定了:http://www.51hei.com/bbs/dpj-199732-1.html
http://www.51hei.com/bbs/dpj-168643-1.html
http://www.51hei.com/bbs/dpj-208189-1.html
http://www.51hei.com/bbs/dpj-210690-1.html

既有可能是软件问题也有硬件问题
http://www.51hei.com/bbs/dpj-187378-1.html
http://www.51hei.com/bbs/dpj-160754-1.html
回复

使用道具 举报

ID:121859 发表于 2022-5-7 17:24 | 显示全部楼层
写命令和数据延时时间可能太短了,加长,到1~3毫秒估计就可以了。
回复

使用道具 举报

ID:213173 发表于 2022-5-7 17:47 | 显示全部楼层
你的主函数到哪里去了???   40us延时太短,能仿真不代表实物也能行。
  1. #include <reg52.h>

  2. unsigned long int fre;
  3. unsigned char time;
  4. unsigned int count;
  5. unsigned int count1;

  6. sbit   LCD_RS=P1^0;          //片选信号
  7. sbit   LCD_RW=P1^1;          //读写信号
  8. sbit   LCD_E =P1^2;           //使能信号

  9. #define LCD_DB  P0        //数据信号

  10. unsigned char character[10]={0};//在屏幕上显示的字符串
  11. unsigned char character_1[]={"fre= Hz"};
  12. unsigned char FLAG = 0;  //是否分频选择标志

  13. void LCD_init(void);//初始化函数   
  14. void LCD_write_command(unsigned char command);//写指令函数         
  15. void LCD_write_data(unsigned char dat);//写数据函数           
  16. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  17. void delay_n40us(unsigned int n);//延时函数
  18. void timer_init();            //中断初始化函数  
  19. void delay_ms(unsigned int t);
  20. //-----------------------------延时函数---------------------------
  21. /*
  22. void delay_n40us(unsigned int n)                  //延时函数
  23. {
  24.         unsigned int i;
  25.         unsigned char j;            
  26.         for(i=n;i>0;i--)
  27.         for(j=0;j<2;j++);         
  28. }*/
  29. void delay_ms(unsigned int t)
  30. {
  31.         unsigned int i,j;
  32.         for(i=t;i>0;i--)
  33.                 for(j=120;j>0;j--);
  34. }
  35. //---------------------lcd1602液晶显示函数--------------------                                    
  36. void LCD_init(void)         //液晶初始化函数
  37. {
  38.         LCD_RW=0;//写入     
  39.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  40.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  41.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  42.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  43.         LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  44.         LCD_write_command(0x06);//设定输入方式,增量不移位
  45.         LCD_write_command(0x01);//清除屏幕显示         
  46.         LCD_write_command(0x80);//数据指针起点
  47. }
  48. void LCD_write_command(unsigned char dat)  //写命令函数
  49. {  
  50.         LCD_RS=0;//指令                 
  51.         LCD_DB=dat;
  52.         delay_ms(1);
  53.         LCD_E=1; //使能         
  54.         delay_ms(1);
  55.         LCD_E=0;
  56. }         
  57. void LCD_write_data(unsigned char dat)          //写数据函数
  58. {
  59.         LCD_RS=1;//数据         
  60.         LCD_DB=dat;
  61.         delay_ms(1);
  62.         LCD_E=1;//使能  
  63.         delay_ms(1);
  64.         LCD_E=0;
  65. }
  66. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)//显示一个字符
  67. {
  68.         unsigned char address;
  69.         if(y==1)
  70.                  address=0x80+x;         //显示在第一排的时候的x的地址
  71.         else
  72.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  73.         LCD_write_command(address);         //输入地址
  74.         LCD_write_data(dat);                 //输入数据
  75. }
  76. void LCD_disp_num(unsigned char x,unsigned char y,unsigned char dat)//显示一个数字
  77. {
  78.         unsigned char address;
  79.         if(y==1)
  80.                  address=0x80+x;         //显示在第一排的时候的x的地址
  81.         else
  82.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  83.         LCD_write_command(address);         //输入地址
  84.         LCD_write_data(dat+48);                 //输入数据
  85. }
  86. void dis_num(void)
  87. {
  88.         unsigned char i=0,j=0,k=0;
  89.         LCD_write_command(0x01);//清除屏幕显示
  90.         character[0] = fre/10000000;
  91.         character[1] = fre/1000000%10;
  92.         character[2] = fre/100000%10;
  93.         character[3] = fre/10000%10;
  94.         character[4] = fre/1000%10;
  95.         character[5] = fre/100%10;
  96.         character[6] = fre/10%10;
  97.         character[7] = fre%10;
  98.         character[8] = 'H';
  99.         character[9] = 'z';
  100.         for(i = 0;i<4;i++)                 //显示“fre=”
  101.         {
  102.                 LCD_disp_char(i+0,1,character_1[i]);
  103.         }
  104.         for(i = 0;i<10;i++)         //判断第一个不为0的数
  105.         {
  106.                 if(character[i]!=0)
  107.                 break;
  108.         }
  109.         k = 8-i;
  110.         for(j = 0;j<k;j++)         //显示所有的数字
  111.         {
  112.                 LCD_disp_num(4+j,1,character[i++]);        
  113.         }
  114.         for(i = 5;i<7;i++)         //显示“Hz”
  115.         {
  116.                 LCD_disp_char(j+4,1,character_1[i]);
  117.                 j++;
  118.         }
  119. }
  120. void main()
  121. {
  122.         LCD_init();
  123.         dis_num();
  124.         while(1);
  125. }
复制代码
回复

使用道具 举报

ID:149451 发表于 2022-5-7 18:54 | 显示全部楼层
没看到你的MCU底板PCB定义,但直觉是你的1602插反方向了(通常设计开发板,1602不会盖在MCU上)
回复

使用道具 举报

ID:94031 发表于 2022-5-7 19:01 | 显示全部楼层
调调左上角对比度电位器,看对比度合适不。
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 19:36 | 显示全部楼层
发表于 2022-5-7 17:47
你的主函数到哪里去了???   40us延时太短,能仿真不代表实物也能行。
  1. void main()
  2. {
  3.         unsigned char i;
  4.         LCD_init();
  5.         timer_init();        
  6.         for(i = 0;i<4;i++)
  7.         {
  8.                  LCD_disp_char(i+0,1,character_1[i]);
  9.         }
  10.         while(1)
  11.         {
  12.                 dis_num();  
  13.                 delay_1s();
  14.         }
  15. }

  16. void timer_init(void)   
  17. {
  18.         TMOD=0x66;
  19.         TH0=0;  
  20.         TL0=0;
  21.         TR0=1;  
  22.         ET0=1;  
  23.         TH1=0;   
  24.         TL1=0;
  25.         TR1=1;  
  26.         ET1=1;
  27.         RCAP2H=(65536-62500)/256;
  28.         RCAP2L=(65536-62500)%256;
  29.         TH2=RCAP2H;      
  30.         TL2=RCAP2L;
  31.         ET2=1;      
  32.         TR2=1;
  33.         EA=1;
  34. }

  35. void timer2(void) interrupt 5 //¶¨ê±Æ÷2ÖD¶Ï(62.5ms)
  36. {
  37.         time++;
  38.         TF2=0;      
  39.         if (time==16)      
  40.         {
  41.            time=0;     
  42.            EA=0;            
  43.            fre=(long)count1*256+TL1;   
  44.            FLAG = 0;
  45.          
  46.            if(fre<2000)
  47.            {
  48.                            fre = (long)count*256+TL0;
  49.                         FLAG = 1;         
  50.            }
  51.                 if(!FLAG)
  52.                 {
  53.                         fre = fre *100;
  54.                 }
  55.            TL0=0;      
  56.            TH0=0;
  57.            TL1=0;
  58.            TH1=0;
  59.            count=0;   
  60.            count1=0;
  61.            EA=1;      
  62.         }
  63. }
  64. //----------------------------------------------------------------
  65. void timer0(void) interrupt 1     
  66. {
  67.         count++;
  68. }               
  69. //----------------------------------------------------------------
  70. void timer1(void) interrupt 3
  71. {
  72.         count1++;
  73. }
复制代码
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 19:39 | 显示全部楼层
w1179benp 发表于 2022-5-7 18:54
没看到你的MCU底板PCB定义,但直觉是你的1602插反方向了(通常设计开发板,1602不会盖在MCU上)

没有反接,只是画pcb的时候没有考虑到ic锁紧座的高度,所以我的1602是有些斜着插到排母上的,而且我这个板子没有USB接口,我需要先用烧录器烧录程序才取出芯片放到板子上
回复

使用道具 举报

ID:149451 发表于 2022-5-7 19:58 | 显示全部楼层
我Dell沈阳了 发表于 2022-5-7 19:39
没有反接,只是画pcb的时候没有考虑到ic锁紧座的高度,所以我的1602是有些斜着插到排母上的,而且 ...

还是把原理图、PCB图上上来看看吧。
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 20:27 | 显示全部楼层
这个是原理图与PCB
I4{8KU_RY9D@}G[1XJJ@[9A.png
1HF4@NZ(IGHLA2UPFGE6T.png
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 20:27 | 显示全部楼层
w1179benp 发表于 2022-5-7 19:58
还是把原理图、PCB图上上来看看吧。

已经发上来了
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 20:31 | 显示全部楼层
因为我没有考虑到这个单片机锁紧座的高度,所以1602插到排母上之后被卡住了所以是这样斜着插上去的,这样会有很大影响吗?
IMG_20220507_202812.jpg
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 20:53 | 显示全部楼层
有几张图在只看大图那里,问问像我最后一张图上这个1602插法影响大吗?需要多插一个排母吗?
回复

使用道具 举报

ID:1019715 发表于 2022-5-7 21:00 | 显示全部楼层
主程序直接粘上来注释没了,发两张图
PO1M56L9C4UXTKLQEPJ`[2M.png
B6[AN7[3R}N~VY5H`JE9WDO.png
回复

使用道具 举报

ID:161164 发表于 2022-5-7 23:15 来自手机 | 显示全部楼层
我Dell沈阳了 发表于 2022-5-7 20:53
有几张图在只看大图那里,问问像我最后一张图上这个1602插法影响大吗?需要多插一个排母吗?

一试无妨
回复

使用道具 举报

ID:1012735 发表于 2022-5-8 13:47 | 显示全部楼层
E口跳变缺少延时!

*/
//------------------------------------------------
//LCD E口跳变时,LCD显示一个字符/接收一个指令
//RS=0:命令指令,RS=1:显示数据指令
//------------------------------------------------
void LcdWriteInfo( u8 RS, u8 RW, u8 dat )
{
        //while(LcdBusy());
       
        LCD1602_RS = RS;
        LCD1602_E  = 0;
        LCD1602_RW = RW;
       
        LCD1602_DATA = dat;
        delay1Cycle(5);
       
        LCD1602_E  = 1;
        delay1Cycle(5);
        LCD1602_E  = 0;
        delay1Cycle(5);
}
回复

使用道具 举报

ID:61140 发表于 2022-5-8 14:20 | 显示全部楼层
我Dell沈阳了 发表于 2022-5-7 20:53
有几张图在只看大图那里,问问像我最后一张图上这个1602插法影响大吗?需要多插一个排母吗?

第一:请确认LCD1602是否插反方向,插反方向是会导致白块的,但不会烧坏屏
第二:请确认你的RS/RW/E/DATA   这些端口是否和程序里面的一致,不一致也会导致屏白块
第三:以上两项都正确,再确认你的程序写指令和写数据延时部分是否正确,一般仿真是不能评论实物的,仿真是理想化的仿真,但实物的时候一切以实际为主.
        如果你不确定你的写指令和写数据部分延时需要多少,尽可能的调大(一般大些不会导致白块或不显示,只是写指令和写数据等的时间稍长些),等显示出来再调小,调到刚好可以稳定显示又不会太大为准(比如你调到40刚好可以显示了,再小就不显示了,直接调到45-50即可,调太大影响程序运行速度)
回复

使用道具 举报

ID:161164 发表于 2022-5-10 14:03 | 显示全部楼层
这种芯片座有机会接触不良
建议用以下代码检查LCD1602各信号脚有没有电平变化

  1. #include <reg52.h>

  2. void Delay500ms()                //@12.000MHz
  3. {
  4.         unsigned char i, j, k;

  5.         i = 4;
  6.         j = 205;
  7.         k = 187;
  8.         do
  9.         {
  10.                 do
  11.                 {
  12.                         while (--k);
  13.                 } while (--j);
  14.         } while (--i);
  15. }

  16. void main()
  17. {
  18.     while (1)
  19.     {
  20.                         P0 ^= 0xFF;//取反电平
  21.                         P1 ^= 0xFF;//取反电平
  22.                         Delay500ms();
  23.     }
  24. }
复制代码



回复

使用道具 举报

ID:1019715 发表于 2022-5-19 15:04 | 显示全部楼层
问题已经解决了,是PCB板我把复位按键的两个相邻引脚接一起导致一直通路,还有三极管原理图和PCB封装不对应导致出错,重新打板之后已经能正常显示了,感谢各位回复过的大佬,此贴终结。
回复

使用道具 举报

ID:904023 发表于 2022-5-19 22:58 来自手机 | 显示全部楼层
可能是对比度没填好,可以调下电位器
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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