当前位置:   article > 正文

51单片机练习:独立键盘篇_用独立键盘实现功能:单片机上电后,数码管显示00,按键接p3.2,按下一次数值加1,

用独立键盘实现功能:单片机上电后,数码管显示00,按键接p3.2,按下一次数值加1,

题目:

用数码管的前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止自动加1,保持显示原数。(来自郭天祥老师的51单片机练习)

代码:

初始化函数:

  1. void Init()
  2. {
  3. LE = 0;//锁住led灯,防止实验过程中灯亮
  4. WLE = 1;//打开位选
  5. P0 = 0xfc;
  6. WLE = 0;//关闭位选
  7. P0 = 0xff;//消影
  8. DLE = 1;//打开段选
  9. P0 = Table[0];
  10. DLE = 0;//关闭段选
  11. delay_1ms(10);
  12. TMOD = 0x01;//定时器工作类型
  13. TH0 = (65536 - 45872) / 256;//50ms
  14. TL0 = (65536 - 45872) % 256;
  15. EA = 1;//总中断
  16. ET0 = 1;//T0中断
  17. TR0 = 0;//开启T0
  18. num = 0;
  19. tt = 0;
  20. }

1ms延时函数:

  1. //延时1ms函数
  2. void delay_1ms(uint z)
  3. {
  4. uint x,y;
  5. for(x = z;x > 0;x--)
  6. {
  7. for(y =110;y > 0;y--){}
  8. }
  9. }

四个独立按键函数:

  1. //按键2函数
  2. void Switch2()
  3. {
  4. while(SW2 == 0)
  5. {
  6. delay_1ms(10);//消抖
  7. if(SW2 == 0)
  8. {
  9. num++;//加1
  10. }
  11. while(SW2 == 0);//等待按键释放
  12. }
  13. }
  14. //按键3函数
  15. void Switch3()
  16. {
  17. while(SW3 == 0)
  18. {
  19. delay_1ms(10);//消抖
  20. if(SW3 == 0)
  21. {
  22. if(num == 0)
  23. {
  24. num = 59;
  25. }
  26. else
  27. {
  28. num--;//减1
  29. }
  30. }
  31. while(SW3 == 0);//等待按键释放
  32. }
  33. }
  34. //按键4函数
  35. void Switch4()
  36. {
  37. while(SW4 == 0)
  38. {
  39. delay_1ms(10);//消抖
  40. if(SW4 == 0)
  41. {
  42. num = 0;//归零
  43. }
  44. while(SW4 == 0);//等待按键释放
  45. }
  46. }
  47. //按键5函数
  48. void Switch5()
  49. {
  50. while(SW5 == 0)
  51. {
  52. delay_1ms(10);//消抖
  53. if(SW5 == 0)
  54. {
  55. if(TR0 == 0)
  56. {
  57. TR0 = 1;
  58. }
  59. else
  60. {
  61. TH0 = (65536 - 45872) / 256;//50ms
  62. TL0 = (65536 - 45872) % 256;
  63. TR0 = 0;
  64. }
  65. }
  66. while(SW5 == 0);//等待按键释放
  67. }
  68. }

数码管显示函数:

  1. //数码管显示函数
  2. void display()
  3. {
  4. uint ge,shi;
  5. //定时1s
  6. if(tt == 20)
  7. {
  8. tt = 0;
  9. num++;
  10. }
  11. //计算每秒个位与十位的变化
  12. if(num == 60)
  13. {
  14. num = 0;
  15. }
  16. shi = num / 10;//十位
  17. ge = num % 10;//个位
  18. //显示十位
  19. WLE = 1;
  20. P0 = 0xfe;
  21. WLE = 0;
  22. P0 = 0xff;//消影
  23. DLE = 1;
  24. P0 = Table[shi];
  25. DLE = 0;
  26. delay_1ms(5);//延时短,达到动态扫描的效果
  27. //显示个位
  28. WLE = 1;
  29. P0 = 0xfd;
  30. WLE = 0;
  31. P0 = 0xff;//消影
  32. DLE = 1;
  33. P0 = Table[ge];
  34. DLE = 0;
  35. delay_1ms(5);//延时短,达到动态扫描的效果
  36. }

定时器T0中断函数:

  1. void Timer0() interrupt 1
  2. {
  3. TH0 = (65536 - 45872) / 256;//50ms
  4. TL0 = (65536 - 45872) % 256;
  5. tt++;
  6. }

整个项目代码:

  1. #include <reg52.h>
  2. //【例4.1.1】用数码管的前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;
  3. //每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止自动加1,保持显示原数。
  4. //晶振为 11.0529MHz
  5. #define uint unsigned int
  6. #define uchar unsigned char
  7. sbit SW2 = P3^4;//S2键
  8. sbit SW3 = P3^5;//S3键
  9. sbit SW4 = P3^6;//S4键
  10. sbit SW5 = P3^7;//S5键
  11. sbit WLE = P2^7;//位选
  12. sbit DLE = P2^6;//段选
  13. sbit LE = P2^5;//led灯的锁存器
  14. //数码管的编码表
  15. uchar code Table[]={
  16. 0x3f,0x06,0x5b,0x4f,
  17. 0x66,0x6d,0x7d,0x07,
  18. 0x7f,0x6f,0x77,0x7c,
  19. 0x39,0x5e,0x79,0x71};
  20. uint num,tt;
  21. void Init();
  22. void delay_1ms(uint z);
  23. void Switch2();//也可以将四个按键都写在一个函数里面
  24. void Switch3();
  25. void Switch4();
  26. void Switch5();
  27. void display();
  28. void main()
  29. {
  30. Init();
  31. while(1)
  32. {
  33. Switch2();
  34. Switch3();
  35. Switch4();
  36. Switch5();
  37. display();
  38. }
  39. }
  40. void Init()
  41. {
  42. LE = 0;//锁住led灯,防止实验过程中灯亮
  43. WLE = 1;//打开位选
  44. P0 = 0xfc;
  45. WLE = 0;//关闭位选
  46. P0 = 0xff;//消影
  47. DLE = 1;//打开段选
  48. P0 = Table[0];
  49. DLE = 0;//关闭段选
  50. delay_1ms(10);
  51. TMOD = 0x01;//定时器工作类型
  52. TH0 = (65536 - 45872) / 256;//50ms
  53. TL0 = (65536 - 45872) % 256;
  54. EA = 1;//总中断
  55. ET0 = 1;//T0中断
  56. TR0 = 0;//开启T0
  57. num = 0;
  58. tt = 0;
  59. }
  60. //延时1ms函数
  61. void delay_1ms(uint z)
  62. {
  63. uint x,y;
  64. for(x = z;x > 0;x--)
  65. {
  66. for(y =110;y > 0;y--){}
  67. }
  68. }
  69. //按键2函数
  70. void Switch2()
  71. {
  72. while(SW2 == 0)
  73. {
  74. delay_1ms(10);//消抖
  75. if(SW2 == 0)
  76. {
  77. num++;//加1
  78. }
  79. while(SW2 == 0);//等待按键释放
  80. }
  81. }
  82. //按键3函数
  83. void Switch3()
  84. {
  85. while(SW3 == 0)
  86. {
  87. delay_1ms(10);//消抖
  88. if(SW3 == 0)
  89. {
  90. if(num == 0)
  91. {
  92. num = 59;
  93. }
  94. else
  95. {
  96. num--;//减1
  97. }
  98. }
  99. while(SW3 == 0);//等待按键释放
  100. }
  101. }
  102. //按键4函数
  103. void Switch4()
  104. {
  105. while(SW4 == 0)
  106. {
  107. delay_1ms(10);//消抖
  108. if(SW4 == 0)
  109. {
  110. num = 0;//归零
  111. }
  112. while(SW4 == 0);//等待按键释放
  113. }
  114. }
  115. //按键5函数
  116. void Switch5()
  117. {
  118. while(SW5 == 0)
  119. {
  120. delay_1ms(10);//消抖
  121. if(SW5 == 0)
  122. {
  123. if(TR0 == 0)
  124. {
  125. TR0 = 1;
  126. }
  127. else
  128. {
  129. TH0 = (65536 - 45872) / 256;//50ms
  130. TL0 = (65536 - 45872) % 256;
  131. TR0 = 0;
  132. }
  133. }
  134. while(SW5 == 0);//等待按键释放
  135. }
  136. }
  137. //数码管显示函数
  138. void display()
  139. {
  140. uint ge,shi;
  141. //定时1s
  142. if(tt == 20)
  143. {
  144. tt = 0;
  145. num++;
  146. }
  147. //计算每秒个位与十位的变化
  148. if(num == 60)
  149. {
  150. num = 0;
  151. }
  152. shi = num / 10;//十位
  153. ge = num % 10;//个位
  154. //显示十位
  155. WLE = 1;
  156. P0 = 0xfe;
  157. WLE = 0;
  158. P0 = 0xff;//消影
  159. DLE = 1;
  160. P0 = Table[shi];
  161. DLE = 0;
  162. delay_1ms(5);//延时短,达到动态扫描的效果
  163. //显示个位
  164. WLE = 1;
  165. P0 = 0xfd;
  166. WLE = 0;
  167. P0 = 0xff;//消影
  168. DLE = 1;
  169. P0 = Table[ge];
  170. DLE = 0;
  171. delay_1ms(5);//延时短,达到动态扫描的效果
  172. }
  173. void Timer0() interrupt 1
  174. {
  175. TH0 = (65536 - 45872) / 256;//50ms
  176. TL0 = (65536 - 45872) % 256;
  177. tt++;
  178. }

心得/经验记录:

1.按键的代码编写过程中,要注意“消抖”(消除人在按动按键的过程中的抖动),这个过程大概延时10ms即可;

2.按键在按下去和释放的瞬间都会有抖动,但是实际过程中,只需要在按下去的时候消抖即可,释放时可以不用消抖;

3.在处理按键按下去的那段代码时,要注意加一个“等待释放”的过程,如果一直按着按键,程序就要等待在那,而不是一直加数;

4.数码管在遇到60的时候要显示0,在0与59之间的加减转换要衔接好;

5.定时器T0的TR0开启或关闭,可以将if else语句简化成TR0 = ~TR0代替;

6.因为P1^7口是第8个发光二极管的口,也是时钟SCLK的口,如果不将发光二极管的使能端LE = 0(锁住),那么在按下按键5的时候,会导致发光二极管亮;

7.可将Switch2()、Switch3()、Switch4()、Switch5()这四个按键写在一个函数里简化,依次判断即可。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/408852
推荐阅读
相关标签
  

闽ICP备14008679号