標(biāo)題: 解決單片機(jī)按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二) [打印本頁(yè)]

作者: 51黑電子會(huì)員    時(shí)間: 2020-5-21 21:31
標(biāo)題: 解決單片機(jī)按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二)
本帖最后由 51黑電子會(huì)員 于 2020-5-23 13:50 編輯
  1. /*****
  2. 承接上一個(gè)解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)來(lái)
  3. 做解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二)。為何呢?
  4. 由于上一個(gè)解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)
  5. 程序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí),導(dǎo)致CPU消耗
  6. 過(guò)大,拖慢CPU處理指令的速度。如何來(lái)解決呢?請(qǐng)看下面講解。
  7. 為什么按下按鍵到按鍵抬起后,會(huì)干擾到數(shù)碼管的顯示?原因:如果按鍵掃描
  8. 函數(shù)和數(shù)碼管顯示函數(shù)都放在主函數(shù)的固定循環(huán)內(nèi),當(dāng)按鍵按下后,按鍵掃描
  9. 函數(shù)進(jìn)行按鍵掃描,在掃描到按鍵延時(shí)后,CPU被限制在按鍵延時(shí)處進(jìn)行計(jì)時(shí),
  10. 卻無(wú)法運(yùn)行其他程序,從而導(dǎo)致數(shù)碼管顯示函數(shù)無(wú)法運(yùn)行,就會(huì)出現(xiàn)數(shù)碼管閃
  11. 滅顯示問(wèn)題。人能看到數(shù)碼管閃爍是因?yàn)槿搜勰茏R(shí)別高頻率(人眼看不到閃爍
  12. 的頻率為50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想讓人眼看不到數(shù)碼管閃
  13. 爍,數(shù)碼管顯示函數(shù)的顯示頻率至少是50Hz,即1/50Hz=0.02秒,也不是越高
  14. 好,還要結(jié)合按鍵掃描函數(shù)的按鍵延時(shí)來(lái)取出最恰當(dāng)?shù)娘@示頻率。
  15. 除了以上問(wèn)題,解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)
  16. 還存在程序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí),導(dǎo)致CPU
  17. 消耗過(guò)大,拖慢CPU處理指令的速度。
  18. 本程序分兩個(gè)程序。一個(gè)是程序一,按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序。
  19. 另一個(gè)是程序二,解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版
  20. 二)。通過(guò)去掉按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)程
  21. 序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí)。定時(shí)器解決按鍵
  22. 消抖原理:編寫(xiě)一個(gè)類(lèi)似普通延時(shí)函數(shù)的定時(shí)器延時(shí)函數(shù),用來(lái)替換掉普通延
  23. 時(shí)即可。提醒:先試程序一,再試程序二,之后兩者對(duì)比,找出不同點(diǎn),取最
  24. 適合的。
  25. *****/
  26. //程序一:按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序
  27. //#include<reg51.h>
  28. //#define uchar unsigned char
  29. //#define uint unsigned int
  30. //sbit add=P3^0;
  31. //sbit dec=P3^4;
  32. //uchar lingweiflag;
  33. //uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共陰數(shù)碼管段碼數(shù)字0~9字碼表,高電平點(diǎn)亮數(shù)碼管段碼數(shù)字0~9。
  34. //uint num;
  35. //uint qian,bai,shi,ge;//定義拆字變量
  36. //  /**ms級(jí)延時(shí)子程序**/
  37. //  void delay(uint x)
  38. //{
  39. //   uint i,j;                       
  40. //   for(i=0;i<x;i++)     
  41. //    for(j=0;j<110;j++);
  42. //  }
  43. //  void display()
  44. //{
  45. //   qian=num/1000;//取得千位數(shù)字
  46. //   bai=num%1000/100;//取得百位數(shù)字
  47. //   shi=num%100/10;//取得十位數(shù)字
  48. //   ge=num%10;//取得個(gè)位數(shù)字
  49. //
  50. //   P2=0xfe;//數(shù)碼管千位顯示位
  51. //   P1=table[qian];//數(shù)碼管千位數(shù)值顯示
  52. //   delay(2);//延時(shí)
  53. //
  54. //   P2=0xfd;//數(shù)碼管百位顯示位
  55. //   P1=table[bai];//數(shù)碼管百位數(shù)值顯示
  56. //   delay(2);//延時(shí)
  57. //
  58. //   P2=0xfb;//數(shù)碼管十位顯示位
  59. //   P1=table[shi];//數(shù)碼管十位數(shù)值顯示
  60. //   delay(2);//延時(shí)
  61. //
  62. //   P2=0xf7;//數(shù)碼管個(gè)位顯示位
  63. //   P1=table[ge];//數(shù)碼管個(gè)位數(shù)值顯示
  64. //   delay(2);//延時(shí)
  65. // }
  66. //  void keyscan()
  67. //{
  68. //   if(add==0)
  69. // {         
  70. //    delay(5);
  71. //    if(add==0)
  72. //  {
  73. //     num++;
  74. //     while(!add);
  75. //     lingweiflag=0;
  76. //    }
  77. //   }
  78. //   if(dec==0&&lingweiflag==0)
  79. // {         
  80. //    delay(5);
  81. //    if(dec==0)
  82. //  {
  83. //     num--;
  84. //     while(!dec);
  85. //    }
  86. //   }
  87. //   if(num>9999)
  88. // {
  89. //      num=0;
  90. //   }
  91. //   if(num==0)
  92. // {
  93. //       num=0;
  94. //       lingweiflag=1;
  95. //   }
  96. // }
  97. //  void main()
  98. //{
  99. //   while(1)
  100. // {
  101. //    display();
  102. //    keyscan();
  103. //   }
  104. //  }



  105. //程序二:解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序
  106. #include<reg51.h>
  107. #define uchar unsigned char
  108. #define uint unsigned int
  109. sbit add=P3^0;
  110. sbit dec=P3^4;
  111. sbit led=P3^5;
  112. sbit led2=P3^6;
  113. uchar count;//定時(shí)器中斷次數(shù)變量
  114. uchar time;//按鍵定時(shí)器延時(shí)變量
  115. uchar lingweiflag;//顯示0標(biāo)志位變量
  116. uchar code weima[]={0xfe,0xfd,0xfb,0xf7};//數(shù)碼管位碼表
  117. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共陰數(shù)碼管段碼數(shù)字0~9字碼表,高電平點(diǎn)亮數(shù)碼管段碼數(shù)字0~9。
  118. uint num;//數(shù)值變量
  119. uint qian,bai,shi,ge;//定義拆字變量
  120. //  /**ms級(jí)延時(shí)子程序**/
  121. //  void delay(uint x)
  122. //{
  123. //   uint i,j;                       
  124. //   for(i=0;i<x;i++)     
  125. //    for(j=0;j<110;j++);
  126. //  }
  127. /**定時(shí)器ms級(jí)延時(shí)子程序**/
  128.   void time0_delay(uchar time)//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
  129. {
  130.    count = 0;//需要定時(shí)器延時(shí)count,先清零,再循環(huán)檢測(cè)是否計(jì)到count,是則退出。
  131.    while(1)
  132. {
  133.     if(count>=time)
  134.   {         
  135.      break;
  136.    }
  137.   }  
  138. }
  139. //  void display()
  140. //{
  141. //   qian=num/1000;//取得千位數(shù)字
  142. //   bai=num%1000/100;//取得百位數(shù)字
  143. //   shi=num%100/10;//取得十位數(shù)字
  144. //   ge=num%10;//取得個(gè)位數(shù)字
  145. //
  146. //   P2=0xfe;//數(shù)碼管千位顯示位
  147. //   P1=table[qian];//數(shù)碼管千位數(shù)值顯示
  148. //   delay(2);//延時(shí)
  149. //
  150. //   P2=0xfd;//數(shù)碼管百位顯示位
  151. //   P1=table[bai];//數(shù)碼管百位數(shù)值顯示
  152. //   delay(2);//延時(shí)
  153. //
  154. //   P2=0xfb;//數(shù)碼管十位顯示位
  155. //   P1=table[shi];//數(shù)碼管十位數(shù)值顯示
  156. //   delay(2);//延時(shí)
  157. //
  158. //   P2=0xf7;//數(shù)碼管個(gè)位顯示位
  159. //   P1=table[ge];//數(shù)碼管個(gè)位數(shù)值顯示
  160. //   delay(2);//延時(shí)
  161. // }
  162.   void display()//顯示程序
  163. {
  164.    static uchar i;
  165.    P1=0x00;
  166.    P2=weima[i];
  167.    switch(i)
  168. {
  169.     case 0:
  170.            P1=table[num/1000];
  171.            break;
  172.     case 1:
  173.            P1=table[num%1000/100];
  174.            break;
  175.     case 2:
  176.            P1=table[num%100/10];
  177.            break;
  178.     case 3:
  179.            P1=table[num%10];
  180.            break;
  181.   }
  182.    i++;
  183.    i%=4;
  184. }
  185.   void keyscan()
  186. {
  187. //   if(add==0)
  188. // {         
  189. //    delay(5);
  190. //    if(add==0)
  191. //  {
  192. //     num++;
  193. //     while(!add);
  194. //     lingweiflag=0;
  195. //    }
  196. //   }
  197.    if(add==0)
  198. {         
  199.     time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
  200.     if(add==0)
  201.   {         
  202.      time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
  203.      while(!add);
  204.      num++;
  205.      lingweiflag=0;
  206.     }
  207.    }
  208. //   if(dec==0&&lingweiflag==0)
  209. // {         
  210. //    delay(5);
  211. //    if(dec==0)
  212. //  {
  213. //     num--;
  214. //     while(!dec);
  215. //    }
  216. //   }
  217.    if(dec==0&&lingweiflag==0)
  218. {         
  219.     time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
  220.     if(dec==0)
  221.   {         
  222.      time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
  223.      while(!dec);
  224.      num--;   
  225.     }
  226.    }
  227.    if(num>9999)
  228. {
  229.     num=0;
  230.    }
  231.    if(num==0)
  232. {
  233.     num=0;
  234.     lingweiflag=1;
  235.    }
  236. }
  237.   void Time0_init()
  238. {
  239.    TMOD=0x01;
  240.    TH0=(65536-2000)/256;//為什么取定時(shí)器中斷時(shí)間為2000微妙,即2毫秒,亦0.002秒,則頻率為1/0.002S=500Hz?由于人眼能看到數(shù)碼管閃爍是源于人眼能識(shí)別高頻率(人眼看不到閃爍的頻率為50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想讓人眼看不到數(shù)碼管閃爍,數(shù)管顯示函數(shù)的顯示頻率至少是50Hz,即1/50Hz=0.02秒,也不是越高越好,還要結(jié)合按鍵掃描函數(shù)的按鍵延時(shí)來(lái)取出最恰當(dāng)?shù)娘@示頻率。
  241.    TL0=(65536-2000)%256;
  242.    EA=1;
  243.    ET0=1;
  244.    TR0=1;
  245.   }
  246.   void time0() interrupt 1
  247. {
  248.    TH0=(65536-2000)/256;
  249.    TL0=(65536-2000)%256;
  250.    count++;
  251.    display();
  252.   }
  253.   void main()
  254. {
  255.    Time0_init();
  256.    while(1)
  257. {
  258.     keyscan();
  259.    }
  260.   }
復(fù)制代碼







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1