格院EP Lab1(嵌入式处理器)-利用PWM控制LED的亮度变化(基于Mbed OS)

本文作者是为了提升自己的知识输出能力以及为同窗,学弟学妹提供思路,所以写了这个系列的栏目。

由于后续会涉及到代码的展示,希望大家谨慎参考,不要直接copy,我的文章最大的作用是分享思路。

话不多说,我们开始吧。

第一步:解读要求

硬件定义

  1. PWM输出

    • 定义一个PWM输出用于控制LED1的亮度。

  2. 数字输入

    • 定义两个数字输入用于检测两个按钮的状态(button和button2)。

主程序逻辑

  1. 循环监测按钮状态

    • 实现一个循环,持续监测两个按钮的状态。

  2. 按钮按下处理

    • 当第一个按钮被按下时,设置一个标志位,表示需要增加LED亮度。

    • 当第二个按钮被按下时,设置一个标志位,表示需要减少LED亮度。

  3. 亮度调整

    • 根据按钮按下的状态,逐步调整LED的亮度:

      • 如果第一个按钮被按下,逐步增加亮度。

      • 如果第二个按钮被按下,逐步减少亮度。

      • 如果没有按钮被按下,切换LED的开关状态(开/关)。

渐变亮度实现

  1. 逐步调整亮度

    • 使用一个循环来逐步增加或减少LED的亮度。

    • 在每次循环中,使用thread_sleep_for()引入延迟,以实现平滑的亮度过渡。

所以我们知道,本实验考察的主要知识点是:1.轮询机制(检测按钮是否被按下) 2.PWM 3. 循环语句(用于提升或者降低小灯的亮度)

 

 第二步:代码实现

我的代码中已经附了注释,但是对于重点知识和某些操作我会专门进行解释

第一块

#include "mbed.h"

#define delaytime 50ms



// 定义1:在A5引脚上为LED设置PWM输出

// 定义2:在D3引脚上为按钮1(增加)设置数字输入,带上拉电阻

// 定义3:在D4引脚上为按钮2(减少)设置数字输入,带上拉电阻

PwmOut LED(A5);

DigitalIn Button1_Increase(D3, PullUp);

DigitalIn Button2_Dncrease(D4, PullUp);



// 初始化占空比为0.5(50%)

float duty_cycle = 0.5f;

 

这里我将按钮进行了上拉操作,上拉以后,按钮的初始状态为高电平。当接地时候则为低电平。

第二块 

// 限制占空比在0.0到1.0之间的函数

void limitDutyCycle() {

    if (duty_cycle > 1.0f) {

        duty_cycle = 1.0f;

    } else if (duty_cycle < 0.0f) {

        duty_cycle = 0.0f;

    }

}

本函数将占空比限制在0-1之间,因为占空比需要是0到1之间的某个小数。

第三块 

        if (Button1_Increase.read() == 0) {

            // 消抖延时

            ThisThread::sleep_for(20);

            // 确认按钮按下

            if (Button1_Increase.read() == 0) {

                // 逐渐增加占空比

                for (int i = 0; i < 20; i++) {

                    duty_cycle = duty_cycle + 0.005f;

                    // 限制占空比

                    limitDutyCycle();

                    // 更新LED亮度

                    LED.write(duty_cycle);

                    // 更新之间的延时

                    ThisThread::sleep_for(50);

                }

            }

        } 

 

        if (Button1_Increase.read() == 0) {

            // 消抖延时

            ThisThread::sleep_for(20);

            // 确认按钮按下

            if (Button1_Increase.read() == 0)

这三个操作是为了消除按键抖动,确保可以真实的感应到按钮被按下。

第五块

 else {

            // 以当前占空比打开LED

            LED.write(duty_cycle);

            // 延时

            ThisThread::sleep_for(300);

            // 关闭LED

            LED.write(0.0f);

            // 延时

            ThisThread::sleep_for(300);

        }

这一模块的用处是在没有按钮被按下的时候,让LEDs闪烁 

以下是Lab1的完整代码

#include "mbed.h"
#define delaytime 50ms

// 定义1:在A5引脚上为LED设置PWM输出
// 定义2:在D3引脚上为按钮1(增加)设置数字输入,带上拉电阻
// 定义3:在D4引脚上为按钮2(减少)设置数字输入,带上拉电阻
PwmOut LED(A5);
DigitalIn Button1_Increase(D3, PullUp);
DigitalIn Button2_Dncrease(D4, PullUp);

// 初始化占空比为0.5(50%)
float duty_cycle = 0.5f;

// 限制占空比在0.0到1.0之间的函数
void limitDutyCycle() {
    if (duty_cycle > 1.0f) {
        duty_cycle = 1.0f;
    } else if (duty_cycle < 0.0f) {
        duty_cycle = 0.0f;
    }
}

int main() {
    // 设置PWM周期为1毫秒
    LED.period_ms(1);

    while (true) {
        // 检查按钮1(增加)是否被按下
        if (Button1_Increase.read() == 0) {
            // 消抖延时
            ThisThread::sleep_for(20);
            // 确认按钮按下
            if (Button1_Increase.read() == 0) {
                // 逐渐增加占空比
                for (int i = 0; i < 20; i++) {
                    duty_cycle = duty_cycle + 0.005f;
                    // 限制占空比
                    limitDutyCycle();
                    // 更新LED亮度
                    LED.write(duty_cycle);
                    // 更新之间的延时
                    ThisThread::sleep_for(50);
                }
            }
        }

        // 检查按钮2(减少)是否被按下
        else if (Button2_Dncrease.read() == 0) {
            // 消抖延时
            ThisThread::sleep_for(20);
            // 确认按钮按下
            if (Button2_Dncrease.read() == 0) {
                // 逐渐减少占空比
                for (int i = 0; i < 20; i++) {
                    // 限制占空比
                    limitDutyCycle();
                    duty_cycle = duty_cycle - 0.005f;
                    // 更新之间的延时
                    ThisThread::sleep_for(50);
                }
            }
        }

        // 如果没有按钮被按下,使LED闪烁
        else {
            // 以当前占空比打开LED
            LED.write(duty_cycle);
            // 延时
            ThisThread::sleep_for(300);
            // 关闭LED
            LED.write(0.0f);
            // 延时
            ThisThread::sleep_for(300);
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值