STM32按键控制流水灯停止启动和正反流水
时间: 2023-08-18 20:05:10 浏览: 75
好的,我可以为您提供一个稍微复杂一些的 STM32 按键控制流水灯的代码,实现以下三个功能:
1. 检测按键是否按下,按下则切换 LED 灯的状态(停止/启动);
2. 在 LED 灯启动状态下,按下按键则切换流水灯的方向(正/反);
3. 在 LED 灯启动状态下,正反流水灯效果。
以下是代码实现:
```c
#include "stm32f10x.h"
#define LED_PIN1 GPIO_Pin_12
#define LED_PIN2 GPIO_Pin_13
#define LED_PIN3 GPIO_Pin_14
#define LED_PIN4 GPIO_Pin_15
#define LED_PORT GPIOA
#define KEY_PIN GPIO_Pin_0
#define KEY_PORT GPIOB
void delay(uint32_t ms);
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
// 初始化 LED 引脚为输出
GPIO_InitStruct.GPIO_Pin = LED_PIN1 | LED_PIN2 | LED_PIN3 | LED_PIN4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(LED_PORT, &GPIO_InitStruct);
// 初始化 KEY 引脚为输入,并开启上拉电阻
GPIO_InitStruct.GPIO_Pin = KEY_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(KEY_PORT, &GPIO_InitStruct);
uint8_t led_state = 0; // LED 灯状态,0表示停止,1表示启动
uint8_t led_direction = 0; // LED 灯流水方向,0表示正向,1表示反向
uint8_t led_index = 0; // LED 灯流水位置
while (1)
{
// 检测按键是否按下
if(GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == 0)
{
// 切换 LED 灯的状态
led_state = !led_state;
if(led_state == 0)
{
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN3 | LED_PIN4);
}
}
if(led_state == 1)
{
// LED 灯启动状态,正反流水灯效果
if(led_direction == 0)
{
// 正向流水
switch(led_index)
{
case 0:
GPIO_SetBits(LED_PORT, LED_PIN1);
GPIO_ResetBits(LED_PORT, LED_PIN2 | LED_PIN3 | LED_PIN4);
break;
case 1:
GPIO_SetBits(LED_PORT, LED_PIN2);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN3 | LED_PIN4);
break;
case 2:
GPIO_SetBits(LED_PORT, LED_PIN3);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN4);
break;
case 3:
GPIO_SetBits(LED_PORT, LED_PIN4);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN3);
break;
default:
break;
}
led_index++;
if(led_index > 3) led_index = 0;
}
else
{
// 反向流水
switch(led_index)
{
case 0:
GPIO_SetBits(LED_PORT, LED_PIN4);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN3);
break;
case 1:
GPIO_SetBits(LED_PORT, LED_PIN3);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN4);
break;
case 2:
GPIO_SetBits(LED_PORT, LED_PIN2);
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN3 | LED_PIN4);
break;
case 3:
GPIO_SetBits(LED_PORT, LED_PIN1);
GPIO_ResetBits(LED_PORT, LED_PIN2 | LED_PIN3 | LED_PIN4);
break;
default:
break;
}
led_index--;
if(led_index > 3) led_index = 3;
}
// 检测按键是否按下,按下则切换流水方向
if(GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == 0)
{
led_direction = !led_direction;
}
delay(100);
}
else
{
// LED 灯停止状态,LED 灯常亮
GPIO_ResetBits(LED_PORT, LED_PIN1 | LED_PIN2 | LED_PIN3 | LED_PIN4);
}
}
}
void delay(uint32_t ms)
{
// 使用 SysTick 计数器实现延时
SysTick->LOAD = SystemCoreClock / 1000 * ms;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
SysTick->CTRL = 0;
}
```
以上代码实现的功能是:检测按键是否按下,按下则切换 LED 灯的状态(停止/启动);在 LED 灯启动状态下,按下按键则切换流水灯的方向(正/反);在 LED 灯启动状态下,正反流水灯效果。在代码中使用了 SysTick 计数器实现延时函数。您需要根据实际情况修改引脚号、延时时间等参数。希望对您有所帮助!