7-сегментный дисплей (одноразрядный)

Урок 8: 7-сегментный дисплей (одноразрядный)

Цели урока:

  1. Научиться использовать 7-сегментный дисплей для отображения чисел и символов.
  2. Понять разницу между дисплеями с общим катодом и общим анодом.
  3. Закрепить знания на практике, создав счётчик и другие проекты.

Теоретическая часть

Что такое 7-сегментный дисплей?

7-сегментный дисплей — это электронный компонент, состоящий из семи светодиодных сегментов (обозначаемых A-G), расположенных в форме восьмёрки. Дополнительно может присутствовать восьмой сегмент — десятичная точка (DP).

Одноразрядный семисегментный дисплей

Области применения:

  • Цифровые часы и таймеры.
  • Измерительные приборы.
  • Счётчики и индикаторы.
  • Простые информационные дисплеи.

Как это работает:

  1. Каждый сегмент (A-G) управляется отдельно.
  2. Для отображения числа или символа включаются соответствующие сегменты.
Описание сегментов семисегментного дисплея

Пример использования:

  • Отображение чисел (например, в часах или счетчиках).
  • Отображение простых символов (например, букв A-F).

7-сегментные дисплеи бывают двух типов: с общим катодом и с общим анодом.

  1. Дисплей с общим катодом (Common Cathode).
    • Все катоды (-) светодиодов соединены вместе.
    • Подключаются к GND (земле).
    • Сегменты включаются подачей HIGH сигнала.
  2. Дисплей с общим анодом (Common Anode).
    • Все аноды (+) светодиодов соединены вместе.
    • Подключаются к VCC (+5V).
    • Сегменты включаются подачей LOW сигнала.

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

Подключение 7-сегментного дисплея (с общим катодом).

Схема подключения (с использованием общего катода):

  • Подключите сегменты A-G к цифровым пинам на Arduino (например, 2-9).
  • Подключите общий катод к GND через резистор 220 Ом.
Схема подключения одноразрядного семисегментного дисплея с общим катодом

Схема подключения (с использованием общего анода):

  • Подключите сегменты A-G к цифровым пинам на Arduino (например, 2-9).
  • Подключите общий анод к 5V через резистор 220 Ом.
Схема подключения одноразрядного семисегментного дисплея с общим анодом

Практическая часть.

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

Пример 1: Последовательное включение сегментов (схема с общим катодом).

void setup() {\
  // Настройка всех пинов как выходов
  pinMode(2, OUTPUT); // DP
  pinMode(3, OUTPUT); // C
  pinMode(4, OUTPUT); // D
  pinMode(5, OUTPUT); // E
  pinMode(6, OUTPUT); // B
  pinMode(7, OUTPUT); // A
  pinMode(8, OUTPUT); // F
  pinMode(9, OUTPUT); // G
}

void loop() {
  // Поочерёдно включаем каждый сегмент
  for (int i = 2; i < 10; i++) {
    digitalWrite(i, HIGH); // Включить светодиод
    delay(200);            // Ждать 200 мс
    digitalWrite(i, LOW);  // Выключить светодиод
  }
}

Как работает этот код:

  1. В setup() настраиваются пины 2-9 как выходы.
  2. В loop() используется цикл for, который перебирает пины от 2 до 9.
  3. Для каждого пина:
    • Включается соответствующий сегмент (HIGH).
    • Делается пауза 200 мс.
    • Сегмент выключается (LOW).
  4. Цикл повторяется бесконечно.

Готовый проект по ссылке: Последовательное включение сегментов (схема с общим катодом).

Далее для этой же схемы реализуем код который будет считать от 0 до 9.

Пример 2: Отображение цифр от 0 до 9 (неоптимизированная версия) (схема с общим катодом).

void setup() {
  pinMode(2, OUTPUT); // Настройка пинов как выходов
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void loop() {
  digitalWrite(2, HIGH); //Всегда включаем dp

  //Цифра 0
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  digitalWrite(5, HIGH);  //вкл. E
  digitalWrite(8, HIGH);  //вкл. F
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D
  digitalWrite(5, LOW);   //выкл. E
  digitalWrite(8, LOW);   //выкл. F

  //Цифра 1
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  delay(1000);
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C

  //Цифра 2
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(9, HIGH);  //вкл. G
  digitalWrite(4, HIGH);  //вкл. D
  digitalWrite(5, HIGH);  //вкл. E
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(9, LOW);   //выкл. G
  digitalWrite(4, LOW);   //выкл. D
  digitalWrite(5, LOW);   //выкл. E

  //Цифра 3
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(9, HIGH);  //вкл. G
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(9, LOW);   //выкл. G
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D

  //Цифра 4
  digitalWrite(8, HIGH);  //вкл. F
  digitalWrite(9, HIGH);  //вкл. G
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  delay(1000);
  digitalWrite(8, LOW);   //выкл. F
  digitalWrite(9, LOW);   //выкл. G
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C

  //Цифра 5
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(8, HIGH);  //вкл. F
  digitalWrite(9, HIGH);  //вкл. G
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(8, LOW);   //выкл. F
  digitalWrite(9, LOW);   //выкл. G
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D
  
  //Цифра 6
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  digitalWrite(5, HIGH);  //вкл. E
  digitalWrite(8, HIGH);  //вкл. F
  digitalWrite(9, HIGH);  //вкл. G
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D
  digitalWrite(5, LOW);   //выкл. E
  digitalWrite(8, LOW);   //выкл. F
  digitalWrite(9, LOW);   //выкл. G

  //Цифра 7
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C

  //Цифра 8
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  digitalWrite(5, HIGH);  //вкл. E
  digitalWrite(8, HIGH);  //вкл. F
  digitalWrite(9, HIGH);  //вкл. G
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D
  digitalWrite(5, LOW);   //выкл. E
  digitalWrite(8, LOW);   //выкл. F
  digitalWrite(9, LOW);   //выкл. G

  //Цифра 9
  digitalWrite(7, HIGH);  //вкл. A
  digitalWrite(6, HIGH);  //вкл. B
  digitalWrite(3, HIGH);  //вкл. C
  digitalWrite(4, HIGH);  //вкл. D
  digitalWrite(8, HIGH);  //вкл. F
  digitalWrite(9, HIGH);  //вкл. G
  delay(1000);
  digitalWrite(7, LOW);   //выкл. A
  digitalWrite(6, LOW);   //выкл. B
  digitalWrite(3, LOW);   //выкл. C
  digitalWrite(4, LOW);   //выкл. D
  digitalWrite(8, LOW);   //выкл. F
  digitalWrite(9, LOW);   //выкл. G
}

Как работает этот код:

  • Для каждой цифры включаются определённые сегменты.
  • После отображения цифры все сегменты выключаются.
  • Каждая цифра отображается 1 секунду (1000 мс).

Готовый проект по ссылке: Отображение цифр от 0 до 9 (неоптимизированная версия) (схема с общим катодом).

Пример 3: Отображение цифр от 0 до 9 (оптимизированная версия) (схема с общим катодом).

// Пины для каждого сегмента (A,B,C,D,E,F,G,DP)
int segmentPins[] = {7, 6, 3, 4, 5, 8, 9, 2};

// Конфигурация сегментов для цифр 0-9
// Каждый байт определяет, какие сегменты горят для цифры
// Бит 0 = сегмент A, бит 1 = сегмент B, ..., бит 7 = DP
byte digitPatterns[10] = {
  0b11111100,  // 0: A,B,C,D,E,F
  0b01100000,  // 1: B,C
  0b11011010,  // 2: A,B,D,E,G
  0b11110010,  // 3: A,B,C,D,G
  0b01100110,  // 4: B,C,F,G
  0b10110110,  // 5: A,C,D,F,G
  0b10111110,  // 6: A,C,D,E,F,G
  0b11100000,  // 7: A,B,C
  0b11111110,  // 8: все сегменты
  0b11110110   // 9: A,B,C,D,F,G
};

void setup() {
  // Настраиваем все пины как выходы
  for (int i = 0; i < 8; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }
}

void displayDigit(int digit) {
  // Проверяем, что цифра в диапазоне 0-9
  if (digit < 0 || digit > 9) return;
  
  // Получаем паттерн для текущей цифры
  byte pattern = digitPatterns[digit];
  
  // Устанавливаем состояние каждого сегмента
  for (int i = 0; i < 8; i++) {
    // Проверяем i-й бит паттерна
    bool segmentState = bitRead(pattern, 7 - i);
    digitalWrite(segmentPins[i], segmentState);
  }
}

void loop() {
  // Последовательно отображаем цифры 0-9
  for (int i = 0; i < 10; i++) {
    displayDigit(i);
    delay(1000);
  }
}

Объяснение улучшенного кода:

  1. Создаётся массив segmentPins, который содержит номера пинов Arduino. Порядок сегментов в массиве: A, B, C, D, E, F, G, DP. Каждый номер соответствует физическому подключению сегмента к Arduino, например: сегмент A подключен к пину 7, сегмент B к пину 6 и т.д.
  2. Создаётся массив digitPatterns из 10 элементов (для цифр 0-9). Каждый элемент — это битовая маска (двоичное число), где: 1 означает, что сегмент должен гореть; 0 означает, что сегмент должен быть выключен. Структура битов: 0bABCDEFGDP (бит 7 = A, бит 6 = B, ..., бит 0 = DP).
  3. Объяснение функции displayDigit
    • Если переданная цифра меньше 0 или больше 9, функция завершается (за это отвечает return). Это защита от ошибок (например, если передать 10 или -1).
    • Из массива digitPatterns выбирается битовая маска для нужной цифры. Например: если digit = 3, то pattern = digitPatterns[3] = 0b11110010
    • На каждой итерации displayDigit(i) — отображает текущую цифру.

Готовый проект по ссылке: Отображение цифр от 0 до 9 (оптимизированная версия) (схема с общим катодом).

Пример 4: Последовательное отключение, затем включение сегментов (схема с общим анодом).

void setup() {
  // Настройка всех пинов как выходов
  pinMode(2, OUTPUT); // DP
  pinMode(3, OUTPUT); // C
  pinMode(4, OUTPUT); // D
  pinMode(5, OUTPUT); // E
  pinMode(6, OUTPUT); // B
  pinMode(7, OUTPUT); // A
  pinMode(8, OUTPUT); // F
  pinMode(9, OUTPUT); // G
}

void loop() {
  // Поочерёдно отключаем каждый сегмент
  for (int i = 2; i < 10; i++) {
    digitalWrite(i, HIGH); // Выключить светодиод
    delay(200);            // Ждать 200 мс
  }

  // Поочерёдно вкключаем каждый сегмент
  for (int i = 2; i < 10; i++){
    digitalWrite(i, LOW);  // Включить светодиод
    delay(200);            // Ждать 200 мс
  }
}

Принцип работы данного кода аналогичный что и в первом примере за одним исключением: для того чтобы диод загорелся необходимо записать в пин значение LOW, a для того чтобы отключить - записать HIGH. То есть при использовании схемы с общим анодом мы инвертируем сигнал используемый с общим катодом.

Готовый проект по ссылке: Последовательное отключение, затем включение сегментов (схема с общим анодом).

Домашнее задание:

  1. Создайте счётчик, который увеличивается при нажатии кнопки.
  2. Реализуйте таймер обратного отсчёта от 9 до 0.

Частые проблемы и решения

  1. Сегменты не светятся:
    • Проверьте тип дисплея (общий катод/анод).
    • Проверьте подключение общего вывода.
    • Убедитесь, что используются резисторы.
  2. Неправильные цифры:
    • Проверьте соответствие пинов и сегментов.
    • Убедитесь в правильности паттернов.
  3. Дисплей мерцает:
    • Убедитесь, что нет конфликта пинов.
    • Проверьте заземление.

Итог:

Вы научились:

  • Подключать 7-сегментный дисплей к Arduino.
  • Управлять отдельными сегментами.
  • Отображать цифры от 0 до 9.
  • Оптимизировать код с помощью массивов.
  • Работать с разными типами дисплеев.