7-сегментный 3-значный дисплей отображает данные неправильно

Я написал код, который должен работать, но по какой-то причине числа отображаются неправильно. Когда я выбираю отображение одного и того же числа 3 раза, оно работает правильно (значит, соединения контактов верны), но при попытке отобразить разные числа на каждой цифре все становится запутанным. Может кто-нибудь увидеть, что не так с кодом? Кажется, я не могу найти. Спасибо!

Работает, когда 3 цифры одинаковы:

занятой кот

Не работает с другими числами (должно быть 3, 2, 1:

занятой кот

И код:

int a = 2;               //Определение сегментов, соответствующих выводам
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;

void setup(void) {      //Установка пинов в качестве выходных данных
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
}

void WriteNum(int PositionN, int Number) {
  int Position;
  int NumberSegments[10][7] = {{a,b,c,d,e,g},     //Определение сегментов для формирования чисел
                          {b,c},
                          {a,b,d,e,g},
                          {a,b,c,d,g},
                          {b,c,f,d},
                          {a,c,d,f,g},
                          {a,c,d,e,f,g},
                          {a,b,c},
                          {a,b,c,d,e,f,g},
                          {a,b,c,d,f,g}};
  digitalWrite(A0, HIGH);                       //Установка начальных условий (Все сегменты низкие и ни одна цифра не включена)
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

  switch (PositionN) {                        //Решение, какую цифру включить
    case 1:
      Position = A0;
      break;
    case 2:
      Position = A1;
      break;
    case 3:
      Position = A2;
      break;
  }
  digitalWrite(Position, LOW);
  for (int i = 0; i < sizeof(NumberSegments[Number]); i++){       //Для каждого сегмента в number для отображения
        digitalWrite(NumberSegments[Number][i], HIGH);            //Освещаем этот сегмент
        }
  delay(5);
}

void loop(void) {
  WriteNum(1,2);
  WriteNum(2,2);
  WriteNum(3,2);
}

, 👍1


1 ответ


Лучший ответ:

1

У меня есть три рекомендации для вас. @Gerben был прав относительно вашей проблемы, но выполнение следующих трех шагов улучшит скорость вашего кода:

  1. Измените определение для NumberSegments на [10][8] и укажите количество активных сегментов в качестве первого числа каждого массива:

     ...[10][8] = {{6,a,b,c,d,e,g},     // ...
                   {2,b,c},
                   {5,a,b,d,e,g}, // и т.д.
    
  2. Измените цикл for следующим образом:

    for (int i = 1; i <= NumberSegments[Number][0]; i++) { // ...
       digitalWrite(NumberSegments[Number][i], HIGH); // ...
    }
    

    Это включит только минимально необходимое количество сегментов. Обратите внимание, что цикл теперь начинается с 1 и использует <= вместо <.

  3. Поместите ключевое слово static перед NumberSegments:

    static int NumberSegments[10][8] = {{ // ...
    

Последнее — языковая тонкость. Каждый раз, когда вызывается функция WriteNum, бедняжке приходится заново создавать (большой) массив NumberSegments — и каждый раз одно и то же! Ключевое слово static означает « создать эту переменную только один раз». В следующий раз в функции она уже будет доступна: никакой обработки не требуется!

Вы также можете рассмотреть возможность перемещения int position; ниже NumberSegments, поскольку принято размещать переменные static на первом месте в функции.

Вы также можете использовать ключевое слово const в NumberSegments, поскольку его значения никогда не меняются:

static const int NumberSegments[10][8] = {{ // ...
,