#include "reg51.h"sbit key_s2 = P3^4; // 按键1sbit key_s3 = P3^5; // 按键2unsigned char pwm_led_val = 0; // LED占空比值 0-20unsigned char pwm_t; // 周期// 毫秒级延时void delay(unsigned int z){ unsigned int x,y; for(x = z; x > 0; x--) for(y = 114; y >0; y--);}// 定时器0中断void timer0() interrupt 1{ pwm_t++; if(pwm_t == 20) { pwm_t = 0; P1 = 0xff; // 控制led灯灭 } if(pwm_led_val == pwm_t) P1 = 0; // 控制led灯亮}void main(){ /* 频率是根据周期决定的,而周期则是定时器溢出时间和占空比决定的 周期 = 定时器溢出时间 * 占空比 频率公式:f = 1/T 机器周期为 1.085us */ TMOD |= 0x02; TH0 = 240; TL0 = 240; // 11.0592晶振最大占空比值为20,输出2880HZ TR0 = 1; // 启动定时器0 ET0 = 1; // 允许定时器0中断 EA = 1; // 总中断允许 while(1) { if(key_s2 == 0) // 按下key_s2 LED变暗 { delay(5); if(key_s2 == 0) { if(pwm_led_val < 20) { pwm_led_val++; } while(!key_s2); } } if(key_s3 == 0) // 按下key_s3 LED变亮 { delay(5); if(key_s3 == 0) { if(pwm_led_val > 0) { pwm_led_val--; } while(!key_s3); } } }}
其他方法(更好的)

使用标记状态
uint16_t count = 0; // 计数uint8_t flag = 0; // 记住这次的状态uint8_t flag2 = 1; // 记住上次的状态void key_scan(void){ uint8_t temp = GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN); // 按键按下时为1,弹开时0 count++; switch(flag) { case 0: if(count>10 && temp == 1) { LED0(ON); count = 0; flag2 = 1; }else if(temp == 0 && flag2 == 1) { flag = 1; } break; case 1: if(count>10 && temp == 1) { LED0(OFF); count = 0; flag2 = 0; }else if(temp == 0 && flag2 == 0) { flag = 0; } break; }}
bsp_key.cbsp_key.h