标题: 求一个STM32的8个流水灯 [打印本页]

作者: HHHHRRR    时间: 2025-5-22 00:42
标题: 求一个STM32的8个流水灯
通过按键能够实现对灯光的启动、关闭、效果花样切换功能 3.设计要求至少控制8盏LED灯,能够完成至少四种花样的切换加分项:能够实现灯光能与蜂鸣器的配合

作者: 阿莎·    时间: 2025-6-27 09:31
#include "stm32f10x.h"

// 硬件定义
#define LED_PORT GPIOA
#define LED_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | \
                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7)

#define KEY_PORT GPIOB
#define KEY_PIN GPIO_Pin_0

#define BEEP_PORT GPIOB
#define BEEP_PIN GPIO_Pin_1

// 系统状态
typedef enum {
    SYSTEM_OFF,
    SYSTEM_RUNNING
} SystemState;

// 灯光模式
typedef enum {
    MODE_1_RIGHT_LEFT,
    MODE_2_LEFT_RIGHT,
    MODE_3_INSIDE_OUT,
    MODE_4_BLINK_ALL,
    MODE_COUNT
} LightMode;

// 全局变量
volatile SystemState sysState = SYSTEM_OFF;
volatile LightMode currentMode = MODE_1_RIGHT_LEFT;
uint8_t ledPosition = 0;
uint16_t delayCounter = 0;
uint8_t blinkState = 0;

// 函数原型
void RCC_Configure(void);
void GPIO_Configure(void);
void TIM_Configure(void);
void SysTick_Handler(void);
void UpdateLEDs(void);
void Beep(uint16_t duration, uint8_t times);
void ProcessKey(void);

int main(void) {
    // 初始化
    RCC_Configure();
    GPIO_Configure();
    TIM_Configure();
   
    // 系统启动提示
    Beep(100, 2);
   
    while(1) {
        ProcessKey();
        __WFI();  // 进入低功耗模式等待中断
    }
}

// 时钟配置
void RCC_Configure(void) {
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                           RCC_APB2Periph_AFIO, ENABLE);
   
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}

// GPIO配置
void GPIO_Configure(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
   
    // LED配置 - PA0~PA7
    GPIO_InitStructure.GPIO_Pin = LED_PINS;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT, &GPIO_InitStructure);
    LED_PORT->ODR = 0x00;  // 初始关闭所有LED
   
    // 按键配置 - PB0 (外部上拉)
    GPIO_InitStructure.GPIO_Pin = KEY_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(KEY_PORT, &GPIO_InitStructure);
   
    // 蜂鸣器配置 - PB1
    GPIO_InitStructure.GPIO_Pin = BEEP_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(BEEP_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
}

// 定时器配置 - 10ms中断一次
void TIM_Configure(void) {
    TIM_TimeBaseInitTypeDef TIM_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
   
    TIM_InitStructure.TIM_Period = 1000 - 1;      // 自动重装载值
    TIM_InitStructure.TIM_Prescaler = 720 - 1;     // 72MHz/720 = 100kHz
    TIM_InitStructure.TIM_ClockDivision = 0;
    TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
   
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM2, ENABLE);
   
    // 配置中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// 蜂鸣器控制
void Beep(uint16_t duration, uint8_t times) {
    for(uint8_t i = 0; i < times; i++) {
        GPIO_SetBits(BEEP_PORT, BEEP_PIN);
        for(volatile uint32_t j = 0; j < duration * 1000; j++);
        GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
        for(volatile uint32_t j = 0; j < 10000; j++); // 短暂间隔
    }
}

// 处理按键
void ProcessKey(void) {
    static uint8_t keyLastState = 1;  // 假设初始高电平
    static uint32_t pressTime = 0;
   
    uint8_t currentState = GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN);
   
    // 检测按键按下 (下降沿)
    if((keyLastState == 1) && (currentState == 0)) {
        pressTime = 0;
    }
   
    // 检测按键释放 (上升沿)
    if((keyLastState == 0) && (currentState == 1)) {
        if(pressTime < 50) {  // 短按 (<0.5s)
            if(sysState == SYSTEM_OFF) {
                sysState = SYSTEM_RUNNING;  // 启动系统
                Beep(100, 1);
            } else {
                // 切换灯光模式
                currentMode = (currentMode + 1) % MODE_COUNT;
                Beep(150, currentMode + 1);
                ledPosition = 0;  // 重置灯光位置
            }
        } else {  // 长按 (>0.5s)
            sysState = (sysState == SYSTEM_OFF) ? SYSTEM_RUNNING : SYSTEM_OFF;
            Beep(100, (sysState == SYSTEM_ON) ? 1 : 2);
            LED_PORT->ODR = 0x00;  // 关闭所有LED
        }
    }
   
    keyLastState = currentState;
    pressTime++;
}

// 更新LED显示
void UpdateLEDs(void) {
    if(sysState != SYSTEM_RUNNING) return;
   
    if(delayCounter++ < 10) return;  // 100ms延迟
    delayCounter = 0;
   
    switch(currentMode) {
        case MODE_1_RIGHT_LEFT:  // 从左向右流水灯
            LED_PORT->ODR = (1 << ledPosition);
            ledPosition = (ledPosition + 1) % 8;
            break;
            
        case MODE_2_LEFT_RIGHT:  // 从右向左流水灯
            LED_PORT->ODR = (0x80 >> ledPosition);
            ledPosition = (ledPosition + 1) % 8;
            break;
            
        case MODE_3_INSIDE_OUT:  // 从中间向两边扩展
            if(ledPosition < 4) {
                LED_PORT->ODR = (1 << (3 - ledPosition)) | (1 << (4 + ledPosition));
            } else {
                LED_PORT->ODR = 0;
            }
            ledPosition = (ledPosition + 1) % 5;
            break;
            
        case MODE_4_BLINK_ALL:  // 所有LED同步闪烁
            LED_PORT->ODR = blinkState ? 0xFF : 0x00;
            blinkState = !blinkState;
            break;
    }
}

// 定时器中断 (10ms)
void TIM2_IRQHandler(void) {
    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        UpdateLEDs();
        ProcessKey();
    }
}
作者: 单片机重购    时间: 2025-6-27 14:47
这种的程序网上开源的很多,你需要去网上找找,在这个网站学习STM32完全不够用的哦,你要去别的网站再去搜寻点STM32的资料哦
作者: SHYKH    时间: 2025-6-27 17:21
Hi! Your project sounds like a fun and practical challenge—controlling 8 LEDs with multiple switching patterns using a button, and even syncing with a buzzer for bonus points. I'd be happy to offer some ideas to help you get started.  ✅ Suggested Approach: &#128257; 1. Use a Microcontroller (like Arduino or STM32): It’s the easiest way to handle multiple LEDs, button input, and a buzzer with flexible logic.  &#128280; 2. Button-Control Logic: Use one button to cycle through 4 different modes.  Each press can increment a mode counter (0–3), and after the 4th, reset back to 0.  c Copy Edit // Pseudocode for button press logic if (buttonPressed) {   mode = (mode + 1) % 4; } &#128161; LED Pattern Ideas (at least 4): All LEDs ON  Chase effect (like running lights, one LED on at a time in sequence)  Blink all LEDs together  Even/Odd pattern (alternate between even-numbered and odd-numbered LEDs)  &#128276; Bonus: Add Buzzer Coordination You can sync a short beep with every button press or  Make the buzzer follow the LED pattern (e.g., beep when LEDs blink)  c Copy Edit // Example: Turn on buzzer with LED digitalWrite(buzzerPin, HIGH); delay(100); digitalWrite(buzzerPin, LOW); &#129504; Additional Tips: Use debounce logic or delay() after button press to avoid false triggers.  Store the mode state in a variable and use a switch or if statements to control LED patterns.  You could even add PWM dimming if you want to level up!  Let me know what platform or microcontroller you’re using—I’d be glad to share example code or schematics tailored to your setup. Good luck with your design!




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1