stm32 hal库高级流水灯代码

使用pd456,三个引脚作为led控制引脚。

  static uint8_t mode = 0;        // 效果模式
  static uint32_t counter = 0;    // 计数器
  static uint8_t dir = 1;         // 方向控制
  static uint8_t breath_val = 0;  // 呼吸灯亮度值
  static uint8_t fade_state = 0;  // 渐变状态
  
  counter++;
  HAL_Delay(20);  // 基础延时,控制效果速度
  
  // 模式1:流水灯效果
  if(mode == 0)
  {
    // 关闭所有LED
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
    
    // 根据计数器点亮不同LED,形成流水效果
    switch((counter / 10) % 3)
    {
      case 0: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); break;
      case 1: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); break;
      case 2: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET); break;
    }
    
    // 5秒后切换模式
    if(counter >= 250) { mode = 1; counter = 0; }
  }
  // 模式2:双向追逐效果
  else if(mode == 1)
  {
    // 关闭所有LED
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
    
    static uint8_t pos = 0;
    if(counter % 10 == 0)
    {
      // 控制移动方向
      if(pos >= 2) dir = 0;
      if(pos <= 0) dir = 1;
      
      pos += dir ? 1 : -1;
      
      // 根据位置点亮LED
      switch(pos)
      {
        case 0: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); break;
        case 1: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); break;
        case 2: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET); break;
      }
    }
    
    // 5秒后切换模式
    if(counter >= 250) { mode = 2; counter = 0; }
  }
  // 模式3:呼吸灯效果(轮流呼吸)
  else if(mode == 2)
  {
    static uint8_t current_led = 0;
    
    // 呼吸灯亮度变化
    if(counter % 2 == 0)
    {
      if(dir) 
        breath_val++;
      else 
        breath_val--;
      
      if(breath_val >= 255) dir = 0;
      if(breath_val <= 0) 
      {
        dir = 1;
        current_led = (current_led + 1) % 3; // 切换到下一个LED
      }
    }
    
    // 关闭所有LED
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
    
    // 根据亮度值控制当前LED的亮灭(PWM模拟)
    if(breath_val > (counter % 255))
    {
      switch(current_led)
      {
        case 0: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); break;
        case 1: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); break;
        case 2: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET); break;
      }
    }
    
    // 8秒后切换模式
    if(counter >= 400) { mode = 3; counter = 0; dir = 1; }
  }
  // 模式4:随机闪烁效果(修复版)
  else if(mode == 3)
  {
    // 随机点亮LED组合,确保不会全灭
    if(counter % 5 == 0)
    {
      uint8_t state4, state5, state6;
      do {
        state4 = (rand() % 2) ? GPIO_PIN_RESET : GPIO_PIN_SET;
        state5 = (rand() % 2) ? GPIO_PIN_RESET : GPIO_PIN_SET;
        state6 = (rand() % 2) ? GPIO_PIN_RESET : GPIO_PIN_SET;
        // 确保至少有一个LED亮着
      } while(state4 == GPIO_PIN_SET && state5 == GPIO_PIN_SET && state6 == GPIO_PIN_SET);
      
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, state4);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, state5);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, state6);
    }
    
    // 5秒后切换模式
    if(counter >= 250) { mode = 4; counter = 0; }
  }
  // 模式5:渐变流水效果
  else if(mode == 4)
  {
    // 关闭所有LED
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
    
    // 计算当前应该点亮的LED和亮度
    uint8_t main_led = (counter / 20) % 3;
    uint8_t prev_led = (main_led - 1 + 3) % 3;
    uint8_t fade_value = (counter % 20) * 13; // 0-255
    
    // 主LED常亮
    switch(main_led)
    {
      case 0: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); break;
      case 1: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); break;
      case 2: HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET); break;
    }
    
    // 前一个LED渐灭
    if(fade_value < 128) // 只在渐变的前半段显示
    {
      switch(prev_led)
      {
        case 0: 
          if(fade_value < (counter % 255))
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET);
          break;
        case 1: 
          if(fade_value < (counter % 255))
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET);
          break;
        case 2: 
          if(fade_value < (counter % 255))
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET);
          break;
      }
    }
    
    // 6秒后切换模式
    if(counter >= 300) { mode = 5; counter = 0; }
  }
  // 模式6:同步闪烁效果
  else if(mode == 5)
  {
    static uint8_t flash_state = 0;
    
    if(counter % 15 == 0)
    {
      flash_state = !flash_state;
      uint8_t state = flash_state ? GPIO_PIN_RESET : GPIO_PIN_SET;
      
      // 全部LED同步闪烁
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, state);
    }
    // 中间加入一次快速闪烁
    else if(counter % 45 == 22)
    {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_RESET);
      HAL_Delay(10);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
      HAL_Delay(10);
    }
    
    // 5秒后切换回第一个模式,形成循环
    if(counter >= 250) { mode = 0; counter = 0; }
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值