1. #include "reg51.h"
  2. sbit key_s2 = P3^4; // 按键1
  3. sbit key_s3 = P3^5; // 按键2
  4. unsigned char pwm_led_val = 0; // LED占空比值 0-20
  5. unsigned char pwm_t; // 周期
  6. // 毫秒级延时
  7. void delay(unsigned int z)
  8. {
  9. unsigned int x,y;
  10. for(x = z; x > 0; x--)
  11. for(y = 114; y >0; y--);
  12. }
  13. // 定时器0中断
  14. void timer0() interrupt 1
  15. {
  16. pwm_t++;
  17. if(pwm_t == 20)
  18. {
  19. pwm_t = 0;
  20. P1 = 0xff; // 控制led灯灭
  21. }
  22. if(pwm_led_val == pwm_t)
  23. P1 = 0; // 控制led灯亮
  24. }
  25. void main()
  26. {
  27. /*
  28. 频率是根据周期决定的,而周期则是定时器溢出时间和占空比决定的
  29. 周期 = 定时器溢出时间 * 占空比
  30. 频率公式:f = 1/T
  31. 机器周期为 1.085us
  32. */
  33. TMOD |= 0x02;
  34. TH0 = 240;
  35. TL0 = 240; // 11.0592晶振最大占空比值为20,输出2880HZ
  36. TR0 = 1; // 启动定时器0
  37. ET0 = 1; // 允许定时器0中断
  38. EA = 1; // 总中断允许
  39. while(1)
  40. {
  41. if(key_s2 == 0) // 按下key_s2 LED变暗
  42. {
  43. delay(5);
  44. if(key_s2 == 0)
  45. {
  46. if(pwm_led_val < 20)
  47. {
  48. pwm_led_val++;
  49. }
  50. while(!key_s2);
  51. }
  52. }
  53. if(key_s3 == 0) // 按下key_s3 LED变亮
  54. {
  55. delay(5);
  56. if(key_s3 == 0)
  57. {
  58. if(pwm_led_val > 0)
  59. {
  60. pwm_led_val--;
  61. }
  62. while(!key_s3);
  63. }
  64. }
  65. }
  66. }

其他方法(更好的)

image.png

使用标记状态

  1. uint16_t count = 0; // 计数
  2. uint8_t flag = 0; // 记住这次的状态
  3. uint8_t flag2 = 1; // 记住上次的状态
  4. void key_scan(void)
  5. {
  6. uint8_t temp = GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN); // 按键按下时为1,弹开时0
  7. count++;
  8. switch(flag)
  9. {
  10. case 0:
  11. if(count>10 && temp == 1)
  12. {
  13. LED0(ON);
  14. count = 0;
  15. flag2 = 1;
  16. }else if(temp == 0 && flag2 == 1)
  17. {
  18. flag = 1;
  19. }
  20. break;
  21. case 1:
  22. if(count>10 && temp == 1)
  23. {
  24. LED0(OFF);
  25. count = 0;
  26. flag2 = 0;
  27. }else if(temp == 0 && flag2 == 0)
  28. {
  29. flag = 0;
  30. }
  31. break;
  32. }
  33. }

bsp_key.cbsp_key.h