STM32F103按键控制LED三级调光设计
时间: 2025-04-01 14:09:58 浏览: 45
### 使用STM32F103实现按键控制LED的三级调光功能
为了实现按键控制LED的三级调光功能,可以利用PWM信号调节LED亮度。以下是一个基于STM32F103C8T6开发板的设计方案和示例代码。
#### 硬件准备
- STM32F103C8T6 开发板
- LED(连接到指定GPIO口)
- 按键开关(连接到另一个GPIO口)
#### 软件环境
- STM32CubeMX 配置工具
- STM32CubeIDE 编程环境
---
#### 配置步骤说明
1. **初始化TIM模块用于生成PWM信号**
- 在STM32CubeMX中配置定时器(如 TIM2),设置其模式为PWM输出。
- 将PWM通道绑定至控制LED的GPIO引脚(例如 PA5)[^1]。
2. **配置按键输入**
- 选择一个GPIO作为外部中断源(例如 PC13),并将其配置为上拉/下拉输入模式。
- 启用EXTI中断以便检测按键按下事件。
3. **编写程序逻辑**
- 定义三个不同的占空比值分别对应低亮、中亮和高亮状态。
- 利用按键触发改变当前占空比,并更新PWM输出。
---
#### 示例代码
```c
#include "stm32f1xx_hal.h"
// 定义全局变量存储当前亮度等级
uint8_t brightness_level = 0; // 初始化为最低亮度
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_PWM_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init(); // GPIO初始化
MX_TIM2_PWM_Init(); // PWM初始化
while (1)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, brightness_levels[brightness_level]);
HAL_Delay(10); // 延迟防止抖动影响
}
}
// 中断服务函数处理按键按下的动作
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); // 处理PC13的中断请求
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13) // 如果是PC13被按下
{
brightness_level++; // 提升亮度级别
if (brightness_level > 2) // 循环回到最低级
brightness_level = 0;
// 更新PWM比较寄存器以调整占空比
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, brightness_levels[brightness_level]);
}
}
// 初始化TIM2用于PWM输出
static void MX_TIM2_PWM_Init(void)
{
TIM_OC_InitTypeDef sConfigOC;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 79; // 设置预分频器使频率接近1kHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999; // 自由运行周期设为1000
HAL_TIM_Base_Init(&htim2);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 默认初始脉冲宽度为零
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_Init(&htim2);
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}
// 初始化GPIO
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能PA端口时钟(用于PWM输出)
__HAL_RCC_GPIOC_CLK_ENABLE(); // 使能PC端口时钟(用于按键输入)
// 配置PA5为复用推挽输出(PWM)
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置PC13为输入模式(按键)
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0); // 设置优先级
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); // 使能中断
}
```
定义不同级别的亮度:
```c
const uint16_t brightness_levels[] = {200, 500, 800}; // 不同占空比对应的数值
```
---
#### 注意事项
- 占空比范围应介于 `0` 至 `(Period + 1)` 的范围内,在此例子中即 `[0, 1000]`。
- 可适当增加去抖动延迟时间以提高稳定性。
---
阅读全文
相关推荐


















