stm32用按键SW2控制灯LED3,LED4,按一次LED 交替闪烁(两秒闪一次),再按一次灭掉
时间: 2024-11-30 19:22:52 浏览: 14
在STM32微控制器上,我们可以使用GPIO功能来控制LED灯,而SW2作为按键用于触发这个操作。首先,我们需要设置SW2为输入模式,并添加中断处理程序来检测按键按下。然后,通过定时器来实现两秒的闪烁间隔。
以下是基本步骤:
1. **初始化硬件资源**:
- 配置SW2为输入模式,并开启中断。
- 初始化两个GPIO口,如GPIOB,将PB0(LED3)和PB1(LED4)配置为推挽输出。
```c
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 初始化SW2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // SW2位置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 输入浮动模式
GPIO_Init(GPIOB, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; // EXTI2通道对应SW2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 开启中断
NVIC_Init(&NVIC_InitStructure);
// 初始化LEDs GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // LED3 和 LED4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUTPUT_PP; // 推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
```
2. **设置定时器**:
使用系统定时器(例如TIM2)每隔两秒发送一个信号,改变LED状态。你可以选择使用软件定时器或者硬件定时器,这里假设使用的是软件定时器。
```c
TIM_TimeBaseInitTypeDef.TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitStructure.TIM_Period = 1000; // 1000us周期等于1ms
TIM_TimeBaseInitStructure.TIM_Prescaler = (SystemCoreClock / 8) - 1; // 根据实际晶振频率计算预分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
HAL_TIM_Base_Init(&htim2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInit(&htim2, &TIM_OCInitStructure);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // LED3
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); // LED4
// 定义软定时器函数
void TimerCallback(TIM_HandleTypeDef *htim)
{
static uint32_t toggle_state = 1;
HAL_GPIO_TogglePin(GPIOB, GPIO_Pin_0 | GPIO_Pin_1); // LED切换
toggle_state ^= 1;
}
```
3. **中断服务程序**:
当SW2被按下时,中断服务程序会被调用,更新定时器并清除中断标志。
```c
void EXTI2_IRQHandler(void)
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_2))
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); // 处理中断
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, toggle_state ? 0 : 1000); // 更新定时器比较值
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, toggle_state ? 1000 : 0);
__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_2); // 清除中断标志
}
}
```
4. **主循环和启动定时器**:
在`while(1)`循环中,保持定时器运行,直到按键释放。
```c
while (1)
{
HAL_Delay(100); // 稍微延时让中断生效
if (!__HAL_GPIO_ReadPin(GPIOB, GPIO_Pin_2)) // 检查SW2是否按下
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
}
}
```
完成以上步骤后,当按下SW2,LED3和LED4就会交替闪烁;再次按下则停止闪烁。注意,在实际项目中,你需要连接好硬件电路,并根据具体STM32型号调整定时器配置。
阅读全文