使用微控制器在颜色之间切换

Changing between colors using a microcontroller

提问人:Mendi 提问时间:7/26/2023 更新时间:7/26/2023 访问量:77

问:

我在微控制器编程和一般编程方面相当陌生。我目前正在使用 Nucleo 开发板进行个人项目,我被困在接下来需要编写哪些代码才能获得我想要的功能上。

这个想法是在开关打开时打开 LED,在开关关闭时关闭 LED,这就是我卡住的地方,每次我再次打开开关时循环使用不同的颜色。

目前,我无法让模式切换到下一种颜色。

所有 LED 均设置为 TIM3(红色、绿色、蓝色)。

我的开关设置为下拉。

这是我目前所拥有的:

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // Red
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // Green
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // Blue

  int mode = 0;


  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      // Check to see if the switch is pressed.
      if (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) == GPIO_PIN_SET) {

          mode++;

          if(mode == 1) {

          // Red
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue

          } else if (mode == 2) {
          // Red
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue

          }


      } else {
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
          __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
      }

  }

任何帮助或建议都会很棒!同样,我对此很陌生,所以如果我错过了需要提供的重要信息,请告诉我。谢谢!

C Arduino STM32 微控制器 Nucleo

评论

0赞 pmacfarlane 7/26/2023
那么当你按下按钮时会发生什么?是黄色的还是什么?
0赞 pmacfarlane 7/26/2023
有用的说明 - 如果您想更改您的问题或添加某些内容,您可以随时对其进行编辑。单击底部的“编辑”按钮。您无需删除问题并创建新问题。
2赞 user3386109 7/26/2023
当开关打开时,将非常快速地增加,因此红色将亮起几分之一秒,然后绿色将亮起。届时将继续增加 3,4,5,...但一切都不会改变。因此,绿色应保持亮起,直到您停止按下开关。modemode

答:

3赞 pmacfarlane 7/26/2023 #1

您可能不希望每次循环时颜色都发生变化(可能每秒执行数千次)。我假设从“关闭”到“打开”的按钮转换应该只更改一次颜色。

我还假设你想在红色、绿色和蓝色之间循环。由于您似乎正在使用 PWM(和三个 LED),因此可以有更多的颜色,但您还没有告诉我们您真正需要什么。

因此,您似乎需要某种状态机来跟踪按钮的状态,以及要显示的颜色。像这样的东西(完全未经测试的伪装代码):

// Track the current state of the button
enum button_state_e {
    BUTTON_NOT_PRESSED,
    BUTTON_JUST_PRESSED,
    BUTTON_PRESSED
};

static enum button_state_e button_state = BUTTON_NOT_PRESSED;

// The colour to show next - 0 = red, 1 = green, 2 = blue, for example
static uint8_t button_colour;

while (1)
{
    bool pressed = (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) == GPIO_PIN_SET);

    switch (button_state)
    {
        case BUTTON_NOT_PRESSED:
            if (pressed)
                button_state = BUTTON_JUST_PRESSED;
            break;

        case BUTTON_JUST_PRESSED:
            if (pressed)
            {
                button_state = BUTTON_PRESSED;
                switch_on_leds_for(button_colour);
                button_colour = (button_colour + 1) % 3;
            }
            else
                button_state = BUTTON_NOT_PRESSED;
            break;

        case BUTTON_PRESSED:
            if (!pressed)
            {
                button_state = BUTTON_NOT_PRESSED;
                switch_off_all_leds();
            }
            break;
    }

    ms_delay(10); // delay 10 ms to make debounce work
}

这实现了基本的去抖动,以防止按钮上的毛刺意外触发颜色变化。这就是为什么你希望在循环中出现延迟。如果您仍然看到退回,请增加延迟时间。

由于你只有三种颜色,你需要包裹你的,以便在它回到 之后,因此模数。button_colour20

我已经省略了一些功能,但你会想要这样的东西:

void switch_off_all_leds(void)
{
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
}

void switch_on_leds_for(int colour)
{
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, colour == 0 ? 230 : 0); // Red
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, colour == 1 ? 230 : 0); // Green
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, colour == 2 ? 230 : 0); // Blue
}

评论

0赞 Mendi 7/26/2023
谢谢!这效果很好。我不得不将延迟更改为HAL_Delay但除此之外,它效果很好。我将通读它,以更好地了解它的作用。再次感谢。