Программа генерации кода для схем с семисегментными индикаторами и микроконтроллерами

На днях в очередной раз столкнувшись с нестандартной схемой включения выводов семисегментного индикатора на порт микроконтроллера понял, что мне уже не хочется вручную считать все требуемые мне коды. Кроме того, из опыта знаю, что потом хоть одна (а часто полдесятка, если не больше) ошибок будет, и их придется потом исправлять. И хотя может быть мне больше и не понадобится это считать, но терпению моему пришел конец. В результате получилась программа, которую давно уж хотел написать, но все никак руки не доходили :)

Программа генерации кода для схем с семисегментными индикаторами

Программа предназначена для автоматической генерации части кода для вывода сигналов на порт микроконтроллера, для управления семисегментными индикаторами. Иногда по некоторым причинам (чтобы упростить разводку платы) выводы семисегментного индикатора не обязательно будут идти по порядку (т.е. abcdefgh не обязательно попадут на PORT7-0).
Программа позволяет сгенерировать «распиновку» портов микроконтроллера на любую комбинацию выводов семисегментного индикатора, для последующего использования в программе микроконтроллера.

Пример использования (для CodeVisionAVR)

Вот тестовая схема в Proteus. Разводка на индикатор бессмысленная, но сейчас это неважно.Счетверенный индикатор с общими анодами. Аноды разрядов подключены на PORTD.3-6, катоды символов подключены на PORTB.7-0 в порядке  bhgdcfea.
Вводим эту последовательность — либо пользуемся панелью «Распиновка МК» либо сразу в текстовое поле под этой панелью.Если текстовое поле красное — значит у вас на один вывод МК — два (три) символа индикатора. (Я вообще предпочитаю сразу вводить готовый код (aefdchbg) — а эту панель сделал… сам не знаю зачем :) )
Если кроме цифр еще надо какие-то спецсимволы — то пользуясь визуальным отображением индикатора записываем его код в виде adef (это символ С, для примера) в любое из 11 нижних доступных для изменения текстовых полей.
Еще нужно установить режим ОА (общий анод). И нажать кнопку генерации кода.
Программа нам выдаст что-то вроде этого:

0b00000101, //0
0b11110101, //1
0b00101100, //2
0b01100100, //3
0b11010100, //4
0b01000110, //5
0b00000110, //6
0b01110101, //7
0b00000100, //8
0b01000100, //9
0b11111111, //blank
0b11111110, //-
0b00010100, //A
0b10000110, //b
0b00001111, //c
0b10100100, //d
0b00001110, //e
0b00011110, //f
0b10001111, //L
0b00011111, //Г
0b10010100, //Н

лишнее убираем, и в начале своей программы объявляем массив данных (я взял всего первых 12 строк):

char DigCode[12] = {
0b00000101, //0
0b11110101, //1
0b00101100, //2
0b01100100, //3
0b11010100, //4
0b01000110, //5
0b00000110, //6
0b01110101, //7
0b00000100, //8
0b01000100, //9
0b11111111, //blank
0b11111110, //-
};

Потом остается только выводить числа в разрядах — просто устанавливая состояние ножек порта В. (delay_time — время вывода одного символа при динамической индикации. Например, 500мкс). Вот кусок кода. Его можно, например записать в бесконечный цикл главной программы. Либо оформить как отдельную функцию… но это уж сами :)

PORTB = DigCode[Digit[1]];
PORTD.3 = 1;
delay_us(delay_time);
PORTD.3 = 0;

PORTB = DigCode[Digit[2]];
PORTD.4 = 1;
delay_us(delay_time);
PORTD.4 = 0;

PORTB = DigCode[Digit[3]];
PORTD.5 = 1;
delay_us(delay_time);
PORTD.5 = 0;

PORTB = DigCode[Digit[4]];
PORTD.6 = 1;
delay_us(delay_time);
PORTD.6 = 0;

В результате получаем вот такое:

Для тех, кто разбирается в Proteus-е — не обращайте внимание на возможные несоответствие состояний портов и отображаемого символа — скриншоты из этой анимации могли делаться в тот момент, в который происходила динамическая индикация других разрядов.

Саму программу можно скачать вот здесь.

Пожелания, замечания, ругательства ( :) ) и сообщения о возможных ошибках (за которые прошу прощения заранее :) ) — можно оставлять здесь..


Программа генерации кода для схем с семисегментными индикаторами и микроконтроллерами: 10 комментариев

  1. Спасибо!
    Очень полезная будет!
    Только к сожалению на буржуйской Винде русский шрифт не отображается. каракули.

  2. Спасибо за программку! Очень помогла,а то до этого приходилось на тетрадном листике строить таблицы символов))

  3. Здравствуйте!Если программа написана на Delphi ,вы можете мне показать исходник? Я новичок в Delphi и по структуре вашей программы хочу написать свою.Заранее спасибо.

  4. Здравствуйте. У меня для зажигания индикаторов используются и порт( a ) и порт ( b ) .Как тут быть?

    • Я в таких случаях делал вот так (разберетесь сами что к чему?)

      unsigned char byCharB[10] = {
      // xx xx
      0b01000000, //0
      0b01001100, //1
      0b10001000, //2
      0b00001000, //3
      0b00000100, //4
      0b00000000, //5
      0b00000000, //6
      0b01001000, //7
      0b00000000, //8
      0b00000000 //9
      };
      unsigned char byCharD[10] = {
      // zzz z
      0b00100000, //0
      0b11100000, //1
      0b00100000, //2
      0b10100000, //3
      0b11100000, //4
      0b10100100, //5
      0b00100100, //6
      0b11100000, //7
      0b00100000, //8
      0b10100000 //9
      };

      // таблица соотвествия семисегментника и портов
      //a B2
      //b D2
      //c B7
      //d D6
      //e D7
      //f B3
      //g B6
      //h D5
      //1 B1
      //2 B0
      //3 D3

      void ShowDisplayData(int value)
      {
      PORTB &= 0b00110011; //обнуляем нужные пины порта
      PORTB |= byCharB[value/100]&(~0b00110011); //устанавливаем пины в нужные значения
      PORTD &= 0b00011011; //обнуляем нужные пины порта
      PORTD |= byCharD[value/100]&(~0b00011011); //устанавливаем пины в нужные значения
      PORTD.5=0;
      PORTB.1 = 1;
      delay_us(LED_delay);
      PORTB.1 = 0;

      PORTB &= 0b00110011; //обнуляем нужные пины порта
      PORTB |= byCharB[(value%100)/10]&(~0b00110011); //устанавливаем пины в нужные значения
      PORTD &= 0b00011011; //обнуляем нужные пины порта
      PORTD |= byCharD[(value%100)/10]&(~0b00011011); //устанавливаем пины в нужные значения
      PORTB.0 = 1;
      delay_us(LED_delay);
      PORTB.0 = 0;

      PORTB &= 0b00110011; //обнуляем нужные пины порта
      PORTB |= byCharB[value%10]&(~0b00110011); //устанавливаем пины в нужные значения
      PORTD &= 0b00011011; //обнуляем нужные пины порта
      PORTD |= byCharD[value%10]&(~0b00011011); //устанавливаем пины в нужные значения
      PORTD.3 = 1;
      delay_us(LED_delay);
      PORTD.3 = 0;
      };

      Т.е. работал сначала с одним портом (обнуляя, либо устанавливая только нужные биты), а потом с другим.
      Таблицу соотвествий придется, конечно, практически вручную писать. Ну или сделать программой коды для одного порта (не обращая внимания на неиспользуемые пины), а потом для другого.

  5. Классно !…. нечего сказать … спасибо!
    P.S. Может чего не понимаю с протеусом но при установке транзисторов PNP
    ( схема ОА) «каша» получается . Понимаю что все элементарно но с этими инверсиями портов просто морока … мысль — добавить вариант с транзисторами на разрядах… (если это поможет таким самоучкам как я…)

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>