04.02.2016

Подключение 4-х разрядного сегментного индикатора к Arduino

Итак, индикатор с общим катодом на 4 разряда 7 сегментов плюс точки в каждом разряде.

Схема индикатора с общим катодом

Здесь необходима динамическая индикация. Один порт нужно использовать для управления сегментами (8 шт - 8 бит), четыре пина - для управления разрядами. Засветка сегмента высоким уровнем, включение разряда - низким. При этом, не забываем, что по цепям сегментов пойдет ток, необходимый для свечения светодиодов, до 20 мА по каждому (это наш микроконтроллер еще вынесет). А вот по общему катоду ток суммируется, при этом пины управления разрядом примут на себя больше положенного. В такой ситуации лучше использовать 4 биполярных транзистора. Так мы себя обезопасим. (Справедливости ради следует отметить, что для экспериментов я не стал заморачиваться на макетке с транзисторами, а просто сократил время свечения каждого разряда до минимума, и нагружал непосредственно на порт. По контактам на сегменты поставил дополнительно резисторы на 220 - 300 Ом, и получил не супер яркое, но надежное свечение.) В жизни же схема получилась вот такая:


С учетом транзисторов, разряд теперь включается высоким уровнем. Формируем комбинацию на порт по сегментам, выставляем высокий уровень на нужный разряд, ожидаем необходимое время (подбирается экспериментально по необходимой яркости и мерцанию), и гасим разряд низким уровнем. Повторяем все для следующего разряда. И так по кругу. Понятно, что при подключении индикатора с общим анодом или индикатора с другим количеством разрядов соображения будут аналогичны. Для удобства написания программы номера портов были внесены в массив в необходимой последовательности, что позволяет перебирать их в одном операторе цикла не зависимо от их значений. А таблицу символов можно написать самому. Разместить символы можно так же в массив.

Пример рабочего програмного кода для вывода значения 4-х значного числа (переменная DIGIT) на индикатор:

unsigned int DIGIT; //значение для вывода на индикатор
/**************** уаправление сегментами ******************/
/* присваиваем номера пинов для наглядности*/
const int segA = 0;   //   номера PIN сегментов (выбирается в конкретном проекте)
const int segB = 1;   //       ______A______
const int segC = 8;   //      F                        B    
const int segD = 9;   //      | _____G_____  |
const int segE = 10; //      E                        C
const int segF = 11; //       | _____D_____  |     H
const int segG = 12;
//const int segH =   ; /* H - сегмент точка, PIN не задаю, мне не нужен */
const int segnum[] = {0, 1, 8, 9, 10, 11, 12};      //занесем номера PIN сегментов в массив
const char sostcathode[4] = {A2, A3, A4, A5}; //массив с номерами PIN для упр.разрядами

//******** знакогенератор ****************/
const unsigned char symbols[ ] = {
B00111111, /* 0 */
B00000110, /* 1 */
B01011011, /* 2 */
B01001111, /* 3 */
B01100110, /* 4 */
B01101101, /* 5 */
B01111101, /* 6 */
B00000111, /* 7 */
B01111111, /* 8 */
B01101111, /* 9 */
};
const unsigned int PAUSE = 1; //задержка свечения - подобрать (мс)
int razr[4]; //массив, содержащий выводимое число, разбитое поразрядно, номера разрядов 0 - 3

void setup() {
/*установка на вывод пинов порта упр. катодами */
pinMode (A2, OUTPUT);        // порт разряд 0
pinMode (A3, OUTPUT);        // порт разряд 1
pinMode (A4, OUTPUT);        // порт разряд 2
pinMode (A5, OUTPUT);        // порт разряд 3
/*установка на вывод пинов порта упр. сегментами*/
pinMode(segA, OUTPUT);
pinMode(segB, OUTPUT);
pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT);
pinMode(segE, OUTPUT);
pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);
}

void loop(){
DIGIT = 1234;       // значение для вывода
// здесь нужен вызов подпрограммы разбора числа по разрядам,
// результатом работы которой будет заполненный массив, но для
// упрощения примера присвоим требуемые значения явно
int razr[] = {1,2,3,4};
for (int n = 0; n <= 3; n++)              // заполнение массива значений знаков индикатора
  {
    for (int g=0; g<=6; g++){             // запись сегментов, побитно
      digitalWrite(segnum[g], bitRead (symbols[razr[n]], g));
    }          
    digitalWrite(sostcathode[n], HIGH);   //высвечиваем нужный разряд
    delay(PAUSE);                         //ждем, пусть посветит
    digitalWrite(sostcathode[n], LOW);    //гасим разряд
  }
}

В этом примере для вывода сегментов использовался не один порт, а набор пинов 0, 1, 8, 9, 10, 11, 12. Использовать целый порт значительно проще, но не всегда возможно.  Кроме того, выводимое значение было указано явно и разбито по разрядам вручную. Подпрограмму разбивки по разрядам я приведу в другом посте.

Результат работы программы:


Комментариев нет:

Отправить комментарий