微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 用STC89C52和LCD1602设计秒表 显示缺失

用STC89C52和LCD1602设计秒表 显示缺失

时间:10-02 整理:3721RD 点击:
显示问题如图,为什么?

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define delayNOP ( ) {_nop_( ); _nop_( ); _nop_( ); _nop_( );}

  6. //LCD控制函数
  7. void LCD_Initialize();
  8. void LCD_Set_POS(uchar);
  9. void LCD_Write_Date(uchar);
  10. void Display_String(uchar *,uchar);

  11. sbit K1 = P1^0;
  12. sbit K2 = P1^1;
  13. sbit BEEP = P3^0;
  14. sbit LCD_RS = P2^0;
  15. sbit LCD_RW = P2^1;
  16. sbit LCD_EN = P2^2;
  17. uchar KeyCount = 0;
  18. uchar code msg1[] ={"   Miao   Biao  "};
  19. uchar code msg2[] ={">>>>            "};
  20. uchar code Prompts[] [16] =
  21. {
  22.         {":: 1---->       "},
  23.         {":: 1----> ::2   "},
  24.         {":: 1->2 ::3-->  "},
  25.         {":: 1->2 ::3-->4 "}
  26. };
  27. // 计时缓冲与显示缓冲
  28. uchar Time_Buffer[]       ={0,0,0,0};
  29. uchar LCD_Display_Buffer[]={"00:00:00:00"};

  30. void Beep ()// 蜂鸣器
  31. {
  32.         uchar i,j = 70;
  33.         for (i = 0;i< 180;i++ )
  34.                 {
  35.                         while(--j);BEEP =~BEEP;
  36.                 }
  37.         BEEP = 0;
  38. }
  39. // 延时
  40. void DelayX(uint ms)
  41. {
  42.          uchar i;
  43.         while(ms--) for (i= 0;i< 120;i++);
  44. }
  45. // 显示计时
  46. void Show_Second( )
  47. {
  48.    uchar i;
  49.    LCD_Set_POS(0x45); //设置LCD显示起点
  50.    for(i = 3;i != 0xff ;i--);
  51.         {
  52. //将两位整数的1/100s,秒,分,时转换为8位数字字符
  53.                 LCD_Display_Buffer[2*i+1] = Time_Buffer[i] / 10 + '0';
  54.                 LCD_Display_Buffer[2*i  ] = Time_Buffer[i] % 10 + '0';
  55. //在 = 3,2,1,0时分别显示时,分,秒,1/100s
  56.                 LCD_Write_Date(LCD_Display_Buffer[2*i+1]);
  57.                 LCD_Write_Date(LCD_Display_Buffer[2*i]);
  58.                 LCD_Write_Date(':');
  59.         }
  60. }
  61. // Time0中断
  62. void Time0( ) interrupt 1 using 0
  63. {
  64.         TH0 = -10000 / 256;
  65.         TL0 = -10000 % 256;
  66.         Time_Buffer[0] ++;
  67.         if(Time_Buffer[0] == 100)
  68.                 {
  69.                      Time_Buffer[0] = 0; Time_Buffer[1]++;
  70.                 }
  71.         if(Time_Buffer[1] == 60)          //秒
  72.                 {
  73.                       Time_Buffer[1] = 0; Time_Buffer[2]++;
  74.                 }
  75.         if(Time_Buffer[2] == 60)          //分
  76.                 {
  77.                       Time_Buffer[2] = 0; Time_Buffer[3]++;
  78.                 }
  79.         if(Time_Buffer[3] == 24)          //时
  80.                       Time_Buffer[3] = 0;
  81. }
  82. //
  83. //主函数
  84. //
  85. void main( )
  86. {
  87. uchar i;
  88. IE = 0x82;
  89. TMOD = 0x01;
  90. TH0 = -10000 / 256;
  91. TL0 = -10000 % 256;
  92. LCD_Initialize( );
  93. Display_String(msg1,0x00);
  94. Display_String(msg2,0x40);
  95. while(1)
  96.         {
  97.                  if(K1 == 0)
  98.                 {
  99.                           DelayX(100);
  100.                           i = ++KeyCount;
  101.                           switch (i)
  102.                         {
  103.                                  case 1:
  104.                                  case 3: TR0 = 1;
  105.                                         Display_String(Prompts[i-1],0);
  106.                                         break;
  107.                                 case 2:
  108.                                  case 4: TR0 = 0;
  109.                                                 Display_String(Prompts[i-1],0);
  110.                                         break;
  111.                                  default:TR0 = 0;
  112.                                                break;
  113.                         }
  114.                          while (K1 == 0);       // 等待释放K1键
  115.                  Beep( );
  116.                 }        
  117.           else
  118.           if(K2 == 0)
  119.         {
  120.               TR0 = 0;
  121.               KeyCount = 0;
  122.               for(i = 0;i < 4; i++)
  123.                 Time_Buffer [i] = 0;    // 清零计数缓冲
  124.                 Display_String(msg1,0);
  125.                 Beep( );
  126.                 DelayX(100);
  127.                 while (K2 == 0);       // 等待释放K2键
  128.         }
  129.     Show_Second( );
  130.         }
  131. }

复制代码

  1. //    1602LCD显示驱动函数
  2. #include<reg51.h>
  3. #include<intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define DelayNOP( ){_nop_( ); _nop_( ); _nop_( ); _nop_( );}
  7. sbit LCD_RS = P2^0;
  8. sbit LCD_RW = P2^1;
  9. sbit LCD_EN = P2^2;
  10. bit LCD_Busy_Check( );
  11. void LCD_Initialize( );
  12. void LCD_Set_POS(uchar);
  13. void LCD_Write_Command(uchar);
  14. void LCD_Write_Date(uchar);
  15. // 延时
  16. void DelayMS(uint ms)
  17. {
  18.   uchar t;
  19.   while(ms--) for (t =0;t < 120;t++);
  20. }
  21. // LCD忙检查
  22. bit LCD_Busy_Check( )
  23. {
  24.         bit Result;
  25.         LCD_RS = 0; LCD_RW = 1; LCD_EN = 1;DelayNOP( );
  26.         Result = (bit)(P0 & 0x80);
  27.         LCD_EN = 0;
  28.         return Result;
  29. }
  30. // 向LCD写指令
  31. void LCD_Write_Command(uchar cmd)
  32. {
  33.         while(LCD_Busy_Check() );
  34.         LCD_RS = 0; LCD_RW = 0; LCD_EN = 0;
  35.          _nop_( ); _nop_( );
  36.         P0 = cmd;  DelayNOP( );
  37.         LCD_EN = 1;DelayNOP( );
  38.         LCD_EN = 0;
  39. }
  40. // 向LCD写数据
  41. void LCD_Write_Date(uchar str)
  42. {
  43.         while(LCD_Busy_Check() );
  44.         LCD_RS = 1; LCD_RW = 0; LCD_EN = 0;P0 = str; DelayNOP( );
  45.         LCD_EN = 1; DelayNOP( );LCD_EN = 0;
  46. }
  47. // 初始化LCD
  48. void LCD_Initialize( )
  49. {
  50.         DelayMS(5); LCD_Write_Command(0x38);
  51.         DelayMS(5); LCD_Write_Command(0x0c);
  52.         DelayMS(5); LCD_Write_Command(0x06);
  53.         DelayMS(5); LCD_Write_Command(0x01);
  54.         DelayMS(5);
  55. }
  56. // 设置显示位置
  57. void LCD_Set_POS(uchar Position)
  58. {
  59.         LCD_Write_Command(Position | 0x80);
  60. }
  61. //显示函数,在LCD指定行上显示字符串
  62. void Display_String(uchar *str,uchar LineNO)
  63. {
  64.   uchar k;
  65.   LCD_Set_POS(LineNO);
  66.   for (k = 0;k < 16;k++) LCD_Write_Date(str[k]);
  67. }

复制代码



哈哈,疯了好,调程序难免会这样,试试还是把其他会更改Time_Buffer[] 的程序都屏蔽,然后把Show_Second( )里的for循环不要,改成直接一个一个显示,就是
LCD_Write_Date(Time_Buffer[3] / 10 + '0');    LCD_Write_Date(Time_Buffer[3] % 10 + '0');     LCD_Write_Date(':');
LCD_Write_Date(Time_Buffer[2] / 10 + '0');    LCD_Write_Date(Time_Buffer[2] % 10 + '0');     LCD_Write_Date(':');
LCD_Write_Date(Time_Buffer[1] / 10 + '0');    LCD_Write_Date(Time_Buffer[1] % 10 + '0');     LCD_Write_Date(':');
LCD_Write_Date(Time_Buffer[0] / 10 + '0');    LCD_Write_Date(Time_Buffer[0] % 10 + '0');     LCD_Write_Date(':');
这样应该不会再缺失了吧,如果缺失,那就不是显示的问题了

应该是时间数据没有处理好就传给了1602所导致的

//将两位整数的1/100s,秒,分,时转换为8位数字字符
                LCD_Display_Buffer[2*i+1] = Time_Buffer[i] / 10 + '0';
                LCD_Display_Buffer[2*i  ] = Time_Buffer[i] % 10 + '0';
//在 = 3,2,1,0时分别显示时,分,秒,1/100s
这里改成
LCD_Display_Buffer[2*i+1] = Time_Buffer[i] / 16 + '0';
                LCD_Display_Buffer[2*i  ] = Time_Buffer[i] % 16 + '0';
试试

还是不行 显示的还是上面那张图

怎么解决呢?

先不要做计时操作,直接往Time_Buffer[] 里随意写入时间数据,看是否能正确显示,先确定了能正确显示,再找其他的问题

不能 也是缺少后面的时间

试试把其他会更改Time_Buffer[] 的程序都屏蔽,然后Time_Buffer[] 里填4个小于10的数值,再看看显示如何

如果Time_Buffer[] 里填小于10的数也显示缺失的话,那有可能循环只循环了一次,所以后面的就根本没显示,试试把
   for(i = 3;i != 0xff ;i--);
        {
//将两位整数的1/100s,秒,分,时转换为8位数字字符
                LCD_Display_Buffer[2*i+1] = Time_Buffer[i] / 10 + '0';
里的   for(i = 3;i != 0xff ;i--);,改成   for(i = 3;i >= 0x00 ;i--);

还是没用 我快疯了

O(∩_∩)O谢谢大神 可以了 应该是for循环的问题

进来学习!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top