Подключение семисегментного светодиодного индикатора. Часть 2.

В первой части мы рассмотрели подключение многоразрядного семисегментного индикатора при динамической развертке по разрядам, т.е. в один момент времени отображается один разряд индикатора целиком. Недостатком такого включения является относительно большое число дополнительных элементов на принципиальной схеме: транзисторные ключи, резисторы в цепи каждого сегмента.7seg-2s

Рассмотрим вариант динамической индикации с по сегментной разверткой.

Посегментная динамическая индикация.

При таком способе в каждый момент времени светятся одинаковые сегменты во всех разрядах индикатора. Т.е. подаем сигнал включения на сегмент, а разряды «поджигаем» только те, где данный сегмент должен светиться. При такой развертке имеем фиксированное число «поджиганий» в цикле развертки:  7 (сегменты) + 1 (точка). Время свечения каждого сегмента не должно превышать 5 мс (цикл полной развертки, при этом, составит 40 мс — предел!). Т.к. для двухразрядного индикатора при токе каждого сегмента 10 мА общий ток через порт контроллера будет составлять максимум 20 мА, следовательно можно обойтись без транзисторных ключей. И токоограничивающих резисторов нужно меньше — не по числу сегментов, а по числу разрядов. Пример принципиальной схемы для двух разрядов ниже:s7seg_s

Двухразрядный индикатор подключен к Arduino Pro mini. Размеры элементов таковы, что выводы индикатора непосредственно можно запаять в контактные площадки модуля (см фото в начале статьи). Катоды сегментов разрядов подключены к выводам платы напрямую без токоограничивающих резисторов. При небольшом числе разрядов (до четырех) это допустимо, т.к. при посегментной развертке, через вывод протекает суммарный ток одного сегмента всех разрядов (при четырех разрядах и 5 мА на сегмент, общий ток 5 мА * 4 = 20 мА, что допустимо). Аноды разрядов индикатора подключаются к выводам платы через токоограничивающий резистор — в каждый момент времени ток определяется только одним сегментом.

Простой скетч, демонстрирующий работу динамической посегментной индикации, приведен ниже. Ничего полезного программа не делает, но позволяет легко в себе разобраться. Основными процедурами являются DisplayShow() — реализующая один цикл развертки (3 мс на свечение одного сегмента, всего восемь);  ShowSeg() — включение нужных разрядов для выбранного сегмента и DigToSegmRaz() — кодирование цифры в ее 7-сегментное изображение по разрядам. Программа индицирует на индикаторе число «3.4».

/* индикация числа "34" на 2х разрядном 7-сегм.индикаторе
программная динамическая развертка по сегментам 3мс на сегмент
8 сегментов - 2 разряда (резисторы) Общий Анод */

#define DIG1 9
#define DIG2 A0
#define s_A 6
#define s_B 5
#define s_C 13
#define s_D 10
#define s_E 12
#define s_F 7
#define s_G 8
#define s_H 11
#define Takt 3  //мс на каждый сегмент

int dig1 = 0; //левый
int dig2 = 0; //правый
byte pnt = 0; //точка меж разрядами

//посегментная развертка 0 в разряде - погашено!
byte segA = 0; //развертка по сегментная, А
byte segB = 0; //развертка по сегментная, B
byte segC = 0; //развертка по сегментная, C
byte segD = 0; //развертка по сегментная, D
byte segE = 0; //развертка по сегментная, E
byte segF = 0; //развертка по сегментная, F
byte segG = 0; //развертка по сегментная, G
byte segH = 0; //развертка по сегментная, H

void setup() {                
  pinMode(s_A, OUTPUT); pinMode(s_B, OUTPUT);
  pinMode(s_C, OUTPUT); pinMode(s_D, OUTPUT);
  pinMode(s_E, OUTPUT); pinMode(s_F, OUTPUT);
  pinMode(s_G, OUTPUT); pinMode(s_H, OUTPUT);
  pinMode(DIG1, OUTPUT);
  pinMode(DIG2, OUTPUT);
  Clean();
  digitalWrite(DIG1,HIGH);
  digitalWrite(DIG2,HIGH);
}

void loop() {
  DisplayMath(34);
  DigToSegmRaz();  //раскидать цифры по сегментам развертки
  DisplayShow();
}

void DisplayMath(int data) {
  pnt = 0; //изначально точка погашена
  dig1 = dig2 = 0;
  if (data < 100) {
    while (data >= 10) {
      data -= 10;
      dig1++;
    }
    dig2 = data;
    pnt = 1;  //вкл точку меж разрядами
  }
  else {
    data = data / 10;
    while (data >= 10) {
      data -= 10;
      dig1++;
    }
    dig2 = data;
  }  
}

void DisplayShow() {
  digitalWrite(s_A,LOW);  //включаем линию сегментов А
  ShowSeg(segA);
  delay(Takt);
  digitalWrite(s_A,HIGH);  //выключаем линию сегментов А
  digitalWrite(s_B,LOW);   //вкл В
  ShowSeg(segB);
  delay(Takt);
  digitalWrite(s_B,HIGH);  //выключаем линию сегментов В
  digitalWrite(s_C,LOW);   //вкл C
  ShowSeg(segC);
  delay(Takt);
  digitalWrite(s_C,HIGH);  //выключаем линию сегментов C
  digitalWrite(s_D,LOW);   //вкл D
  ShowSeg(segD);
  delay(Takt);
  digitalWrite(s_D,HIGH);  //выключаем линию сегментов D
  digitalWrite(s_E,LOW);   //вкл E
  ShowSeg(segE);
  delay(Takt);
  digitalWrite(s_E,HIGH);  //выключаем линию сегментов E
  digitalWrite(s_F,LOW);   //вкл F
  ShowSeg(segF);
  delay(Takt);
  digitalWrite(s_F,HIGH);  //выключаем линию сегментов F
  digitalWrite(s_G,LOW);   //вкл G
  ShowSeg(segG);
  delay(Takt);
  digitalWrite(s_G,HIGH);  //выключаем линию сегментов G
  digitalWrite(s_H,LOW);   //вкл H
  ShowSeg(segH);
  delay(Takt);
  digitalWrite(s_H,HIGH);  //выключаем линию сегментов H
}

//включение разрядов индикатора 
void ShowSeg(byte digit)  {
  switch(digit) {
    case 1: {
       digitalWrite(DIG1,LOW);    //правый разряд включить
       digitalWrite(DIG2,HIGH); }
    break;
    case 2: {
       digitalWrite(DIG1,HIGH);    //левый разряд включить
       digitalWrite(DIG2,LOW); }
    break;
    case 3: {
       digitalWrite(DIG1,HIGH);    //оба разряда включить
       digitalWrite(DIG2,HIGH); }
    break;
    default: 
     {   //case 0:
       digitalWrite(DIG1,LOW);    //оба разряда гасим
       digitalWrite(DIG2,LOW); }
    break;
  }
}  

//раскидать цифры по сегментам развертки
void DigToSegmRaz() {
  //для левого разряда
  switch(dig1) {
    case 0: {
      segA = B10; segB = B10; segC = B10; segD = B10;
      segE = B10; segF = B10; segG = B00;    }
    break;
    case 1: {
      segA = B00; segB = B10; segC = B10; segD = B00;
      segE = B00; segF = B00; segG = B00;    }
    break;
    case 2: {
      segA = B10; segB = B10; segC = B00; segD = B10;
      segE = B10; segF = B00; segG = B10;    }
    break;
    case 3: {
      segA = B10; segB = B10; segC = B10; segD = B10;
      segE = B00; segF = B00; segG = B10;    }
    break;
    case 4: {
      segA = B00; segB = B10; segC = B10; segD = B00;
      segE = B00; segF = B10; segG = B10;    }
    break;
    case 5: {
      segA = B10; segB = B00; segC = B10; segD = B10;
      segE = B00; segF = B10; segG = B10;    }
    break;
    case 6: {
      segA = B10; segB = B00; segC = B10; segD = B10;
      segE = B10; segF = B10; segG = B10;    }
    break;
    case 7: {
      segA = B10; segB = B10; segC = B10; segD = B00;
      segE = B00; segF = B00; segG = B00;    }
    break;
    case 8: {
      segA = B10; segB = B10; segC = B10; segD = B10;
      segE = B10; segF = B10; segG = B10;    }
    break;
    case 9: {
      segA = B10; segB = B10; segC = B10; segD = B10;
      segE = B00; segF = B10; segG = B10;    }
    break;
  }
  //для правого разряда с помощью ИЛИ включаем единицей нужный сегмент
  switch(dig2) {
    case 0: { //для "0" надо включить все, кроме G
      segA = segA | 1; segB = segB | 1; segC = segC | 1; segD = segD | 1;
      segE = segE | 1; segF = segF | 1;   }
    break;
    case 1: { //для "1" включим сегменты B и С
      segB = segB | 1; segC = segC | 1;   }
    break;
    case 2: {
      segA = segA | 1; segB = segB | 1; segD = segD | 1;
      segE = segE | 1; segG = segG | 1;    }
    break;
    case 3: {
      segA = segA | 1; segB = segB | 1; segC = segC | 1; segD = segD | 1;
      segG = segG | 1;    }
    break;
    case 4: {
      segB = segB | 1; segC = segC | 1;
      segF = segF | 1; segG = segG | 1;    }
    break;
    case 5: {
      segA = segA | 1; segC = segC | 1; segD = segD | 1;
      segF = segF | 1; segG = segG | 1;    }
    break;
    case 6: {
      segA = segA | 1; segC = segC | 1; segD = segD | 1;
      segE = segE | 1; segF = segF | 1; segG = segG | 1;    }
    break;
    case 7: {
      segA = segA | 1; segB = segB | 1; segC = segC | 1;   }
    break;
    case 8: {
      segA = segA | 1; segB = segB | 1; segC = segC | 1; segD = segD | 1;
      segE = segE | 1; segF = segF | 1; segG = segG | 1;    }
    break;
    case 9: {
      segA = segA | 1; segB = segB | 1; segC = segC | 1; segD = segD | 1;
      segF = segF | 1; segG = segG | 1;    }
    break;
  }
  if (pnt == 1)  segH = B10;  //управляем точкой
  else  segH = B00;
}

void Clean() {  //все гасим (очистка)
    digitalWrite(s_A,HIGH); digitalWrite(s_B,HIGH);  //катоды +
    digitalWrite(s_C,HIGH); digitalWrite(s_D,HIGH);
    digitalWrite(s_E,HIGH); digitalWrite(s_F,HIGH);
    digitalWrite(s_G,HIGH); digitalWrite(s_H,HIGH);
    digitalWrite(DIG1,HIGH); digitalWrite(DIG2,HIGH);   //аноды + 
}

Надо отметить, что программа так же написана в ХУДШИХ традициях программирования. При ее работе контролер тоже только разверткой изображения и занимается, сделать что-то полезное ему «некогда», разве что — в прерываниях… Тем не менее, такой подход к написанию программы позволил «быстренько» создать вполне работоспособный велоспидометр (статья в журнале «Радио»). DSCF4093 DSCF4101A

Для увеличения числа разрядов индикатора в схеме надо аноды новых разрядов подключить через резисторы к портам Arduino. В ShowSeg() надо добавить отработку комбинаций включения для новых разрядов индикатора. В процедуре DigToSegmRaz() также необходимо дописать логическое ИЛИ для включения сегментов новых разрядов.

Для индикаторов с общим катодом схема изменится: аноды сегментов подключаются к выходам микроконтроллера без резисторов, а катоды разрядов через резисторы. В процедурах DisplayShow() и Show() надо поменять местами HIGH и LOW.

Подключение семисегментного светодиодного индикатора. Часть 2.: 1 комментарий

  1. В первой части, посвященной методике работы с драйвером светодиодных индикаторов MAX7221, было знакомство с этим драйвером. В частности был описан режим прямого управления сегментами. Осталось научится работать во втором режиме, при котором используется встроенный в микросхему декодер символов

Добавить комментарий

Ваш e-mail не будет опубликован.

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".