嘟嘟荞code 2023-06-10 13:42 采纳率: 0%
浏览 17

51频率占空比可控pwm小灯

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

  • 写回答

1条回答 默认 最新

  • qllaoda 2023-06-10 13:55
    关注
    
    #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();  // 更新占空比和频率
                }
            }
        }
    }
    
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月10日

悬赏问题

  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥15 crossover21 ARM64版本安装软件问题
  • ¥15 mymetaobjecthandler没有进入
  • ¥15 mmo能不能做客户端怪物
  • ¥15 osm下载到arcgis出错
  • ¥15 Dell g15 每次打开eiq portal后3分钟内自动退出
  • ¥200 使用python编写程序,采用socket方式获取网页实时刷新的数据,能定时print()出来就行。
  • ¥15 matlab如何根据图片中的公式绘制e和v的曲线图
  • ¥15 我想用Python(Django)+Vue搭建一个用户登录界面,但是在运行npm run serve时报错了如何解决?