Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 74HC4094 в качестве расширителя порта
Форум разработчиков электроники ELECTRONIX.ru > Аналоговая и цифровая техника, прикладная электроника > Цифровые схемы, высокоскоростные ЦС
Страницы: 1, 2
alux
Привет. Необходимо сделать динамическое включение катодов 7-сегментного индикатора. Выводов контроллера как всегда не хватает. В качестве расширителя порта решил поставить преобразователь последовательной шины в параллельную 74HC4094. Т.е. по сути мне необходимо периодически (10мсек) на выходе 4094 сдвигать "1" для включения соответсвующего индикатора. Или другими словами последовательно загружать числа 1,2,4,8,16,32 и так по кругу. Вывод OE всегда притянут к питанию. Важно не допустить одновременного включения нескольких катодов. Правильно ли я делаю :

1) SI=1, CLK=1, SI=0, CLK=0 . Повторить n раз (n =1,2,4,8,16,32)
2) STROB=1;
3) STROB=0;

Сильно греется КРЕН. Померял ток потребления схемы - около 130 мА. Схема - это микроконтроллер (Мега48) с двумя светодиодными индикаторами, управляемые динамически. Видимо, проблема связана с неправильным формированием сигналов на 74HC4094.

Прикладываю даташит. Кстати, у разных производителей по-разному осуществляется загрузка данных: либо по наростающему фронту на CLK, либо по спадающему... Странно.
rezident
Народ обычно использует 74HC595 и TPIC6C595. При наличии контроллера нолик там гонять по кругу или единичку совершенно без разницы. Только следут учитывать, что у TPIC6C595 открытые стоки на выходах.
P.S. они обе замечательно каскадируются.
AVL
Микросхема 74HC4094 для Вашей задачи подходит не лучшим образом. Для этой задачи нужен счетчик с дешифратором (одна микросхема). Вам будет достаточно управлять 2-мя входами этой микросхемы: счетный вход и вход сброса, при этом активность единственного выхода в каждый момент времени гарантирована независимо от логики работы программы мк.

Если же микросхема 74HC4094:
Цитата(alux @ Jun 7 2007, 22:03) *
1) SI=1, CLK=1, SI=0, CLK=0 . Повторить n раз (n =1,2,4,8,16,32)
2) STROB=1;
3) STROB=0;

Из Ваших слов не понятно, что вы повторяете и как, и похоже, что все равно не правильно.
Должно быть так (если по кругу).

CLK=0, STR=0
1) SI=0
2) {CLK=1, CLK=0} повторить 7 раз
3) SI=1, CLK=1, CLK=0
4) STR=1, STR=0 => станет активным выход QP0
5) SI=0, CLK=1, CLK=0
6) STR=1, STR=0 => станет активным выход QP1
7) SI=0, CLK=1, CLK=0
8) STR=1, STR=0 => станет активным выход QP2
9) SI=0, CLK=1, CLK=0
10) STR=1, STR=0 => станет активным выход QP3
11) SI=0, CLK=1, CLK=0
12) STR=1, STR=0 => станет активным выход QP4
13) SI=0, CLK=1, CLK=0
14) STR=1, STR=0 => станет активным выход QP5
15) SI=0
16) {CLK=1, CLK=0} повторить 2 раза
17) переход на п.3

Цитата(alux @ Jun 7 2007, 22:03) *
Сильно греется КРЕН. Померял ток потребления схемы - около 130 мА. Схема - это микроконтроллер (Мега48) с двумя светодиодными индикаторами, управляемые динамически. Видимо, проблема связана с неправильным формированием сигналов на 74HC4094.

Неплохо бы схему принципиальную тоже приложить.
alux
Цитата(rezident @ Jun 7 2007, 22:34) *
Народ обычно использует 74HC595, TPIC6C595.

Вопрос был о 74HC4094. Просто она уже запаяна в схему. А менять на что-либо другое буду только если не будет других вариантов. Так в чем же проблема?

Цитата(AVL @ Jun 7 2007, 23:09) *
Неплохо бы схему принципиальную тоже приложить.

Прикладываю схему. Спасибо за ответ. Сейчас попробую. Временно программно отключил индикацию , но 7805 все равно греется (палец не удержать), хотя ток составляет 35мА ?! В холостом режиме (когда от откренки все отсоединено), не греется. Странно однако %-()
rezident
Похожую схему только без аналоговых входов (индикация:две строки по четыре 7-сегментных индикатора+4 отдельных светодиода, вдобавок 9-и кнопочная клавиатура+RS485) с год назад делал. Применил как раз 74HC595 - 3 шт., т.к. на каждую строку нужна была своя динамическая индикация (по одному регистру), а третий регистр для управления совмещенными анодами индикаторов строк и 4-мя светодиодами. Индикация у МК всего три вывода отняла. Для вашего же случая TPIC6C595 сам бог велел - от 8 транзисторов по пути избавитесь. smile.gif
Насчет большого потребления.
У меня вызывает сомнение цепь питания AVCC. ИМХО там по схеме не хватает тантала или электролита после дросселя впараллель керамике 0,1мкФ. Такой Г-образный фильтр в виде дросселя с керамикой нехило "звенеть" может.
Кроме того в базах транзисторов, которые управляют обмотками реле, вы забыли резисторы Б-Э. КТ3102 ведь не "цифровые" транзисторы. В транзисторы управление катодами индикаторов почему-то поставили, а тут нет.
Кстати, а что питается по цепи 3,3В? Или для чего там 78L33 стоит? 7805, которая якобы сильно греется, вообще не показана. Возле нее, непосредственно возле выводов OUT и GND, конденсатор номиналом не менее 1мкФ стоит? Если нет, то она опять же возбуждаться может, а саморазогрев при этом у нее не слабый!
alux
Цитата(AVL @ Jun 7 2007, 23:09) *
Должно быть так (если по кругу).

CLK=0, STR=0
1) SI=0
2) {CLK=1, CLK=0} повторить 7 раз
3) SI=1, CLK=1, CLK=0
4) STR=1, STR=0 => станет активным выход QP0
5) SI=0, CLK=1, CLK=0
6) STR=1, STR=0 => станет активным выход QP1
7) SI=0, CLK=1, CLK=0
8) STR=1, STR=0 => станет активным выход QP2
9) SI=0, CLK=1, CLK=0
10) STR=1, STR=0 => станет активным выход QP3
11) SI=0, CLK=1, CLK=0
12) STR=1, STR=0 => станет активным выход QP4
13) SI=0, CLK=1, CLK=0
14) STR=1, STR=0 => станет активным выход QP5
15) SI=0
16) {CLK=1, CLK=0} повторить 2 раза
17) переход на п.3


Не понял с п.17. Чтобы включить следующее знакоместо (QP1="1", все остальные="0"), при следующем вызове начинать с п.3 ?
rezident
Может совет несколько неуместный, но зачем вам заниматься учетом сдвигов в самом регистре? У вас же МК для управления имеется. Сдвигайте и XOR-те байт как хотите программно в самом МК, а в регистр записывайте этот байт каждый раз целиком. Все будет детерменировано и никакого геморроя - всего один цикл записи 8-ми бит (установить бит данных, сформировать сдвиговый импульс - и так 8 раз) плюс формирование строба записи по окончании цикла.
alux
Цитата(rezident @ Jun 8 2007, 00:29) *
Сдвигайте и XOR-те байт как хотите программно в самом МК, а в регистр записывайте этот байт каждый раз целиком. Все будет детерменировано и никакого геморроя - всего один цикл записи 8-ми бит (установить бит данных, сформировать сдвиговый импульс - и так 8 раз) плюс формирование строба записи по окончании цикла.

Я так и делал. Только загружаемые значения беру из таблицы:

__interrupt void TC0_COMPA_ISR(void)
{..........
digit(++znak);
...........
}
/////////////////////////
void digit(unsigned char number)
{
unsigned char table[]={0,1,2,4,8,16,32};

for(unsigned char i=0; i < *(table+number); i++)
{
PORTC |= (1<<SI);
PORTC |= (1<<CLK);
PORTC &= ~(1<<SI);
PORTC &= ~(1<<CLK); //загрузить число n=0,1,2,4,8,16,32 раз
}
PORTD |= (1<<STR);
PORTD &= ~(1<<STR); //строб
}

Для выключения индикаторов (для гашения незначащих разрядов) вызвать digit(0);
Я хочу, чтобы было так:
1)Строб=0. Приэтом на выходе без изменений остается предыдущее значение.
2) загрузить в storage register (74HC4094) число (0,1,2,4,8,16,32).
3)сформировать строб. При этом на выход поступает значение из storage register.

Можно ли так сделать на этой микросхеме?

Цитата(rezident @ Jun 8 2007, 00:14) *
У меня вызывает сомнение цепь питания AVCC. ИМХО там по схеме не хватает тантала или электролита после дросселя впараллель керамике 0,1мкФ. Такой Г-образный фильтр в виде дросселя с керамикой нехило "звенеть" может.
Кроме того в базах транзисторов, которые управляют обмотками реле, вы забыли резисторы Б-Э. КТ3102 ведь не "цифровые" транзисторы. В транзисторы управление катодами индикаторов почему-то поставили, а тут нет.
Кстати, а что питается по цепи 3,3В? Или для чего там 78L33 стоит? 7805, которая якобы сильно греется, вообще не показана. Возле нее, непосредственно возле выводов OUT и GND, конденсатор номиналом не менее 1мкФ стоит? Если нет, то она опять же возбуждаться может, а саморазогрев при этом у нее не слабый!


Это часть схемы. Прошу прощения, на рисунке есть несоответствия. На плате параллельно керамике 0.1мкФ по питанию AVCC стоит танталовый 10мкФ. И в базовых цепях забыл указать(на плате стоят) резисторы 100кОм. А 7805 - на другом листе. Спаяна по стандартной схеме: ~9В->диодный мост->4700мкФ->7805->100мкФ. На входе и на выходе непосредственно на выводах 7805 подключены керамические 0.1мкФ. +3.3В нужны для других целей.
AVL
Цитата(alux @ Jun 8 2007, 01:22) *
Не понял с п.17. Чтобы включить следующее знакоместо (QP1="1", все остальные="0"), при следующем вызове начинать с п.3 ?

Вы же по кругу хотите. Соответственно после активации QP5 должен быть активирован QP0. Следовательно из п.17 нужно перейти на пункт 3.

Цитата(alux @ Jun 8 2007, 00:43) *
... но 7805 все равно греется (палец не удержать), хотя ток составляет 35мА ?! В холостом режиме (когда от откренки все отсоединено), не греется. Странно однако %-()

Значит на вашей 7805 рассеивается большая мощность. Какое напряжение Вы подаете на вход 7805? Такое ощущение, что входное напряжение велико и вся разность падает на 7805, поэтому и греется и не важно, что ток всего 35мА. К примеру, если Вы подаете на вход 7805 15В, на выходе 7805 5В, то все 10В при токе 35мА, падающие на 7805, превращаются в тепло.

Цитата(rezident @ Jun 8 2007, 01:29) *
Может совет несколько неуместный, но зачем вам заниматься учетом сдвигов в самом регистре? У вас же МК для управления имеется. Сдвигайте и XOR-те байт как хотите программно в самом МК, а в регистр записывайте этот байт каждый раз целиком. Все будет детерменировано и никакого геморроя - всего один цикл записи 8-ми бит (установить бит данных, сформировать сдвиговый импульс - и так 8 раз) плюс формирование строба записи по окончании цикла.

В данном случае он в примерно в 8 раз теряет в производительности.

Цитата(alux @ Jun 8 2007, 11:01) *
for(unsigned char i=0; i < *(table+number); i++)
{
PORTC |= (1<<SI);
PORTC |= (1<<CLK);
PORTC &= ~(1<<SI);
PORTC &= ~(1<<CLK); //загрузить число n=0,1,2,4,8,16,32 раз
}
PORTD |= (1<<STR);
PORTD &= ~(1<<STR); //строб
}

Последовательность действий абсурдна. То как Вы пытаетесь делать, только единицы будут записываться в сдвиговый регистр (все выходы станут активными).

Смотрите мой алгоритм. Его можно упростить (как описал rezident), но при этом потеряете в производительности. Если вопрос производительности не стоит, то, конечно, можно загружать каждый раз весь регистр. Но для данной задачи выглядит это криво.
alux
Цитата(AVL @ Jun 8 2007, 10:35) *
Значит на вашей 7805 рассеивается большая мощность. Какое напряжение Вы подаете на вход 7805? Такое ощущение, что входное напряжение велико и вся разность падает на 7805, поэтому и греется и не важно, что ток всего 35мА.

Трансформатор на выходе под нагрузкой дает 10,5В. На входной емкости 4700мкФ еще на пару вольт накидывается. По справочнику допустимое входное напряжение 7805 от 7 до 35В. Вы хотите сказать, что причина перегрева в том, что на входе стабилизатора напряжение 12В?

Цитата(AVL @ Jun 8 2007, 10:35) *
Если вопрос производительности не стоит, то, конечно, можно загружать каждый раз весь регистр.

Да, мне так удобней. Кроме индикации мне необходимо по событию на выходы Q6, Q7 подать управляющие сигналы. Т.е. вызывать функцию digit(znak), в качестве аргумента является загружаемое значение (0,1,2,4,8,16,32 или др). Если я правильно понял, надо делать так? :

void digit(unsigned char number)
{
for (unsigned char i = 0; i < 8; i++)
{
if ((number & 1)) SI = 1;
else SI = 0;
CLK = 1;
CLK = 0;
number = number >> 1;
};
STR = 1;
STR = 0;
}
Мне сейчас необходимо определится: можно ли добится желаемого результата с этой микросхемой или покупать и менять на 74HC595?
AVL
Цитата(alux @ Jun 8 2007, 12:18) *
По справочнику допустимое входное напряжение 7805 от 7 до 35В. Вы хотите сказать, что причина перегрева в том, что на входе стабилизатора напряжение 12В?

Возможно из-за этого. Радиатор стоит какой-нибудь для отвода тепла? И дополнительно рекомендую снизить входное напряжение до 8-9 Вольт (при больших токах потребления этот момент уже существенен).

Цитата(alux @ Jun 8 2007, 12:18) *
Да, мне так удобней. Кроме индикации мне необходимо по событию на выходы Q6, Q7 подать управляющие сигналы. Т.е. вызывать функцию digit(znak), в качестве аргумента является загружаемое значение (0,1,2,4,8,16,32 или др). Если я правильно понял, надо делать так? :

void digit(unsigned char number)
{
for (unsigned char i = 0; i < 8; i++)
{
if ((number & 1)) SI = 1;
else SI = 0;
CLK = 1;
CLK = 0;
number = number >> 1;
};
STR = 1;
STR = 0;
}

Да, Вы правильно поняли.

Цитата(alux @ Jun 8 2007, 12:18) *
Мне сейчас необходимо определится: можно ли добится желаемого результата с этой микросхемой или покупать и менять на 74HC595?

конечно можно. Единственное в микросхеме 74HC4094 нет входа сброса. Чревато это тем, что пока Вы не загрузите в регистр корректное значение (все 8 бит), на выходе 74HC4094 при включении питания будет мусор, что приведет к активации нескольких индикаторов сразу. Возможно для Вас это не критично (но Вы указывали, что нельзя, чтобы активизировалось больше, чем один выход).
alux
Цитата(AVL @ Jun 8 2007, 11:42) *
Возможно из-за этого. Радиатор стоит какой-нибудь для отвода тепла? И дополнительно рекомендую снизить входное напряжение до 8-9 Вольт (при больших токах потребления этот момент уже существенен).

Радиатора нет. По идее 7805 (TO-220) может работать без радиатора до 0,5А.

Цитата(AVL @ Jun 8 2007, 11:42) *
Единственное в микросхеме 74HC4094 нет входа сброса. Чревато это тем, что пока Вы не загрузите в регистр корректное значение (все 8 бит), на выходе 74HC4094 при включении питания будет мусор, что приведет к активации нескольких индикаторов сразу.

Если эта проблема проявляется только при включении питания, то это не проблема. Только я не до конца уяснил один момент. Во время загрузки значения при OE=1 каждый входной бит будет сразу отображаться на выходе до сигнала строб?

Кстати, какая нагрузочная способность 74hc4094? В моем даташите(Philips)указаны только временные характеристики. Судя из аналогичного других фирм, указан параметр DC Output Source Sink Current Per Output Pin +/-25mA, DC VCC or Ground Current +/-50mA. Т.е. в статике можно включать одновременно не более 5 нагрузок током 10мА?
AVL
Цитата(alux @ Jun 8 2007, 13:06) *
Радиатора нет. По идее 7805 (TO-220) может работать без радиатора до 0,5А.

Я же говорю Вам, проблема не в макс.нагр.токе и не в макс.вх.напряжении, с которыми может работать 7805. Проблема в рассеиваемой мощности. Если Вы подадите на вход 7805 35В и при этом ток в цепи будет 0.5А, то стабилизатор сгорит ярким пламенем smile.gif Вам нужно посмотреть, на какую макс.рассеиваемую мощность расчитан этот стабилизатор без применения радиатора и на какую он расчитан с применением радиатора. И сделать выводы после этого ставить или нет радиатор и какой он должен быть конфигурации.

Цитата(alux @ Jun 8 2007, 13:06) *
Если эта проблема проявляется только при включении питания, то это не проблема. Только я не до конца уяснил один момент. Во время загрузки значения при OE=1 каждый входной бит будет сразу отображаться на выходе до сигнала строб?

обновление информации (которую Вы задвинули во входной регистр) на выходе микросхемы произойдет только после установки STR=1.

Цитата(alux @ Jun 8 2007, 13:06) *
Кстати, какая нагрузочная способность 74hc4094? В моем даташите(Philips)указаны только временные характеристики.

У меня Ваш даташит smile.gif
на первой странице даташита написано:
For a complete data sheet, please also download:
· The IC06 74HC/HCT/HCU/HCMOS Logic Family Specifications
· The IC06 74HC/HCT/HCU/HCMOS Logic Package Information
· The IC06 74HC/HCT/HCU/HCMOS Logic Package Outlines

Цитата(alux @ Jun 8 2007, 13:06) *
Судя из аналогичного других фирм, указан параметр DC Output Source Sink Current Per Output Pin +/-25mA, DC VCC or Ground Current +/-50mA. Т.е. в статике можно включать одновременно не более 5 нагрузок током 10мА?

да, если эти параметры указаны как макс.допустимые величины. Еще нужно проверять, чтобы не была превышена макс.рассеиваемая мощность.
alux
Все, заработало! Вот окончательный код:

void digit(unsigned char number)
{
unsigned char table[]={0,1,2,4,8,16,32};

for (unsigned char i = 0; i < 8; i++)
{
if ((*(table+number) & 128)) PORTC |= (1<<SI);
else PORTC &= ~(1<<SI);
PORTC |= (1<<CLK);
PORTC &= ~(1<<CLK);
*(table+number) = *(table+number) << 1;
}
PORTD |= (1<<STR);
PORTD &= ~(1<<STR);
}

number соответствует номеру знакоместа. Если включить одно знакоместо постоянно и засветить все сегменты ("8"), ток потребления составляет 104мА. 7805 греется :-/ Хотя по з-ну Ома: I=U/R = 5/220=23мА. Для 7 сегментов 23*7=161мА. Откуда такая разница?

Кстати, если кому интересно, нашел одну ссылку на подобную тему:
http://homepages.which.net/~paul.hills/Sof...ftRegister.html
AVL
Цитата(alux @ Jun 8 2007, 17:07) *
Если включить одно знакоместо постоянно и засветить все сегменты ("8"), ток потребления составляет 104мА. 7805 греется :-/ Хотя по з-ну Ома: I=U/R = 5/220=23мА. Для 7 сегментов 23*7=161мА. Откуда такая разница?

Откуда Вы это берете? на резисторах R25...R32 не по 5В же падает, а намного меньше.
almay
Цитата
Если включить одно знакоместо постоянно и засветить все сегменты ("8"), ток потребления составляет 104мА. 7805 греется :-/ Хотя по з-ну Ома: I=U/R = 5/220=23мА. Для 7 сегментов 23*7=161мА. Откуда такая разница?

Вроде бы как еще падение на светодиоде имеется 1,2-1,6В плюс точность(%) резисторов.
alux
Цитата(AVL @ Jun 8 2007, 16:28) *
Откуда Вы это берете? на резисторах R25...R32 не по 5В же падает, а намного меньше.

Согласен. В общем, тему считаю исчерпанной. Спасибо за участие.
alux
Прошу прощения, но есть еще одна проблема с индикацией. В статике все работает замечательно. Делаю так:
display(1);
digit(1);
delay_ms(2000);

display(2);
digit(2);
delay_ms(2000);

display(1);
digit(1);
delay_ms(2000);
и на индикаторе поочередно зажигаются 1,2,3 слева-на-право.
А вот в динамике есть накладка. Вот кусок кода:


__flash unsigned char code7[]=
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};


#pragma vector=TIMER0_COMPA_vect
__interrupt void TC0_COMPA_ISR(void)
{
switch(znak)
{
case 0:
hundred=1;
ten=2;
one=3;

display(hundred);
digit(++znak);
break;

case 1:
display(ten);
digit(++znak);
break;

case 2:
display(one);
digit(++znak);
znak=0;
break;
}
...................
}

////////////////////////////////////////
/********************************************************
// Вывод значения на индикатор с преобразованием в 7-сегментный код
void display(unsigned char num)
{
unsigned char temp;

num=*(code7+num);

temp = num;
PORTB=(temp&0x3f);

temp = PORTD;
temp &= 0x3f;
num &= 0xc0;
PORTD = (temp|num);
}


//*****************************************************************
//Включение знакоместа формированием "1" на выходе (74HC4094)
void digit(unsigned char number)
{
unsigned char table[]={0,1,2,4,8,16,32};

for (unsigned char i = 0; i < 8; i++)
{
if ((*(table+number) & 128)) PORTC |= (1<<SI);
else PORTC &= ~(1<<SI);
PORTC |= (1<<CLK);
PORTC &= ~(1<<CLK);
*(table+number) <<= 1;
}
PORTD |= (1<<STR);
PORTD &= ~(1<<STR);
}

При этом происходит наложение H+M, M+L, L+H. H,M,L-разряды индикатора.
Проганял в симуляторе. Все пучком. В чем же дело?
AVL
Цитата(alux @ Jun 9 2007, 04:03) *
А вот в динамике есть накладка.
При этом происходит наложение H+M, M+L, L+H. H,M,L-разряды индикатора.
Проганял в симуляторе. Все пучком. В чем же дело?

Как часто вызывается __interrupt void TC0_COMPA_ISR(void) ?
alux
Цитата(AVL @ Jun 9 2007, 10:06) *
Как часто вызывается __interrupt void TC0_COMPA_ISR(void) ?

10 мсек
AVL
Цитата(alux @ Jun 9 2007, 12:14) *
10 мсек

тогда весь листинг программы приведите (приложите файл)
alux
Цитата(AVL @ Jun 9 2007, 12:22) *
тогда весь листинг программы приведите (приложите файл)

Прикладываю. Правда там закоментированы некоторые части... Буду Вам очень благодарен, если подскажите, в чем проблема. На первый взгляд, ошибка явная, но я ее не вижу. Нужен взгляд со стороны.
AVL
Цитата(alux @ Jun 9 2007, 13:58) *
Прикладываю. Правда там закоментированы некоторые части... Буду Вам очень благодарен, если подскажите, в чем проблема. На первый взгляд, ошибка явная, но я ее не вижу. Нужен взгляд со стороны.

Во первых, проинициализируйте переменную znak=0 в Initialise(void).

Затем попробуйте следующее:

1) добавьте элемент "нет свечения":
__flash unsigned char code7[]= //hgfedcba
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x78, 0x5c, 0x39, 0x77, 0x38, 0x00};
//0(0), 1(1), 2(2), 3(3), 4(4), 5(5), 6(6), 7(7), 8(8), 9(9), 10(t),11(o),12©,13(A),14(L),15( )

2) в обработчике __interrupt void TC0_COMPA_ISR(void)
вместо каждой пары строк
display(hundred/ten/one);
digit(++znak);

напишите:
display(15);
digit(++znak);
display(hundred/ten/one);

Если не поможет, попробуйте для эксперимента отключить все обработчики прерываний, кроме __interrupt void TC0_COMPA_ISR(void).
rezident
Цитата(alux @ Jun 8 2007, 14:18) *
Трансформатор на выходе под нагрузкой дает 10,5В. На входной емкости 4700мкФ еще на пару вольт накидывается. По справочнику допустимое входное напряжение 7805 от 7 до 35В. Вы хотите сказать, что причина перегрева в том, что на входе стабилизатора напряжение 12В?

Цитата(alux)
number соответствует номеру знакоместа. Если включить одно знакоместо постоянно и засветить все сегменты ("8"), ток потребления составляет 104мА. 7805 греется :-/ Хотя по з-ну Ома: I=U/R = 5/220=23мА. Для 7 сегментов 23*7=161мА. Откуда такая разница?

Допустимая рассеиваемая без радиатора мощность рассчитывается довольно просто. Достаточно пары страниц из datasheet L7805CV. Тепловое сопротивление корпуса TO-220 составляет 55 С/Вт. Максимальная рабочая температура кристалла L7805CV - 150 C. Следовательно при температуре окружающей среды 25С максимально допустимая рассеиваемая температура (150С-25С)/55С/Вт=2,27Вт.
Считаем далее.
Собственный ток потребления L7805 при 25С - 6мА (+0,5мА при изменении нагрузки до 1А.) При входном напряжении 12В и токе нагрузки 35 мА на м/с будет рассеиваться примерно (12В-5В)*(0,006А+0,035А)=0,29Вт. Что даст перегрев 0,29Вт*55С/Вт=15,95С. При температуре окружающей среды 25С температура м/с составит примерно 25C+15.95C=41С, еще не горячо, но уже ощутимо smile.gif
Если 35мА ток потребления устройства при погашенном индикаторе, то при всех засвеченных сегментах всех знакомест ток потребления будет около (5В-1,3В)/220Ом*7+0,035А=118мА. Тогда температура самого стабилизатора L7805 при температуре окр. воздуха 25С будет около (12В-5В)*(0,006А+0,118А)*55С/Вт+25С= 73С - уже можно обжечься! wink.gif
alux
Цитата(AVL @ Jun 9 2007, 13:48) *
Во первых, проинициализируйте переменную znak=0 в Initialise(void).

А зачем? Она же глобальная.

Цитата(AVL @ Jun 9 2007, 13:48) *
Если не поможет, попробуйте для эксперимента отключить все обработчики прерываний, кроме __interrupt void TC0_COMPA_ISR(void).

А вот тут началось самое интересное!!! Запретил прерывание АЦП, и все заработало. В смысле хотя бы показывает число в динамике. Но самое интересное в том, что все работает даже после разрешения прерывания АЦП !!! Это что, мистика?



Цитата(rezident @ Jun 9 2007, 14:20) *
Допустимая рассеиваемая без радиатора мощность рассчитывается довольно просто.

Спасибо за детальный расчет. Очень кстати. Значит для уменьшения тепловыделения:
1) поставить трансформатор с выходным напряжением 6...7В,
2) поставить на 7805 радиатор,
3) или вообще применить импульсный источник питания.
rezident
Цитата(alux @ Jun 9 2007, 18:05) *
1) поставить трансформатор с выходным напряжением 6...7В,

Ага, но только на 9В. При очень грубом подсчете выпрямителя на небольшие напряжение можно считать, что в самых плохих условиях (пониженное входное сетевое напряжение, маленькая емкость фильтрующего конденсатора выпрямителя и т.п.) на входе стабилизатора будет то же по величине напряжение (естественно что уже постоянное), что и на выходе трансформатора. Maximum Dropout Voltage (падение напряжение на стабилизаторе) для L7805CV составляет 2,5В. При использовании 6-7В трансформатора вашему стабилизаторе просто не хватит величины выпрямленного напряжения, чтобы на выходе обеспечить стабильное напряжение 5В.
Цитата(alux @ Jun 9 2007, 18:05) *
2) поставить на 7805 радиатор,

Для трансформаторного линейного БП, я бы даже сказал, что это обязательное условие.
Цитата(alux @ Jun 9 2007, 18:05) *
3) или вообще применить импульсный источник питания.

Одно из самых корректных решений.
AVL
Цитата(alux @ Jun 9 2007, 16:05) *
А зачем? Она же глобальная.

А причем здесь глобальная? Вы когда включаете питание, каким будет содержимое SRAM? Если ее никто не проинициализирует, там будет мусор. Или у Вас есть какая-то процедура, производящая инициализацию всей памяти, и я ее не приметил?

Цитата(alux @ Jun 9 2007, 16:05) *
А вот тут началось самое интересное!!! Запретил прерывание АЦП, и все заработало. В смысле хотя бы показывает число в динамике. Но самое интересное в том, что все работает даже после разрешения прерывания АЦП !!! Это что, мистика?

затрудняюсь ответить
alux
Цитата(alux @ Jun 9 2007, 15:05) *
А вот тут началось самое интересное!!! Запретил прерывание АЦП, и все заработало. В смысле хотя бы показывает число в динамике. Но самое интересное в том, что все работает даже после разрешения прерывания АЦП !!! Это что, мистика?

Прошу прощения. Нет здесь мистики. Была ошибка в настройке прерывания. Предделитель был No_prescaling. Но все равно не ясно, каким образом период прерывания влияет на наложение разрядов? И еще один момент. В программе используется прерывание АЦП. В нем я обычно гашу индикацию, чтобы не "плавал" источник питания, к которому привязано опорное напряжение. Хотя в качестве опорного используется TL431 и схема измерения ratiometric.
#pragma vector=ADC_vect
__interrupt void ADC_ISR(void)
{
digit(0); //выключить индикатор

accum = ADC;

digit(znak); //восстановить индикатор
} // End of ADC_ISR
Но включение, выключение в процедуре АЦП влияет на индикацию. Младший разряд нижнего индикатора еле светится значением. Вопрос:
1)так ли необходимо выключать индикацию в момент измерения?
2)опорное напряжение (+2.5В) на TL431 по качеству отличается от внутреннего, который в микроконтроллере, например в Меге8 ? Я использовал внешний, потому-что у Меги48 внутренний +1.1В.
AVL
Цитата(alux @ Jun 9 2007, 17:02) *
Прошу прощения. Нет здесь мистики. Была ошибка в настройке прерывания. Предделитель был No_prescaling. Но все равно не ясно, каким образом период прерывания влияет на наложение разрядов?

Предделитель какого обработчика был No_prescaling?
И вопрос. Вы сделали, что я рекомендовал (см.ниже)?
Цитата
1) добавьте элемент "нет свечения":
__flash unsigned char code7[]= //hgfedcba
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x78, 0x5c, 0x39, 0x77, 0x38, 0x00};
//0(0), 1(1), 2(2), 3(3), 4(4), 5(5), 6(6), 7(7), 8(8), 9(9), 10(t),11(o),12©,13(A),14(L),15( )

2) в обработчике __interrupt void TC0_COMPA_ISR(void)
вместо каждой пары строк
display(hundred/ten/one);
digit(++znak);

напишите:
display(15);
digit(++znak);
display(hundred/ten/one);
alux
Цитата(AVL @ Jun 9 2007, 15:38) *
А причем здесь глобальная? Вы когда включаете питание, каким будет содержимое SRAM? Если ее никто не проинициализирует, там будет мусор. Или у Вас есть какая-то процедура, производящая инициализацию всей памяти, и я ее не приметил?

Цитата из учебника по С: "Если глобальная переменная не проинициализирована явным образом, она инициализируется значением 0". Мне не трудно проинициализировать. Я только хочу разобраться.
AVL
Цитата(alux @ Jun 9 2007, 17:16) *
Цитата из учебника по С: "Если глобальная переменная не проинициализирована явным образом, она инициализируется значением 0". Мне не трудно проинициализировать. Я только хочу разобраться.

Это не всегда правда. Если ОЗУ до выполнения Вашей программы не было инициализировано и конкретно используемый Вами C-компилятор не добавляет в машинный код код инициализации глобальных переменных, для которых не заданы в исходном тексте начальные значения, эти переменные будут содержать мусор. Вы можете провести эксперимент. Включите питание и с помощью средств отладки сразу после старта main() посмотрите содержимое памяти в области расположения глобальных переменных.

P.S. Например, C-компилятор, которым пользуюсь я, не инициализирует переменные, которые не проинициализированы явным образом. Отсюда вывод, чтобы там ни было написано в книге, лучше делать инициализацию, из соображений совместимости.
rezident
Цитата(AVL @ Jun 9 2007, 19:33) *
P.S. Например, C-компилятор, которым пользуюсь я, не инициализирует переменные, которые не проинициализированы явным образом. Отсюда вывод, чтобы там ни было написано в книге, лучше делать инициализацию, из соображений совместимости.

Насчет инициализации глобальных alux прав. А ваш компилятор в таком случае (если вы именно про глобальные переменные пишете) не соответствует стандарту ASNI C (ISO/IEC 9899:1999), как вы вообще им пользуетесь-то? 07.gif
Цитата(AVL)
конкретно используемый Вами C-компилятор не добавляет в машинный код код инициализации глобальных переменных, для которых не заданы в исходном тексте начальные значения, эти переменные будут содержать мусор.

Вот этот блок инициализации, включаемый компилятором в старт-ап, и "чистит" глобальные переменные, если явно не заданы значения для их инициализации.
alux
Цитата(AVL @ Jun 9 2007, 16:12) *
Предделитель какого обработчика был No_prescaling?
И вопрос. Вы сделали, что я рекомендовал (см.ниже)?

Предделитель таймера. Значит так. Проблема действительно была связана с предделителем. В исходном коде, No_Prescaling:
display(hundred/ten/one);
digit(++znak);
было наложение разрядов. Решение проблемы:
1)Предделитель =1024,
2)либо Ваш вариант
display(15) /// не обязательно
digit(++znak);
display(hundred/ten/one);
Предложенный Вами вариант работает и с No_Prescaling.
Спасибо огромное. Вывод - ночью надо спать smile.gif


...еще бы получить ответ про опорное напряжение и необходимость выключения индикаторов в прерывании АЦП.
AVL
Цитата(rezident @ Jun 9 2007, 17:43) *
Насчет инициализации глобальных alux прав. А ваш компилятор в таком случае (если вы именно про глобальные переменные пишете) не соответствует стандарту ASNI C (ISO/IEC 9899:1999), как вы вообще им пользуетесь-то? 07.gif

Согласен, если компилятор отвечает требованиям стандарта ASNI C (ISO/IEC 9899:1999), то глобальные переменные будут проинициализированы. Но не все компиляторы полностью отвечают требованиям этого стандарта.
rezident
Цитата(alux)
2)опорное напряжение (+2.5В) на TL431 по качеству отличается от внутреннего, который в микроконтроллере, например в Меге8 ? Я использовал внешний, потому-что у Меги48 внутренний +1.1В.

На TL431A можно сделать опорное напряжение со точностью (начальный разброс 2,47В...2,52В) и стабильностью (не более 50ppm/C) не хуже 2%. Внутренняя опора ATMega8 имеет только разброс начального значения напряжения больше 5% (2,3В...2,7В), а временнАя температурная нестабильность вообще не указана. Выводы сделаете сами? wink.gif
alux
Цитата(rezident @ Jun 9 2007, 18:11) *
Выводы сделаете сами? wink.gif

Да, спасибо. А на счет необходимости выключения индикации в прерывании АЦП? Для более точного результата?
rezident
Цитата(alux @ Jun 9 2007, 21:58) *
А на счет необходимости выключения индикации в прерывании АЦП? Для более точного результата?

Статическую индикацию выключать не требуется. А вот "ногодрыжечество" во время оцифровки крайне нежелательно. Т.е. во время работы АЦП нежелательно, чтобы изменялись состояния каких-либо пинов МК, т.к. импульсные токи, возникающие при этом, могут давать помехи и приводить к искажению результатов оцифровки. Следовательно динамическую индикацию нужно как-то синхронизировать с выборками АЦП.
alux
Цитата(rezident @ Jun 9 2007, 19:25) *
А вот "ногодрыжечество" во время оцифровки крайне нежелательно. Т.е. во время работы АЦП нежелательно, чтобы изменялись состояния каких-либо пинов МК, т.к. импульсные токи, возникающие при этом, могут давать помехи и приводить к искажению результатов оцифровки. Следовательно динамическую индикацию нужно как-то синхронизировать с выборками АЦП.

Во время преобразования АЦП никаких изменений состояний пина не предвидится. Просто в разные моменты времени будут зажжены разные сегменты, что приведет к разным просадкам напряжения питания с вытекающими из этого изменения опорного напряжения. Ворос в следующем: насколько это будет критично?
AVL
Цитата(alux @ Jun 9 2007, 17:02) *
И еще один момент. В программе используется прерывание АЦП. В нем я обычно гашу индикацию, чтобы не "плавал" источник питания, к которому привязано опорное напряжение. Хотя в качестве опорного используется TL431 и схема измерения ratiometric.
#pragma vector=ADC_vect
__interrupt void ADC_ISR(void)
{
digit(0); //выключить индикатор

accum = ADC;

digit(znak); //восстановить индикатор
} // End of ADC_ISR

Такое отключение (в обработчике __interrupt void ADC_ISR(void) ) Вам ничего не даст. Когда управление передается обработчику прерывания __interrupt void ADC_ISR(void), АЦП уже все посчитал. То есть из обработчика отключение индикации можно убрать.
Если требуется высокая точность измерения, то, конечно, динамическая индикация во время измерения будет давать помехи. Но не только индикация, переключение реле тоже. Если идти дальше, то помехи дают даже переключения внутри микроконтроллера. Для того, чтобы устранить главный источник помех (последствия управления пинами), на время работы АЦП не изменяйте состояния выходных пинов. Время преобразования АЦП составляет от 13 до 260 мкс (в зависимости от того, какой режим Вы выбрали).
А еще лучше, переходите в SLEEP режим до начала преобразования АЦП, а просыпайтесь по прерыванию от АЦП.
rezident
Цитата(alux @ Jun 10 2007, 00:26) *
Просто в разные моменты времени будут зажжены разные сегменты, что приведет к разным просадкам напряжения питания с вытекающими из этого изменения опорного напряжения.

Какие просадки напряжения? Где оно "просаживается"? Причем тут опора? "Нич-ч-чего не понимаю" (с) м/ф "Следствие ведут колобки" smile.gif
alux
Цитата(AVL @ Jun 9 2007, 22:04) *
Для того, чтобы устранить главный источник помех (последствия управления пинами), на время работы АЦП не изменяйте состояния выходных пинов. Время преобразования АЦП составляет от 13 до 260 мкс (в зависимости от того, какой режим Вы выбрали).
А еще лучше, переходите в SLEEP режим до начала преобразования АЦП, а просыпайтесь по прерыванию от АЦП.

Одно уточнение. Не щелкать выводами во время выборки входного сигнала или во время всего преобразования?
AVL
Цитата(alux @ Jun 9 2007, 23:17) *
Одно уточнение. Не щелкать выводами во время выборки входного сигнала или во время всего преобразования?

всего преобразования
alux
Цитата(rezident @ Jun 9 2007, 22:10) *
Какие просадки напряжения? Где оно "просаживается"? Причем тут опора? "Нич-ч-чего не понимаю" (с) м/ф "Следствие ведут колобки" smile.gif

Ну что здесь не понятного? Преобразования АЦП, на мой взгляд, лучше проводить в одинаковых условиях. Возьмем крайние случаи: одно преобразование произошло, когда все сегменты зажжены. Ток потребления составляет 120мА. Второе преобразование произошло , когда все сегменты потушены. Ток 30мА. Неужели напряжение питание в обеих случаях останется постоянным? Уверен, что нет. А раз нет, значит значения АЦП будут отличаться при одинаковом входном воздействии.
rezident
Цитата(alux @ Jun 10 2007, 01:48) *
Неужели напряжение питание в обеих случаях останется постоянным? Уверен, что нет.

А для чего тогда вы стабилизатор напряжения питания поставили? wink.gif При правильной трассировке печатной платы ток потребления светодиодного индикатора на результат работы АЦП сколь-либо существенно влиять не будет. Но можно конечно сделать и наоборот smile.gif
Результат работы АЦП в большей степени зависит от параметров опорного напряжения (ну и входных цепей - мультиплексора/буфера/усилителя - тоже).
alux
Цитата(rezident @ Jun 10 2007, 00:18) *
А для чего тогда вы стабилизатор напряжения питания поставили? wink.gif При правильной трассировке печатной платы ток потребления светодиодного индикатора на результат работы АЦП сколь-либо существенно влиять не будет. Но можно конечно сделать и наоборот smile.gif
Результат работы АЦП в большей степени зависит от параметров опорного напряжения (ну и входных цепей - мультиплексора/буфера/усилителя - тоже).

Все относительно. Параметры опорного напряжения в некоторой мере тоже зависят от напряжения питания. Вопрос только насколько? Согласен, что этим изменением можно в первом приближении пренепречь. К тому же схема опорного напряжения ratiometric, т.е. изменение напряжения питания приведет к пропорциональному изменению опорного напряжения. И это не скажется на результате измерения.
rezident
ratiometric, это просто делитель напряжения питания что ли? А кто вас заставляет такую дурацкую опору использовать? Если хотите точность измерений обеспечить, то извольте "человеческую" опору использовать. И гадать сколько/насколько тоже не нужно, т.к. можно все посчитать и промоделировать с достаточной точностью.
alux
Цитата(rezident @ Jun 9 2007, 16:43) *
Вот этот блок инициализации, включаемый компилятором в старт-ап, и "чистит" глобальные переменные, если явно не заданы значения для их инициализации.

А как на счет того, если глобальная переменная назначена в регистре:
__regvar __no_init unsigned char Flags@ 15;
Ее надо инициализировать 0 в отдельной процедуре? Помнится, когда программировал на асме (AVR) были проблемы из-за того, что регистр не был проинициализирован после сброса. Хотя по идее регистровый файл находится в статическом ОЗУ, и должен быть инициализирован 0 по умолчанию. Так ведь?

Хотя только что проверил. Если не инициализировать глобальную переменную в регистре, там будет мусор. Хотя такой вывод я сделал по неработоспособности программы, а не считав это значение каким-либо образом.
rezident
Несмотря на то, что в вашем примере переменная Flags глобальная, вы сами дали указание компилятору о том, что инициализировать ее не нужно. Указание это в виде команды для препроцессора __no_init. В IAR его можно записать еще и по-другому, как прагму.
Код
#pragma type_attribute=__no_init
__regvar unsigned char Flags@ 15;

И щё ж ви еще таки хотите? wink.gif Совершенно естественно компилятор вас "послушается" и заниматься инициализацией этой переменной не будет.
alux
to rezident.
Я хочу вернуться к вопросу чрезмерного тепловыделения стабилизатором напряжения. Можно ли решить эту проблему заменой 7805 на LDO-стабилизатор. Есть pin-to-pin совместимые с 7805?
И заменой трансформатора на пониженное напряжение (6...7В) ?
AVL
Цитата(alux @ Jun 14 2007, 11:28) *
to rezident.
Я хочу вернуться к вопросу чрезмерного тепловыделения стабилизатором напряжения. Можно ли решить эту проблему заменой 7805 на LDO-стабилизатор. Есть pin-to-pin совместимые с 7805?
И заменой трансформатора на пониженное напряжение (6...7В) ?

В таком случае тепловыделение должно стать ниже.
Еще все-таки рассмотрите вариант импульсного ИП.
Еще как вариант можно поставить дешевый DC-DC преобразователь сразу после выпрямителя.
Два последние варианты хороши тем, что тепловыделение будет ниже, а КПД высоким.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.