本文作者是为了提升自己的知识输出能力以及为同窗,学弟学妹提供思路,所以写了这个系列的栏目。
由于后续会涉及到代码的展示,希望大家谨慎参考,不要直接copy,我的文章最大的作用是分享思路。
话不多说,我们开始吧。
第一步:解读要求
硬件定义
-
PWM输出:
-
定义一个PWM输出用于控制LED1的亮度。
-
-
数字输入:
-
定义两个数字输入用于检测两个按钮的状态(button和button2)。
-
主程序逻辑
-
循环监测按钮状态:
-
实现一个循环,持续监测两个按钮的状态。
-
-
按钮按下处理:
-
当第一个按钮被按下时,设置一个标志位,表示需要增加LED亮度。
-
当第二个按钮被按下时,设置一个标志位,表示需要减少LED亮度。
-
-
亮度调整:
-
根据按钮按下的状态,逐步调整LED的亮度:
-
如果第一个按钮被按下,逐步增加亮度。
-
如果第二个按钮被按下,逐步减少亮度。
-
如果没有按钮被按下,切换LED的开关状态(开/关)。
-
-
渐变亮度实现
-
逐步调整亮度:
-
使用一个循环来逐步增加或减少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);
}
}
}