0

Вывод на семисегментный индикатор

Популярное

  • Устройство и программирование микроконтроллеров AVR для начинающих – 143
  • Трехканальный термостат, терморегулятор, таймер на ATmega8 – 70
  • Двухканальный термостат, терморегулятор на ATmega8 – 67

Семисегментный индикатор: программирование работы

Перевод двоичного кода десятичного числа в код семисегментного индикатора
Программирование одноразрядного семисегментного индикатора

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

Перевод двоичного кода десятичного числа в код семисегментного индикатора

Давайте еще раз посмотрим на схему подключения семисегментного индикатора к микроконтроллеру:

На этой схеме выводы порта PB0…..PB7 подключены к выводам индикатора в определенной последовательности. Выводу PB0 соответствует сегмент «А» и далее соответственно по порядковому номеру вывода порта и по алфавиту выводов индикатора, при этом десятичная точка «dp» подсоединена к выводу порта PB7 . Сейчас и далее мы будем рассматривать схемы подключения для индикаторов с общим катодом, а при необходимости я буду вставлять дополнения для индикатора с общим анодом.

Для того, чтобы высветить определенную цифру на индикаторе, необходимо на соответствующих выводах порта микроконтроллера установить логическую единицу

На рисунке выше, черные цифры от 0 до 7 — выводы порта, зеленные латинские буквы — выводы светодиодного индикатора, красные нули — логические уровни на выходах порта (в данном случае логический уровень «0»). Для того, чтобы, к примеру, высветить на индикаторе цифру «4» и зажечь десятичную точку нам необходимо подать логическую 1 на выводы индикатора B, C, F, G и dp, что соответствует подачи логической единицы на выводы порта 1,2,5,6 и 7:

Поэтому, первое что нам необходимо сделать, это определить соответствие каждой десятичной цифре двоичного числа, которое надо выдавать на выход порта микроконтроллера для зажигания соответствующих сегментов индикатора.
Для «четверки» мы уже определили такую комбинацию = 1110 0110, что соответствует шестнадцатиричному числу 66h, определяем и для остальных цифр:

Операция, которую мы проделали, называется переводом двоичного кода десятичного числа в код семисегментного индикатора .

Данная таблица дана для семисегментных индикаторов с общим катодом (сегмент индикатора зажигается логическим уровнем «1»). Для индикаторов с общим анодом (сегмент индикатора зажигается логическим уровнем «0») двоичные коды необходимо проинвертировать (поменять 0 на 1, и наоборот) и заново вычислить соответствующие значения в шестнадцатиричной системе.

Программирование одноразрядного семисегментного индикатора

Использование в конструкции одноразрядного индикатора может потребоваться в разных случаях. К примеру, собираем кодовый замок и есть необходимость высвечивать цифру соответствующую нажатой кнопки, или в охранной сигнализации высвечивать номер сработавшего датчика. Так что сфера применения одноразрядных индикаторов приличная.
Организацию вывода цифр на одноразрядный индикатор мы оформим в виде подпрограммы: «Вывод информации на одноразрядный семисегментный светодиодный индикатор» , так, чтобы затем эту подпрограмму с минимальными изменениями можно было использовать в любой программе.

Алгоритм подпрограммы:

1. Инициализация индикатора (подпрограмма)
— настройка порта, к которому подключен индикатор на вывод информации
— запись кодов семисегментного индикатора, соответствующих десятичным цифрам в определенные ячейки памяти
Данная подпрограмма должна вызываться отдельно из основной программы
2. Вход в основную подпрограмму
3. Основная часть
— считываем текущую цифру
— определяем какой код семисегментного индикатора соответствует текущей десятичной цифре
— записываем определенный код индикатора в порт микроконтроллера
4. Выход из подпрограммы

Для оформления программы в виде подпрограммы нам необходимо проделать ряд действий:
1. Присваиваем имя подпрограмме инициализации индикатора — Ini_Indiкator_1 (к примеру)
2. Присваиваем имя основной подпрограмме — Indicator_1
3. Присваиваем имена переменным SRAM в которых будут храниться коды семисегментного индикатора, к примеру:
D0 (для цифры 0, и так далее), D1, D2, D3, D4, D5, D6, D7, D8, D9
— присваиваем имя переменной в которой будет хранится адрес ячейки памяти (D0) с кодом первой цифры (0) — D0_9
4. Присваиваем имя переменной, в которой будет хранится текущая цифра, которую необходимо вывести на индикатор. В эту переменную основная программа будет записывать вычисленные данные (цифры), которые мы выводим на индикатор — Data (к примеру).

Вот как, к примеру, в Algorithm Builder (остальные примеры тоже для этой программы), объявляются имена переменных в памяти программ (ОЗУ, SRAM):

В графе «Name» перечислены все имена переменных. В графе «Adress» запись «@D0_9» означает, что в переменной D0_9 хранится адрес первой переменной (D0)

Подпрограмма инициализации индикатора (подпрограмма вызывается из основной программы до обращения к подпрограмме вывода информации на индикатор):

А теперь давайте посмотрим основную часть программы и расшифруем ее:

Основная программа записала в назначенную нами переменную Data текущую цифру (для примера — цифра 6) и для вывода ее на индикатор вызвала подпрограмму Indikator_1.

Читайте также:  Зачем нужны платы расширения

Работа подпрограммы:
— Содержимое переменной Data записывается в рабочий регистр R20 , теперь в регистре число 6 (рабочий регистр может быть любой)
— Допустим, первая переменная с кодом цифры у нас находится в ячейки памяти по адресу 100 . На самом деле мы не знаем адреса ячеек памяти где хранятся значения D0…D9 , но они точно следуют друг за другом. Поэтому была назначена переменная D0_9 , в которой, как мы назначили, хранится адрес ячейки памяти D0 (в данный момент адрес = 100 ).
— Следующей командой:
@D0_9 —> Y мы загружаем в двойной регистр Y адрес переменной D0 и получаем, что в регистре Y записалось число — 100 .
— Следующей командой:
Y + R20 мы складываем число 100 с числом 6 , результат = 106 при этом сохраняется в двойном регистре Y .
— Следующей командой:
[Y] —> R20 мы записываем содержимое ячейки памяти, расположенной по адресу, который записан в двойном регистре Y (106) , а по этому адресу у нас расположена ячейка памяти переменной D6 . Теперь в рабочем регистре R20 записано число 7Dhкод семисегментного индикатора для вывода цифры 6 .
— Следующей командой:
R20 —> PortB мы выводим содержимое R20 в порт PBвысвечиваем цифру 6
— Возвращаемся из подпрограммы

Надеюсь, что материал изложен доступно, если что-то не понятно, спрашивайте.

(15 голосов, оценка: 4,93 из 5)

Популярное

  • Устройство и программирование микроконтроллеров AVR для начинающих – 143
  • Трехканальный термостат, терморегулятор, таймер на ATmega8 – 70
  • Двухканальный термостат, терморегулятор на ATmega8 – 67

Семисегментный индикатор: программирование работы

Перевод двоичного кода десятичного числа в код семисегментного индикатора
Программирование одноразрядного семисегментного индикатора

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

Перевод двоичного кода десятичного числа в код семисегментного индикатора

Давайте еще раз посмотрим на схему подключения семисегментного индикатора к микроконтроллеру:

На этой схеме выводы порта PB0…..PB7 подключены к выводам индикатора в определенной последовательности. Выводу PB0 соответствует сегмент «А» и далее соответственно по порядковому номеру вывода порта и по алфавиту выводов индикатора, при этом десятичная точка «dp» подсоединена к выводу порта PB7 . Сейчас и далее мы будем рассматривать схемы подключения для индикаторов с общим катодом, а при необходимости я буду вставлять дополнения для индикатора с общим анодом.

Для того, чтобы высветить определенную цифру на индикаторе, необходимо на соответствующих выводах порта микроконтроллера установить логическую единицу

На рисунке выше, черные цифры от 0 до 7 — выводы порта, зеленные латинские буквы — выводы светодиодного индикатора, красные нули — логические уровни на выходах порта (в данном случае логический уровень «0»). Для того, чтобы, к примеру, высветить на индикаторе цифру «4» и зажечь десятичную точку нам необходимо подать логическую 1 на выводы индикатора B, C, F, G и dp, что соответствует подачи логической единицы на выводы порта 1,2,5,6 и 7:

Поэтому, первое что нам необходимо сделать, это определить соответствие каждой десятичной цифре двоичного числа, которое надо выдавать на выход порта микроконтроллера для зажигания соответствующих сегментов индикатора.
Для «четверки» мы уже определили такую комбинацию = 1110 0110, что соответствует шестнадцатиричному числу 66h, определяем и для остальных цифр:

Операция, которую мы проделали, называется переводом двоичного кода десятичного числа в код семисегментного индикатора .

Данная таблица дана для семисегментных индикаторов с общим катодом (сегмент индикатора зажигается логическим уровнем «1»). Для индикаторов с общим анодом (сегмент индикатора зажигается логическим уровнем «0») двоичные коды необходимо проинвертировать (поменять 0 на 1, и наоборот) и заново вычислить соответствующие значения в шестнадцатиричной системе.

Программирование одноразрядного семисегментного индикатора

Использование в конструкции одноразрядного индикатора может потребоваться в разных случаях. К примеру, собираем кодовый замок и есть необходимость высвечивать цифру соответствующую нажатой кнопки, или в охранной сигнализации высвечивать номер сработавшего датчика. Так что сфера применения одноразрядных индикаторов приличная.
Организацию вывода цифр на одноразрядный индикатор мы оформим в виде подпрограммы: «Вывод информации на одноразрядный семисегментный светодиодный индикатор» , так, чтобы затем эту подпрограмму с минимальными изменениями можно было использовать в любой программе.

Алгоритм подпрограммы:

1. Инициализация индикатора (подпрограмма)
— настройка порта, к которому подключен индикатор на вывод информации
— запись кодов семисегментного индикатора, соответствующих десятичным цифрам в определенные ячейки памяти
Данная подпрограмма должна вызываться отдельно из основной программы
2. Вход в основную подпрограмму
3. Основная часть
— считываем текущую цифру
— определяем какой код семисегментного индикатора соответствует текущей десятичной цифре
— записываем определенный код индикатора в порт микроконтроллера
4. Выход из подпрограммы

Для оформления программы в виде подпрограммы нам необходимо проделать ряд действий:
1. Присваиваем имя подпрограмме инициализации индикатора — Ini_Indiкator_1 (к примеру)
2. Присваиваем имя основной подпрограмме — Indicator_1
3. Присваиваем имена переменным SRAM в которых будут храниться коды семисегментного индикатора, к примеру:
D0 (для цифры 0, и так далее), D1, D2, D3, D4, D5, D6, D7, D8, D9
— присваиваем имя переменной в которой будет хранится адрес ячейки памяти (D0) с кодом первой цифры (0) — D0_9
4. Присваиваем имя переменной, в которой будет хранится текущая цифра, которую необходимо вывести на индикатор. В эту переменную основная программа будет записывать вычисленные данные (цифры), которые мы выводим на индикатор — Data (к примеру).

Читайте также:  Бесплатные игры на прохождение в steam

Вот как, к примеру, в Algorithm Builder (остальные примеры тоже для этой программы), объявляются имена переменных в памяти программ (ОЗУ, SRAM):

В графе «Name» перечислены все имена переменных. В графе «Adress» запись «@D0_9» означает, что в переменной D0_9 хранится адрес первой переменной (D0)

Подпрограмма инициализации индикатора (подпрограмма вызывается из основной программы до обращения к подпрограмме вывода информации на индикатор):

А теперь давайте посмотрим основную часть программы и расшифруем ее:

Основная программа записала в назначенную нами переменную Data текущую цифру (для примера — цифра 6) и для вывода ее на индикатор вызвала подпрограмму Indikator_1.

Работа подпрограммы:
— Содержимое переменной Data записывается в рабочий регистр R20 , теперь в регистре число 6 (рабочий регистр может быть любой)
— Допустим, первая переменная с кодом цифры у нас находится в ячейки памяти по адресу 100 . На самом деле мы не знаем адреса ячеек памяти где хранятся значения D0…D9 , но они точно следуют друг за другом. Поэтому была назначена переменная D0_9 , в которой, как мы назначили, хранится адрес ячейки памяти D0 (в данный момент адрес = 100 ).
— Следующей командой:
@D0_9 —> Y мы загружаем в двойной регистр Y адрес переменной D0 и получаем, что в регистре Y записалось число — 100 .
— Следующей командой:
Y + R20 мы складываем число 100 с числом 6 , результат = 106 при этом сохраняется в двойном регистре Y .
— Следующей командой:
[Y] —> R20 мы записываем содержимое ячейки памяти, расположенной по адресу, который записан в двойном регистре Y (106) , а по этому адресу у нас расположена ячейка памяти переменной D6 . Теперь в рабочем регистре R20 записано число 7Dhкод семисегментного индикатора для вывода цифры 6 .
— Следующей командой:
R20 —> PortB мы выводим содержимое R20 в порт PBвысвечиваем цифру 6
— Возвращаемся из подпрограммы

Надеюсь, что материал изложен доступно, если что-то не понятно, спрашивайте.

(15 голосов, оценка: 4,93 из 5)

Семисегментный индикатор ввиду своей красочности часто применяется для отображения информации, например значения температуры, величины напряжения либо тока. В этой статье мы продолжаем изучать программирование микроконтроллеров и уже научимся подключать к микроконтроллеру ATmega8 простейший одноразрядный семисегментный индикатор, и будем отображать на нем цифры.

Давайте начнем все по порядку. Для начала рассмотрим, что собою представляет семисегментный индикатор. Внешне он имеет различные размеры. Главным идентификатором служит высота цифры, которая в справочниках приводится в дюймах. Высота цифры имеет стандартный ряд значений, который приводится в дюймах.

По количеству разрядов различают одно-, двух-, трех-, и четырехразрядные индикаторы. Бывает и более разрядов, но они встречаются довольно редко.

Семисегментный индикатор. Принцип работы семисегментного индикатора

Любой семисегментный индикатор обязательно состоит из семи сегментов. Отсюда и происходит его название. Каждый сегмент – это обычный отдельный светодиод. Мощные семисегментники могут содержать в одном сегменте несколько, как правило, последовательно соединенных светодиодов.

Кроме того в корпусе помимо сегментов находится еще и точка или запятая или другой символ.

С помощью семи сегментов можно изобразить десять цифр: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 и некоторые буквы, как латиницы, так и кириллицы.

Светодиоды всех элементов соединяются одноименными выводпми между собой или анодами, или катодами. Поэтому разделяют семисегментные индикаторы с общим анодом и общим катодом.

Вне зависимости от количества разрядов и размеров цифр каждый сегмент имеет название в виде одной из первых букв английского алфавита: a, b, c, d, e, f, g. Точка обозначается dp.

Для того чтобы засветить один из светодиодов семисегментного индикатора с общим анодом следует на общий вывод (анод) подать «+», а на соответствующий отдельный вывод – «-» источника питания.

Если применяется общий катод, — то наоборот – минус подается на общий, а плюс на отдельный вывод.

Чтобы отобразить на индикаторе цифру или букву следует засветить несколько сегментов. Например, для отображения единицы 1 задействуются сегменты b и c. При отображении восьмерки 8 задействуются все символы от a до g. Пятерка получается из таких символов: a, c, d, f, g.

Как подключить семисегментный индикатор к микроконтроллеру

Теперь рассмотрим, как подключить семисегментный индикатор к микроконтроллеру ATmega8. Подключим его к порту D. Данные порт имеет все восемь бит, что очень удобно сочетается с количеством выводов одноразрядного семисегментного индикатора, у которого их также восемь с учетом вывода для точки.

Схемы подключения с общим анодом ОА и общим катодом ОК аналогичны, только общий вывод подключается соответственно к плюсу или минусу источника питания.

Все светодиоды подключаются к выводам микроконтроллера через отдельные резисторы сопротивлением 220…330 Ом.

Читайте также:  Верхний бар для андроид

Не стоит экономить на резисторах и подключать все элементы через один общий резистор. Поскольку в таком случае с изменением числа задействованных сегментов будет изменяться величина тока, протекающего через них. Поэтому цифра 1 будет светиться ярче, чем 8.

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

Теперь создадим модель в Протеусе и соберем схему на макетной плате. Далее по мере написания кода будем проверять работу микроконтроллера на модели и на реальном устройстве.

Семисегментный индикатор в Proteus находится в категории (Category) Optoelectronics (Оптоэлектроника). Ниже в подкатегории (Sub-category) следует кликнуть по строке 7-Segment Displays. После этого в окне результатов (Results) выбираем одноразрядный семисегментный индикатор 7SEG-MPX1-CC.

Код для микроконтроллера ATmega8

Теперь пишем код. Сначала настраиваем порт D полностью на выход. Для отображения единицы 1 задействуются сегменты b и c, выводы которых подключены к PD1 и PD2. Поэтому соответствующие биты регистр PORTD нужно установить в единицу.

PORTD = 0b00000110; //1

После компиляции кода и прошивки кода результаты мы видим в Proteus и на макетной плате.

Аналогичным образом формируются все цифры.

Давайте сделаем программу более интересной, так, чтобы цифры изменялись в порядке нарастания от нуля до девяти с паузой 0,3 секунды.

#define F_CPU 1000000L

PORTD = 0b00111111; //0

PORTD = 0b00000110; //1

PORTD = 0b01011011; //2

PORTD = 0b01001111; //3

PORTD = 0b01100110; //4

PORTD = 0b01101101; //5

PORTD = 0b01111101; //6

PORTD = 0b00000111; //7

PORTD = 0b01111111; //8

PORTD = 0b01101111; //9

Данный код можно значительно упорядочить и этим мы займемся в последующих статьях по программированию микроконтроллера ATmega8. На этом заканчиваем наше первое знакомство с семисегментными индикаторами.

Еще статьи по данной теме

Тут такая засада.
На Atiny2323 все работает нормально, на Atmega8 семисегментный индикатор постоянно мерцает. Правда схема такая же как и на Atiny2323 т.е. без кварца. Не подскажите в чем дело?

Дело в том, что по-умолчанию частота работы встроенного генератора (RC-цепочки) Atiny2323 4 МГц, а ATmega8 — 1 МГц, поэтому на меге заметна частота мерцания.

Дмитрий,
Поизучал даташит, правильно понимаю что для установки 4Мгц нужно установить CKSEL3..0 в 0011?

Дмитрий, и еще вопрос в догонку.
Какие кварцы (частоты, типы, кол-во) стоит прикупить для изучения микроконтроллеров?

Сначало зажги светодиод,потом помигай им,потом подключи кнупку,чтоб программа заработал когда нажал кнопку и т.д.кварц для этого не нужен.От простого к сложному.

Автору большое спасибо. После видео уроков на ютубе появился интерес к МК.
Большая просьба автору. Вы собирались сделать материал по динамической индикации —
семи-сегментного индикатора. Возможно, вы бы, могли бы сделать материал, сегменты индикатора к разным портам. Например к двум портам МК.

Andrei, никто не хочет за это дерьмо с разными портами браться, я сам долго искал, у всех подключение к одному порту (так головняка меньше). То что я смог переварить взято с радиокота https://radiokot.ru/forum/viewtopic.php?f=57&t=131489. Да, через анус, но работает.
код:
/*
* M48_dinamind_radiokot.c
*
* Created: 28.11.2018 10:37:52
* Author: Left
*/

#define F_CPU 1000000UL
#include
#include
#include
//—————————————————————
#define SetBit(reg, bit) reg |= (1 29.11.2018 Ответить

Относительно просто динамическую индикацию подключать, применяя оператор switch case.

Да, просто, но как быть с сегментами на разных портах? да еще и так чтоб начинающий смог понять. То что что я видел, с кучей подключаемых библиотек, где хрен разберешь последовательность и что откуда берется, выглядит (как для начинающего) уж очень муторно. Если у Вас будет свободное время, сделайте урок по динамической индикации с сегментами на разных портах, это будет единственное видео на ютубе и единственный урок с комментариями (если будет конечно;) )

Это нужно быть совсем нубом в прерывании тратить время на перебор 13ти кейсов в свитче.
Все делается одним сдвигом N влево в зависимости от размера кейса и джамп на кейс по получившимся смещению после сдвига N. 2 инструкции чтобы попасть в кейс. Но для этого нужно уметь на ассемблере написать.
Еще гасится весь дисплей, потом куча кода проходит до момента отображения сегмента. Все это время дисплей не горит. Лажа полная, а не пример.
У меня даже на убогом нувотоне, где одна инструкция по 3 такта,а не один как у avr обновление дисплея занимает 4.7микросекунды. То есть я могу его обновлять с частотой аж 200 кГц. И каждая нога тоже отдельно дергается, а не просто в порт кинуть. И между моментом когда все гасится и отображается новый сегмент вообще нет пробела, следующей же ассемблерной инструкцией начинает зажигаться.
Так что хочешь сделать быстро и качественно динамическую индикацию без ассемблера не обойтись.

Что-то не весь код с копировался, напиши почту я сброшу.

admin

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

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