[创客交流] 解决按键控制数码管带来闪灭显示问题的项目工程-优化版1

[复制链接]
 楼主| zhamatu 发表于 2020-10-25 17:18 | 显示全部楼层 |阅读模式
  1. /*****
  2. 为什么按下按键到按键抬起后,会干扰到数码管的显示?原因:如果按键扫描
  3. 函数和数码管显示函数都放在主函数的固定循环内,当按键按下后,按键扫描
  4. 函数进行按键扫描,在扫描到按键延时后,CPU被限制在按键延时处进行计时,
  5. 却无法运行其他程序,从而导致数码管显示函数无法运行,就会出现数码管闪
  6. 灭显示问题。人能看到数码管闪烁是因为人眼能识别高频率(人眼看不到闪烁
  7. 的频率为50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想让人眼看不到数码管闪
  8. 烁,数码管显示函数的显示频率至少是50Hz,即1/50Hz=0.02秒,也不是越高
  9. 好,还要结合按键扫描函数的按键延时来取出最恰当的显示频率。
  10. 本程序分两个程序。一个是程序一,按键控制数码管带来闪灭显示问题的程序。
  11. 另一个是程序二,解决按键控制数码管带来闪灭显示问题的程序。通过把数码
  12. 管显示函数放在定时器中断子程序中,以及把按键扫描函数放在主函数固定循
  13. 环内。提醒:先试程序一,再试程序二,之后两者对比,找出不同点,取最适
  14. 合的。
  15. *****/


 楼主| zhamatu 发表于 2020-10-25 17:22 | 显示全部楼层
  1. //程序一:按键控制数码管带来闪灭显示问题的程序
  2. //#include<reg51.h>
  3. //#define uchar unsigned char
  4. //#define uint unsigned int
  5. //sbit add=P3^0;
  6. //sbit dec=P3^4;
  7. //uchar lingweiflag;
  8. //uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
  9. //uint num;
  10. //uint qian,bai,shi,ge;//定义拆字变量
  11. //  /**ms级延时子程序**/
  12. //  void delay(uint x)
  13. //{
  14. //   uint i,j;                       
  15. //   for(i=0;i<x;i++)     
  16. //    for(j=0;j<110;j++);
  17. //  }
  18. //  void display()
  19. //{
  20. //   qian=num/1000;//取得千位数字
  21. //   bai=num%1000/100;//取得百位数字
  22. //   shi=num%100/10;//取得十位数字
  23. //   ge=num%10;//取得个位数字
  24. //
  25. //   P2=0xfe;//数码管千位显示位
  26. //   P1=table[qian];//数码管千位数值显示
  27. //   delay(2);//延时
  28. //
  29. //   P2=0xfd;//数码管百位显示位
  30. //   P1=table[bai];//数码管百位数值显示
  31. //   delay(2);//延时
  32. //
  33. //   P2=0xfb;//数码管十位显示位
  34. //   P1=table[shi];//数码管十位数值显示
  35. //   delay(2);//延时
  36. //
  37. //   P2=0xf7;//数码管个位显示位
  38. //   P1=table[ge];//数码管个位数值显示
  39. //   delay(2);//延时
  40. // }
  41. //  void keyscan()
  42. //{
  43. //   if(add==0)
  44. // {         
  45. //    delay(5);
  46. //    if(add==0)
  47. //  {
  48. //     num++;
  49. //     while(!add);
  50. //     lingweiflag=0;
  51. //    }
  52. //   }
  53. //   if(dec==0&&lingweiflag==0)
  54. // {         
  55. //    delay(5);
  56. //    if(dec==0)
  57. //  {
  58. //     num--;
  59. //     while(!dec);
  60. //    }
  61. //   }
  62. //   if(num>9999)
  63. // {
  64. //    num=0;
  65. //   }
  66. //   if(num==0)
  67. // {
  68. //    num=0;
  69. //    lingweiflag=1;
  70. //   }
  71. // }
  72. //  void main()
  73. //{
  74. //   while(1)
  75. // {
  76. //    display();
  77. //    keyscan();
  78. //   }
  79. //  }
 楼主| zhamatu 发表于 2020-10-25 17:25 | 显示全部楼层
  1. //程序二:解决按键控制数码管带来闪灭显示问题的程序
  2. #include<reg51.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit add=P3^0;
  6. sbit dec=P3^4;
  7. uchar lingweiflag;
  8. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
  9. uint num;
  10. uint qian,bai,shi,ge;//定义拆字变量
  11.   /**ms级延时子程序**/
  12.   void delay(uint x)
  13. {
  14.    uint i,j;                       
  15.    for(i=0;i<x;i++)     
  16.     for(j=0;j<110;j++);
  17.   }
  18.   void display()
  19. {
  20.    qian=num/1000;//取得千位数字
  21.    bai=num%1000/100;//取得百位数字
  22.    shi=num%100/10;//取得十位数字
  23.    ge=num%10;//取得个位数字

  24.    P2=0xfe;//数码管千位显示位
  25.    P1=table[qian];//数码管千位数值显示
  26.    delay(2);//延时

  27.    P2=0xfd;//数码管百位显示位
  28.    P1=table[bai];//数码管百位数值显示
  29.    delay(2);//延时

  30.    P2=0xfb;//数码管十位显示位
  31.    P1=table[shi];//数码管十位数值显示
  32.    delay(2);//延时

  33.    P2=0xf7;//数码管个位显示位
  34.    P1=table[ge];//数码管个位数值显示
  35.    delay(2);//延时
  36. }
  37.   void keyscan()
  38. {
  39.    if(add==0)
  40. {         
  41.     delay(5);
  42.     if(add==0)
  43.   {
  44.      num++;
  45.      while(!add);
  46.      lingweiflag=0;
  47.     }
  48.    }
  49.    if(dec==0&&lingweiflag==0)
  50. {         
  51.     delay(5);
  52.     if(dec==0)
  53.   {
  54.      num--;
  55.      while(!dec);
  56.     }
  57.    }
  58.    if(num>9999)
  59. {
  60.     num=0;
  61.    }
  62.    if(num==0)
  63. {
  64.     num=0;
  65.     lingweiflag=1;
  66.    }
  67. }
  68.   void Time0_init()
  69. {
  70.    TMOD=0x01;
  71.    TH0=(65536-10000)/256;//为什么取定时器中断时间为10000微妙,即10毫秒,亦0.01秒,则频率为1/0.01S=100Hz?由于人眼能看到数码管闪烁是源于人眼能识别高频率(人眼看不到闪烁的频率为50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想让人眼看不到数码管闪烁,数管显示函数的显示频率至少是50Hz,即1/50Hz=0.02秒,也不是越高越好,还要结合按键扫描函数的按键延时来取出最恰当的显示频率。
  72.    TL0=(65536-10000)%256;
  73.    EA=1;
  74.    ET0=1;
  75.    TR0=1;
  76.   }
  77.   void time0() interrupt 1
  78. {
  79.    TH0=(65536-10000)/256;
  80.    TL0=(65536-10000)%256;
  81.    display();
  82.   }
  83.   void main()
  84. {
  85.    Time0_init();
  86.    while(1)
  87. {
  88.     keyscan();
  89.    }
  90.   }
 楼主| zhamatu 发表于 2020-10-25 17:26 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

63

主题

504

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部