STM32利用中断方式通过两个按键分别控制流水灯的转向和开关
以下是一种实现方式:
首先需要初始化两个按键的GPIO口和中断:
void GPIO_Init(void)
{
// 初始化LED灯的GPIO口
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = LED_PIN_1 | LED_PIN_2 | LED_PIN_3 | LED_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
// 初始化按键1的GPIO口和中断
GPIO_InitStruct.Pin = KEY1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
// 初始化按键2的GPIO口和中断
GPIO_InitStruct.Pin = KEY2_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
// 使能按键1和按键2的中断
HAL_NVIC_SetPriority(KEY1_EXTI_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(KEY1_EXTI_IRQn);
HAL_NVIC_SetPriority(KEY2_EXTI_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(KEY2_EXTI_IRQn);
}
然后定义中断回调函数,根据按键的不同来执行不同的操作:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == KEY1_PIN)
{
// 按下按键1时,改变流水灯的方向
if (direction == 1)
{
direction = -1;
}
else
{
direction = 1;
}
}
else if (GPIO_Pin == KEY2_PIN)
{
// 按下按键2时,开关流水灯
if (led_on)
{
led_on = 0;
}
else
{
led_on = 1;
}
}
}
最后,在主循环中根据流水灯的方向和开关状态控制LED灯的亮灭:
while (1)
{
if (led_on)
{
// 如果LED灯开启,则根据方向控制LED灯的流动
if (direction == 1)
{
// 向右流动
for (uint8_t i = 0; i < 4; i++)
{
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN_1 << i, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN_1 << i, GPIO_PIN_RESET);
}
}
else
{
// 向左流动
for (uint8_t i = 3; i >= 0; i--)
{
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN_1 << i, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN_1 << i, GPIO_PIN_RESET);
}
}
}
else
{
// 如果LED灯关闭,则全部关闭
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN_1 | LED_PIN_2 | LED_PIN_3 | LED_PIN_4, GPIO_PIN_RESET);
}
}
完整代码如下
原文地址: https://www.cveoy.top/t/topic/eNUV 著作权归作者所有。请勿转载和采集!