Меню

Ток при динамической индикации

Динамическая индикация

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

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

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

Рисунок 1. Структурная схема динамической индикации

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

В результате, когда коммутатор подает двоично-десятичный код с входа A на входы семисегментного дешифратора, то этот код отображается на индикаторе HL1. Когда коммутатор подает на входы семисегментного дешифратора двоично-десятичный код с входа B, то этот код отображается на индикаторе HL2, и так далее, по циклу.

Скорость обновления информации в рассмотренной схеме будет в четыре раза меньше частоты генератора. То есть для того, чтобы получить частоту мерцания индикаторов 100 Гц, требуется частота генератора 400 Гц.

Во сколько же раз мы в результате уменьшили количество соединительных проводников? Это зависит от того, где мы проведем сечение схемы. Если мы на плате индикации оставим только индикаторы, то для их работы потребуется 7 информационных сигналов для сегментов и четыре коммутирующих сигнала. Всего 11 проводников. В статической схеме индикации нам потребовалось бы 7×4=28 проводников. Как видим, выигрыш налицо. При реализации 8-ми разрядного блока индикации выигрыш будет еще больше.

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

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

Как уже упоминалось ранее, для нормальной работы светодиода требуется ток от 3 до 10 мА. Зададимся минимальным током светодиода 3 мА. Однако при импульсном режиме работы яркость свечения индикатора падает в N раз, где коэффициент N равен скважности импульсов тока, подаваемых на этот индикатор.

Если мы собираемся сохранить ту же яркость свечения, то требуется увеличить величину импульсного тока, протекающего через сегмент, в N раз. Для восьмиразрядного индикатора коэффициент N равен восьми. Пусть первоначально мы выбрали статический ток через светодиод, равный 3 мА. Тогда для сохранения той же яркости свечения светодиода в восьмиразрядном индикаторе потребуется импульсный ток:

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

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

Как вам такой ток?! В радиолюбительских схемах я часто встречаю решения, где коммутирующий ток берется непосредственно с выхода дешифратора, который не может выдать ток больше 20 мА, и задаю себе вопрос — а где смотреть такой индикатор? В полной темноте? Получается «прибор ночного видения», то есть прибор, показания которого видны только в полной темноте.

А теперь давайте рассмотрим принципиальную схему полученного блока индикации. Она приведена на рисунке 3.

Рисунок 3. Принципиальная схема блока динамической индикации

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

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

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

Итак, применение динамической индикации позволяет минимизировать количество соединительных проводов между цифровым устройством и индикатором, но является при этом мощным источником помех, поэтому ее применение в радиоприемных устройствах нежелательно.

Если по каким-либо причинам, например, необходимость применения матричных индикаторов, приходится использовать динамическую индикацию, то нужно принять все меры по подавлению помех.

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

Вместе со статьей «Динамическая индикация» читают:

Виды индикаторов Индикаторы предназначены для отображения различных видов информации для человека. Простейший вид информации — это.
https://digteh.ru/digital/Indic.php

Газоразрядные индикаторы Газоразрядные индикаторы используются как для индикации битовой информации, так и для отображения десятичной информации. При построении десятичных индикаторов катод.
https://digteh.ru/digital/GazIndic/

Светодиодные индикаторы В настоящее время практически везде для отображения двоичной информации используются светодиоды. Это обусловлено тем.
https://digteh.ru/digital/LED.php

Жидкокристаллические индикаторыПринципы работы жидкокристаллических индикаторов. Режимы работы жидкокристаллических индикаторов. Формирование цветного изображения.
https://digteh.ru/digital/LCD.php

Автор Микушин А. В. All rights reserved. 2001 . 2020

Предыдущие версии сайта:
http://neic.nsk.su/

Об авторе:
к.т.н., доц., Александр Владимирович Микушин

Кандидат технических наук, доцент кафедры САПР СибГУТИ. Выпускник факультета радиосвязи и радиовещания (1982) Новосибирского электротехнического института связи (НЭИС).

А.В.Микушин длительное время проработал ведущим инженером в научно исследовательском секторе НЭИС, конструкторско технологическом центре «Сигнал», Научно производственной фирме «Булат». В процессе этой деятельности он внёс вклад в разработку систем радионавигации, радиосвязи и транкинговой связи.

Научные исследования внедрены в аппаратуре радинавигационной системы Loran-C, комплексов мобильной и транкинговой связи «Сигнал-201», авиационной системы передачи данных «Орлан-СТД», отечественном развитии системы SmarTrunkII и радиостанций специального назначения.

Источник

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

Программирование микроконтроллеров Курсы

Динамическая индикация широко применяется для отображения различной информации, например температуры, напряжения, времени или просто количества срабатывания каких-либо устройств или датчиков. Динамическая индикация на базе семисегментных индикаторов отлично согласуется в совместной работе с микроконтроллерами. Однако в литературе по программированию микроконтроллеров AVR данный вопрос рассмотрен очень поверхностно и далеко не в каждой книге, посвященной соответствующей тематике. Поэтому более подробно рассмотрим, как подключить семисегментный индикатор с динамической индикацией к микроконтроллеру, в данном случае – к ATmega8, но аналогия сохраняется для МК AVR любой серии.

Читайте также:  По закону ома для полной цепи сила тока измеряется в амперах равна где эдс источника

По количеству разрядов (цифр) динамические семисегментные индикаторы бывают одноразрядные, двухразрядные, трехразрядные, четырехразрядные и очень редко – шестиразрядные. Основное внимание мы уделим четырехразрядным семисегментным индикаторам, как наиболее применяемому типу динамической индикации. Изготовляются они с общим анодом и общим катодом. Схемы соединения светодиодов отдельных сегментов представлены на рисунках.

4-х разрядный семисегментный индикатор с общим катодом обозначение выводов схема

Как видно из рисунков, каждый разряд, называемый digit, имеет свой отдельный общий в пределах разряда вывод. Поскольку рассматривается 4-х разрядная динамическая индикация, то таких выводы четыре – digit1, digit2, digit3, digit4.

4-х разрядный семисегментный индикатор с общим анодом обозначение выводов схема

Распиновка выводов 4-х разрядного семисегментного индикатора приведена на рисунке ниже. В данном случае показан вид сверху, то есть индикатор не нужно переворачивать вверх ногами.

4 разрядный семисегментный индикатор обозначение выводов распиновка

Как работает динамическая индикация

Теперь рассмотрим, как работает динамическая индикация с общим катодом. Например, нам необходимо отобразить число 1987. Для этого следует в первый момент времени подать высокий потенциал на аноды сегментов, образующих единицу – b и c, а на общий катод первого разряда подать низкий потенциал. Общие катоды оставшихся трех разрядов – digit2, digit3 и digit4 остаются не подключенными.

Динамическая индикация Принцип работы

Во второй момент времени получают питания сегменты, образующие цифру 9, общий катод второго разряда подключается к минусу, а digit1 теряет питание; digit2, digit3, как и раннее – остаются не подключенными.

В третий момент времени засвечивается цифра 8 на третьем индикаторе, а остальные индикаторы гаснут.

В четвертый момент времени получает питание последний индикатор и отображается цифра 7.

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

Схема подключения динамической индикации к микроконтроллеру ATmega8

Сегменты динамической индикации будем подключать через токоограничивающие резисторы номиналом 330 Ом к выводам порта D микроконтроллера ATmega8. Выводы, отвечающие digit1, digit2, digit3, digit4 подсоединим через транзисторы n-p-n тип, например BC547 или 2n2222 к выводам порта B.

Динамическая индикация с общим катодом Схема подключения к микроконтроллеру AVR ATmega8

Если применять динамическую индикацию с общим анодом, тогда понадобятся биполярные транзисторы p-n-p типа, например BC557, эмиттеры которых нужно подсоединить к плюсу «+» источника питания, а коллекторы – к минусу «-» также через подтягивающий резистор 10 кОм. Принцип работы и подробные расчет транзисторного ключа описан ранее.

Динамическая индикация с общим анодом Схема подключения к микроконтроллеру AVR ATmega8

Алгоритм написания кода для подключения динамической индикации

Для большей конкретизации действий будем применять 4-х разрядный семисегментный индикатор с общим катодом. Первым делом следует создать массив цифр от 0 до 9. Этому мы уже научились ранее, вот здесь. Далее необходимо разбить 4-х значное число на четыре отдельных цифры. Например, число 1987 нужно разбить на 1, 9, 8 и 7. Затем единицу нужно отобразить в первом разряде индикатора, девятку – во втором, восьмерку – в третьем и семерку – в четвертом.

Среди многих алгоритмов разбивки многозначного числа на отдельные числа мы воспользуемся операциями деления и остатком от деления. Рассмотрим пример:

В языке С при использовании целочисленного типа данных int при выполнении деления все десятые, сотые и т. д., то есть все числа меньше единицы отбрасываются. Остаются только целые числа. Математическое округление здесь не работает, то есть 1,9 в данном случае будет 1, а не 2.

Команда «остаток от деления» обозначается знаком процента «%». Данная команда отбрасывает все целые числа и оставляет остальную часть числа. Например, 1987%1000 → 987; 1987%100 → 87; 1987%10 → 7.

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

#define F_CPU 1000000L

#include

#define CHISLO PORTD

#define RAZRIAD PORTB

unsigned int razr1 = 0, razr2 = 0, razr3 = 0, razr4 = 0;

unsigned int chisla [10] = <

// числа от 0 до 10

0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f

void vse_chislo (unsigned int rabivka_chisla)

razr1 = rabivka_chisla/1000; // тысячи

razr2 = rabivka_chisla%1000/100; // сотни

razr3 = rabivka_chisla%100/10; // десятки

razr4 = rabivka_chisla%10; // единицы

int main(void)

DDRB = 0b00001111;

DDRD = 0b11111111;

RAZRIAD = 0b00000001; // изначально 1-й разряд

CHISLO = 0x3f; // число 0

while (1)

vse_chislo(1987); // отображаемое число

RAZRIAD = 0b00000001; // включаем 1-й разряд, остальные выключаем

CHISLO = chisla [razr1]; // отображаем 1-ю цифру

_delay_ms(3);

RAZRIAD = 0b00000010; // включаем 2-й разряд, остальные выключаем

CHISLO = chisla [razr2]; // отображаем 2-ю цифру

_delay_ms(3);

RAZRIAD = 0b00000100; // включаем 3-й разряд, остальные выключаем

CHISLO = chisla [razr3]; // отображаем 3-ю цифру

_delay_ms(3);

RAZRIAD = 0b00001000; // включаем 4-й разряд, остальные выключаем

CHISLO = chisla [razr4]; // отображаем 4-ю цифру

_delay_ms(3);

Улучшаем программу для работы динамической индикации

Приведенный выше алгоритм является в большей степени обучающий, поэтому несколько упрощенный, но он также имеет место в программах, не выполняющих каких-либо быстрых расчетов в режиме реального времени. Единственным недостатком данного алгоритма является применение задержек, негативное влияние которых была рассмотрено ранее. Чтобы избавится от применения задержек можно применять прерывания от таймер-счетчиков. В ниже представленном коде задержки формируются с помощью нулевого таймер-счетчика и вызова прерывания по переполнению этого счетчика.

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

Для того, чтобы при каждом прерывании числа отображались последовательно в каждом разряде индикатора, добавлена переменная bc547, которая увеличивается на единицу при последующем вызове прерывания ISR (TIMER0_OVF_vect). Затем выполняется проверка значения переменной bc547 и получает питания соответствующий разряд. Когда bc547 становится больше четырех, происходит сброс в единицу.

Источник

Введение

Для отображения цифровой информации в системах на базе микроконтроллеров используются светодиодные семисегментные индикаторы. Они просты в управлении, имеет высокую яркость, широкий диапазон рабочих температур и низкую стоимость. К недостаткам светодиодных индикаторов относятся – высокое энергопотребление, отсутствие управляющего контроллера и скудные возможности по выводу буквенной информации.
Светодиодный семисегментный индикатор представляет собой группу светодиодов расположенных в определенном порядке и объединенных конструктивно. Зажигая одновременно несколько светодиодов можно формировать на индикаторе символы цифр. Индикаторы различаются по типу соединения светодиодов – общий анод, общий катод, по количеству отображаемых разрядов – однораразрядные, двух разрядные и т.д. и по цвету – красные, зеленые, желтые и т.д.

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

Читайте также:  Пусковой ток предельные значения

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

Эксперименты с семисегментным индикатором

Чтобы зажечь на индикаторе какую-то цифру нужно настроить порты, к которым подключен индикатор, в режим выхода, “открыть” транзистор (в данном случае подать на базу “единицу”) и установить в порту микроконтроллера её код.
В зависимости от того, куда подключены сегменты индикатора – коды могут быть разные. Для нашего случая коды цифр будут выглядеть так.

unsigned char number[] =
<
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
>;

Используя десятичные цифры от 0 до 9 в качестве индекса массива, легко выводить в порт нужные коды.

Пример 1. Вывод цифр от 0 до 9
#include
#include

unsigned char number[] =
<
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
>;

unsigned char count = 0;
int main( void )
<
//порт, к которому подкл. сегменты
PORTB = 0xff;
DDRB = 0xff;

//вывод, к которому подкл. катод
PORTD |= (1 while (1) <
PORTB = number[count];
count++;
if (count == 10) count = 0;
__delay_cycles (8000000);
>
return 0;
>
Эта программа каждую секунду выводит значение переменной count на семисегментный индикатор. Индикация в данном случае — статическая.

Идем дальше – вывод двух цифр. Настройка портов и коды цифр остаются без изменений, но теперь нам нужно добавить кусок кода, который будет зажигать разряды индикатора по очереди. Частота смены разрядов должна быть достаточно высокой, чтобы свечение индикатора воспринималось без мерцания.

Пример2. Вывод цифр от 0 до 99
#include
#include

unsigned char number[] =
<
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
>;

unsigned char
count = 0;

//числа для вывода на индикатор
unsigned char data1 = 2;
unsigned char data2 = 5;

int main( void )
<
//порт, к которому подкл. сегменты
PORTB = 0xff;
DDRB = 0xff;

//порт, к которому подкл. катод
PORTD = 0;
DDRD = (1 while (1)<

//гасим оба разряда
PORTD &=

((1 //выводим в порт код цифры
//и зажигаем следующий разряд
if (count == 0) <
PORTB = number[data2];
PORTD |= (1 if (count == 1) <
PORTB = number[data1];
PORTD |= (1 if (count == 2) count = 0;

//частота смены разрядов будет 100 Гц при кварце 8МГц
__delay_cycles (800000);
>
return 0;
>
Эта программа просто выводит любое поразрядно заданное число от 0 до 99.
Частота смены разрядов семисегментного индикатора задается с помощью программной задержки __delay_cycles(). Это не самое удачное решение, потому что добавление каких-нибудь других задач в цикл while будет мешать выводу на индикатор. Давайте организуем смену разрядов индикатора с помощью аппаратного таймера/счетчика Т0

Пример3. Вывод цифр от 0 до 99. Смена разрядов выполняется в прерывании таймера
#include
#include

unsigned char number[] =
<
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
>;

//числа для вывода на индикатор
volatile unsigned char data1 = 0;
volatile unsigned char data2 = 0;

int main( void )
<
//порт, к которому подкл. сегменты
PORTB = 0xff;
DDRB = 0xff;

//порт, к которому подкл. катод
PORTD = 0;
DDRD |= (1 //инициализация таймера Т0
//частота прерываний 100Гц при кварце 8МГц
TIMSK = (1 __enable_interrupt ();
while (1) <
//программный счетчик секунд
data1++;
if (data1 == 10) <
data1 = 0;
data2++;
if (data2 == 10) data2 = 0;
>
__delay_cycles (8000000);
>
return 0;
>

//прерывания таймера Т0 — вывод на индикатор
#pragma vector = TIMER0_OVF_vect
__interrupt void Timer0_Ovf( void )
<
static unsigned char count = 0;
TCNT0 = 0xb2;

//гасим оба разряда
PORTD &=

((1 //выводим в порт код цифры
//и зажигаем следующий разряд
if (count == 0) <
PORTB = number[data2];
PORTD |= (1 if (count == 1) <
PORTB = number[data1];
PORTD |= (1 if (count == 2) count = 0;
>
Переменные data1, data2 объявлены с ключевым словом volatile, потому что они используются и в основном коде и в прерывании. В проекте под GCC я забыл поставить его поставить, и компилятор выкинул обе переменные, посчитав их ненужными!

Прерывания таймера происходят параллельно выполнению цикла while. Это позволяет выполнять в цикле какую-нибудь полезную задачу. В данном примере с помощью двух переменных в цикле организован программный счетчик от 0 до 99.
Использовать две восьмиразрядные переменные для организации счетчика от 0 до 99 неудобно и расточительно, ведь такой счетчик можно сделать и на одной переменной типа unsigned char. Хорошо, счетчик мы сделаем, а как вывести его значение на семисегментный индикатор? Нужен код “разбивающий” десятичное число на отдельные разряды и вот как он выглядит:

//программный счетчик
unsigned char counterProg = 35;

//”разбиваем” значение счетчика на отдельные разряды
data1 = counterProg % 10;
data2 = counterProg/10;

data1 = counterProg % 10 – это операция деления по модулю 10 (деление с остатком). Результатом этого выражения будет остаток от деления переменной counterProg на 10, то есть для нашего случая 5.

counterProg/10 – это целочисленное деление на 10. Результатом этого выражения будет число 3.

Таким образом, в переменные data2, data1 будут записаны числа 3 и 5 соответственно, значение счетчика counterProg при этом не изменится.

Пример 4. Вывод цифр от 0 до 99.
Преобразование двоичных чисел в двоично-десятичные (BCD)

#include
#include

unsigned char number[] =
<
0x3f, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
>;

//числа для вывода на индикатор
volatile unsigned char data1 = 0;
volatile unsigned char data2 = 0;

//программный счетчик секунд
unsigned char counterProg = 0;

int main( void )
<
//порт, к которому подкл. сегменты
PORTB = 0xff;
DDRB = 0xff;

//порт, к которому подкл. катод
PORTD = 0;
DDRD |= (1 //инициализация таймера Т0
TIMSK = (1 __enable_interrupt ();
while (1) <
//программный счетчик секунд
counterProg++;
if (counterProg == 100) counterProg = 0;
data1 = counterProg % 10;
data2 = counterProg/10;
__delay_cycles (8000000);
>
return 0;
>

//прерывания таймера Т0 — вывод на индикатор
#pragma vector = TIMER0_OVF_vect
__interrupt void Timer0_Ovf( void )
<
static unsigned char count = 0;
TCNT0 = 0xb2;

//гасим оба разряда
PORTD &=

((1 //выводим код цифры в порт
//и зажигаем следующий разряд
if (count == 0) <
PORTB = number[data2];
PORTD |= (1 if (count == 1) <
PORTB = number[data1];
PORTD |= (1 if (count == 2) count = 0;
>
Следующий этап работы над программой – выделение кода обслуживающего светодиодный семисегментный индикатор в отдельные функции. Какой минимальный набор функций нам необходим? Функция инициализации, функция вывода на индикатор и функция преобразования чисел и записи их в буфер.

Функция инициализации

#define PORT_IND PORTB
#define DDR_IND DDRB
#define PORT_K PORTD
#define DDR_K DDRD
#define KAT1 0
#define KAT2 1

Читайте также:  Обмотки электрических машин переменного тока асинхронные машины

volatile unsigned char data[2];

void IND_Init( void )
<
//порт к которому подкл. сегменты
PORT_IND = 0xff;
DDR_IND = 0xff;

//порт, к которому подкл. катоды
PORT_K &=

((1 //очистка буфера
data[0] = 0;
data[1] = 0;
>

Порты, к которым подключен семисегментный индикатор, определены с помощью директивы #define – в будущем это позволит быстро править код. Вместо двух переменных data1, data2 удобнее использовать массив unsigned char data[2].

Функция преобразования

void IND_Conv( unsigned char value)
<
unsigned char tmp;
tmp = value % 10;
data[0] = number[tmp];
tmp = value/10;
data[1] = number[tmp];
>

Процедура преобразования чисел аналогична описанной выше. Единственное отличие – в буфере (data[]) мы теперь сохраняем не результат преобразования, а коды цифр. Зачем делать в прерывании то, что можно сделать в основном цикле программы?

Функция вывода на индикатор

void IND_Update( void )
<
static unsigned char count = 0;

//гасим оба разряда
PORT_K &=

((1 //выводим в порт код цифры
PORT_IND = data[count];

//зажигаем нужный разряд
if (count == 0) PORT_K |= (1 if (count == 1) PORT_K |= (1 if (count == 2) count = 0;
>

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

Пример 5. Код программы с использованием этих функций //программный счетчик секунд
unsigned char counterProg = 0;

int main( void )
<
IND_Init();

//инициализация таймера Т0
TIMSK = (1 __enable_interrupt ();
while (1) <
counterProg++;
if (counterProg == 100) counterProg = 0;
IND_Conv(counterProg);
__delay_cycles (8000000);
>
return 0;
>

//прерывания таймера Т0 – вывод на индикатор
#pragma vector = TIMER0_OVF_vect
__interrupt void Timer0_Ovf( void )
<
TCNT0 = 0xb2;
IND_Update();
>
И, наконец – разбиение программы на модули.

Создаем два файла – indicator.h и indicator.c. Сохраняем их в папке проекта.
В хидер файле у нас будут директивы условной компиляции, макроопределения и прототипы функций.

#ifndef INDICATOR_H
#define INDICATOR_H

#define PORT_IND PORTB
#define DDR_IND DDRB
#define PORT_K PORTD
#define DDR_K DDRD
#define KAT1 0
#define KAT2 1

void
IND_Init( void );
void IND_Conv( unsigned char value);
void IND_Update( void );

#endif //INDICATOR_H

В сишном файле – #include “indicator.h”, объявления переменных и реализация трех функций. Функции описаны выше, поэтому здесь их не привожу.

Подключаем файл indicator.c к проекту.
В файл main.c инклюдим заголовочный файл нашего драйвера семисегментного индикатора — #include “indicator.h”

Все. Теперь мы можем использовать функции для работы с индикатором в файле main.
Полный код драйвера смотрите в проектах.

Продолжение следует… Скоро будет дополнение к этой статье — описание вольтметра на микроконтроллере – в проекте используется 4-ех разрядный семисегментный индикатор.

Источник



Ток при динамической индикации

О среднем токе замолвите слово (к вопросу о динамической индикации).

Автор: Олег Петрович
Опубликовано 18.03.2010

Общаясь на форуме, обратил внимание, что многие кототоварищи не понимают почему не рекомендуется подключать 7-ми сегментные светодиодные индикаторы напрямую к МК, что и побудило меняу взять в лапы перо и, не претендуя на полноту изложения материала, попробовать разобраться с данным вопросом.
Изыскания будем проводить на базе Atmega16. На порт РАх — подключены ОА индикаторов, на порт РВх — подключены сегменты индикаторов, но все сказанное справедливо для любой системы с динамической индикацией на светодиодных 7-ми сегментных индикаторах, как с ОА, так и с ОК.
Исходные данные для анализа:
Максимальные токи через выводы МК:

Ток потребления собственно МК:

Теперь давайте посмотрим на рис.1

У нас имеется 3-х разрядный 7-ми сегментный светодиодный индикатор, например KingBright BA56-12GWA (Iv ср=8мкд при Iпр.ср=10 мА) разряды обозначены HL1-HL3, управляемый с помощью МК.
Разберем крайний случай — на всех индикаторах светится «8» (все сегменты включены).
Как видно из рисунка в каждый момент времени t1, t2, t3 через выводы МК Vcc и GND будут протекать суммарные токи IЦПУ+(7*IHLx), где х — номер соответствующего разряда индикатора.
Давайте посмотрим, какой максимальный ток через 1 сегмент можно обеспечить при таком подключении индикатора.
Согласно ДШ (см. выше) максимальный ток через выводы МК Vcc и GND для меги16 составляет 200 мА (что справедливо для большинства МК семейства AVR), вычитаем из него ток потребляемый самим МК 20 мА при F0=8 МГц, остается 180 мА на разряд. Казалось бы, вполне достаточно, чтобы получить нормальную яркость индикатора — 180/7=25,7 мА, а не тут то было. Поскольку общий анод каждого индикатора запитан через вывод МК, то максимальный суммарный ток на 1 разряд индикатора, согласно ДШ, равен 40 мА, или 40/7=5,7 мА на один сегмент, и это тоже вроде бы ничего, но у нас имеется 3 индикатора.
Посмотрим, что при этом происходит.
Как известно, человеческий глаз — прибор довольно инерционный, поэтому мы и не видим смены кадров на экране телевизора, переключения цифр на многоразрядных дисплеях при динамической индикации. Яркость источника света оценивается глазом по интенсивности излучения, которое в свою очередь прямо пропорционально току через сегмент индикатора. Таким образом, опуская ряд математических выкладок, мы имеем полное право утверждать, что средняя яркость сегмента будет пропорциональна среднему (за период повторения) току через сегмент, а он, как известно, для 3-х индикаторов, будет равен 1/3 от тока сегмента во включенном состоянии, для нашей схемы получится около 2 мА на сегмент.
Плюсы схемы:
Простота, не требуются внешние элементы, кроме токоограничительных резисторов.
Минусы:
Не все индикаторы могут обеспечить достаточную яркость при таком среднем токе через сегмент.
Опять же, через выводы МК Vcc и GND одновременно протекают максимально возможные токи, что тоже не есть хорошо.
«Где же выход?» спросите вы.

Выход №1.
Исключить ограничение, связанное с подключением ОА индикатора к выводу МК.
Для это надо поставить транзисторный ключ между МК и индикатором (рис.2).

Транзистор должен обеспечивать Iк макс > 180 мА, подойдет практически любой маломощный транзистор.
При этом через вывод РАх будет протекать Iб, который в h21Э/2 (2-коэффициент тока базы, вводится для гарантированного обеспечения режима насыщения транзистора, обычно 1,5-3) раза меньше чем Iк=IHLx.
Таким образом, можно обеспечить ток через 1 сегмент порядка

Средний ток составит около 8,3 мА, при этом яркость будет вполне достаточна для большинства практических применений.
При этом максимальный ток будет протекать только через вывод МК GND, что уже в 2 раза облегчает работу МК по тепловому режиму.

Выход №2.
Для тех, кому и этого мало (девайс будет эксплуатироваться при большой освещенности, ну например в автодевайсе) можно рекомендовать добавить, к предыдущему варианту, между МК и выводами сегментов ULN2003A (7 ключей) или ULN2803A (8 ключей), для тех, у кого задействована десятичная точка (рис.3). Максимальный ток через сегмент при этом можно поднять до 500 мА, и соответственно средний примерно до 167 мА, главное не перестараться и не спалить индикатор.

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

Источник

Adblock
detector