51频率占空比可控pwm小灯

如何用51写一个pwm占空比和频率都可调的灯(要求按下s1键小灯占空比加%10,按下s2键小灯占空比减小%10,按下s3键小灯频率加50hz,按下s4键小灯频率减50hz)


#include <reg51.h>

sbit S1 = P1^0;   // S1键
sbit S2 = P1^1;   // S2键
sbit S3 = P1^2;   // S3键
sbit S4 = P1^3;   // S4键

sbit LED = P2^0;  // 控制小灯的引脚

unsigned int pwm_duty_cycle = 500;    // 初始占空比为50%(0-1000)
unsigned int pwm_frequency = 1000;    // 初始频率为1000Hz

// 延时函数
void delay(unsigned int count)
{
    unsigned int i, j;
    for (i = 0; i < count; i++)
        for (j = 0; j < 1000; j++);
}

// 初始化定时器0
void init_timer0()
{
    TMOD |= 0x01;   // 设置定时器0为工作在模式1(16位定时器)    
    TH0 = (65536 - 50000) / 256;  // 定时50ms
    TL0 = (65536 - 50000) % 256;
    TR0 = 1;        // 启动定时器0
    ET0 = 1;        // 允许定时器0中断
    EA = 1;         // 允许总中断
}

// 更新占空比和频率
void update_pwm()
{
    CCAP0L = pwm_duty_cycle % 256;
    CCAP0H = pwm_duty_cycle / 256;
    TH0 = (65536 - (50000 / pwm_frequency)) / 256;
    TL0 = (65536 - (50000 / pwm_frequency)) % 256;
}

// 定时器0中断处理函数
void timer0_isr() interrupt 1
{
    TF0 = 0;   // 清除定时器0溢出标志位
    LED = ~LED;  // 反转小灯状态
}

// 主函数
void main()
{
    init_timer0();  // 初始化定时器0
    update_pwm();   // 更新占空比和频率

    while (1)
    {
        if (S1 == 0)  // 检测S1键是否按下
        {
            delay(20);  // 延时去抖动
            if (S1 == 0)
            {
                while (S1 == 0);  // 等待按键释放
                pwm_duty_cycle += 100;  // 增加占空比10%
                if (pwm_duty_cycle > 1000)
                    pwm_duty_cycle = 1000;
                update_pwm();  // 更新占空比和频率
            }
        }

        if (S2 == 0)  // 检测S2键是否按下
        {
            delay(20);  // 延时去抖动
            if (S2 == 0)
            {
                while (S2 == 0);  // 等待按键释放
                pwm_duty_cycle -= 100;  // 减小占空比10%
                if (pwm_duty_cycle > 1000)
                    pwm_duty_cycle = 0;
                update_pwm();  // 更新占空比和频率
            }
        }

        if (S3 == 0)  // 检测S3键是否按下
        {
            delay(20);  // 延时去抖动
            if (S3 == 0)
            {
                while (S3 == 0);  // 等待按键释放
                pwm_frequency += 50;  // 增加频率50Hz
                update_pwm();  // 更新占空比和频率
            }
        }

        if (S4 == 0)  // 检测S4键是否按下
        {
            delay(20);  // 延时去抖动
            if (S4 == 0)
            {
                while (S4 == 0);  // 等待按键释放
                if (pwm_frequency > 50)
                    pwm_frequency -= 50;  // 减小频率50Hz
                update_pwm();  // 更新占空比和频率
            }
        }
    }
}