#include "reg51.h"
sbit key_s2 = P3^4; // 按键1
sbit key_s3 = P3^5; // 按键2
unsigned char pwm_led_val = 0; // LED占空比值 0-20
unsigned 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