Проверка состояния GPIO во встроенном программировании на C - PullRequest
0 голосов
/ 03 апреля 2019

У нас есть встроенное программирование на C, где мы должны реализовать конечный автомат, который меняет серию светодиодов в зависимости от входа джойстика. Два условия: «если левый светодиод включен и нажата кнопка« Вниз », перейдите на правый светодиод» и «если правый светодиод включен, а кнопка« Вниз нажата », перейдите в левый светодиод». Я знаю, как включить определенные светодиодные индикаторы при нажатии кнопок, но не знаю, как проверить состояние вывода / светодиода GPIO и изменить другой светодиод в зависимости от состояния при использовании джойстика. Я просто хочу знать, как «вызвать» состояние светодиода.

На данный момент это пример кода конечного автомата:

void
StateMachine ()
{
  // REPLACE THE FOLLOW CODE WITH YOUR SOLUTION
  // This code just toggles top LED and set left or right LED.
  //
  // Solution.

  uint8_t Joystick;
  uint8_t Toggle = 0;

  while (1)
  {
    Joystick = GetJoystick();

    if (Joystick == 'L')
    {
      WriteLED ('L', LED_ON);
      WriteLED ('R', LED_OFF);
    }
    else if (Joystick == 'R')
    {
      WriteLED ('L', LED_OFF);
      WriteLED ('R', LED_ON);
    }

    if (Toggle == 0)
    {
      WriteLED ('T', LED_ON);
      Toggle = 1;
    }
    else
    {
      WriteLED ('T', LED_OFF);
      Toggle = 0;
    }
  }
}

Обновление: это мой WriteLED метод

void
WriteLED (uint8_t LED, uint8_t State)
{
  // Check for correct state
  if ((State != LED_OFF) && (State != LED_ON))
  {
    return;
  }

  // Turn on/off the LED
  switch (LED)
    {
    case 'L':
      HAL_GPIO_WritePin (LD4_GPIO_Port, LD4_Pin, State);
      break;
    case 'T':
      HAL_GPIO_WritePin (LD3_GPIO_Port, LD3_Pin, State);
      break;
    case 'B':
      HAL_GPIO_WritePin (LD6_GPIO_Port, LD6_Pin, State);
      break;
    case 'R':
      HAL_GPIO_WritePin (LD5_GPIO_Port, LD5_Pin, State);
      break;
    }

  return;
}

Ответы [ 4 ]

3 голосов
/ 03 апреля 2019

Если в задании специально запрашивается «конечный автомат», то программное обеспечение должно как-то иметь разные внутренние «состояния», соответствующие различным требованиям к выходу светодиода.Существует множество способов представления конечного автомата - (вам показали один?) - Например:

// enumeration of the required states
enum OutputState {
    stateAllOff, // I'm *guessing* this is the required initial state?
    stateLeftLED,
    stateRightLED,
    // ... any other states that are specified.
    // ... but *not* random combinations of LEDs that are not part of the specification.
};

enum OutputState currentState = stateAllOff; // or whatever initial state is required

// [...] I'm not going to do the actual assignment here

Конечный автомат не должен считывать состояния светодиодов, он просто «запоминает»"их в переменной currentState.Теперь остальная часть кода становится простой реализацией условий, которые вам были заданы, так что ...

", если левый светодиод включен, а вниз нажата, изменить на правый светодиод"

    if (currentState == stateLeftLED) {
        if (Joystick == "D") {
            WriteLED ('R', LED_ON);
            WriteLED ('L', LED_OFF);
            currentState = stateRightLED;
        }
    }
2 голосов
/ 03 апреля 2019

Библиотека HAL STM предлагает функцию ReadPin, аналогичную функции WritePin, которую вы уже использовали.

Это объявление выглядит следующим образом:

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

Это означает, что вы можете прочитать состояние определенноговот так:

GPIO_PinState ld6_state = HAL_GPIO_ReadPin(LD6_GPIO_Port, LD6_Pin);

GPIO_PinState - это перечисление:

typedef enum
{
  GPIO_PIN_RESET = 0,
  GPIO_PIN_SET
}GPIO_PinState;

Осталось только сравнить возвращаемое значение функции чтения (ld6_state) с любым из значений перечисления.Как уже упоминалось в первом ответе, вы, скорее всего, испытаете некоторый отскок ваших входов, который вызван механической конструкцией ваших кнопок.Я думаю, выяснить, как решить это является частью задания, поэтому я оставлю это на ваше усмотрение.Ключевые слова для поиска: debounce или debouncing

1 голос
/ 03 апреля 2019

Вы, вероятно, хотите поместить задержку в свой основной цикл.Если ваша функция джойстика не блокирует код до тех пор, пока не увидит изменения, то переключение на верхнем светодиоде произойдет настолько быстро, что вы, вероятно, увидите тусклое свечение или, возможно, вообще ничего, в зависимости от времени нарастания вашего оборудования.Как сказал Wizzard, вы сможете узнать состояние своего светодиода, посмотрев в реестр.Как это сделать, полностью зависит от вашего оборудования.Скорее всего, было бы целесообразно использовать несколько статических логических значений, чтобы вы могли сохранить состояние светодиодов и проверить их, чтобы получить значения светодиодов, но это не идеальная реализация.Регистрируйте чеки лучше.

1 голос
/ 03 апреля 2019

Обычно состояние GPIO сохраняется в переменной регистра.Вам нужно либо определение этой переменной, либо вектор, указывающий на ее адрес, чтобы прочитать (или манипулировать) ее напрямую.У вас есть документация по методу WriteLED?Это может дать вам подсказку.

Если вы ничего не нашли, вы все равно можете установить флаг, чтобы указать, какой светодиод вы включили в последнее время.

Обычно встроенное программирование сильно зависит от чипа, с которым вы работаете, исоответствующий компилятор.Поэтому, чтобы дать вам лучший ответ, вы должны сначала предоставить важную информацию, такую ​​как аппаратное и программное обеспечение, которое вы используете, и библиотеки, которые вы хотите реализовать.

...