Амперметр для лабораторного блока питания своими руками

ЛАБОРАТОРНЫЙ БП С ЦИФРОВЫМ АМПЕРВОЛЬТМЕТРОМ

В печатной плате я бы посоветовал предусмотреть место под конденсатор 0,1-2 мкФ на 12-й вывод МК, на случай если надо будет сглаживать пульсации и помехи, которые будет ловить входной усилитель. Элементы входной части на ОУ (R3, R4, RV2) необходимо подбирать в зависимости от номинала шунта (R101) и тока измерения.

Электросхема самого блока питания особеностей особых не имеет. Эта рабочая схема функционирует стабильно, печатная плата без ошибок. Его схема и описание работы взяты с сайта vrtp.ru:

Это схема и разводка упрощенного варианта блока питания, на одном проходнике VT2 – TIP147. Нумерация схемы совпадает с предыдущей, удалены элементы, относящиеся к 3 проходникам. Размер платы, как и в предыдущем варианте, 120 х 55 мм. Попутно совет, если не удастся убрать самовозбуд на ВЧ в режиме источника напряжения, — попробуйте совсем убрать конденсатор С21.

Что касается VD8 – (он включен в эмиттер VT3), то, с помощью этого стабилитрона смещается рабочая точка выходного напряжения ОУ DA1.1 в середину напряжения опоры и питания = +12.25 Вольт. Так что выходное напряжение этого ОУ всегда держится около этого предела (5.6 + 0.7 = 6.3 Вольт). А назначение VD10 и VD11 – увеличить напряжение включения (засветки) соответствующих светодиодов HL1 и HL2. Дело в том, что на макете я применял яркие светодиоды, поэтому наличием одних резисторов R21 и R22 не обошлось. Чтобы не было лишней подсветки «чужого” светодиода, и пришлось поставить стабилитроны. При смене режимов стабилизации «напряжение-ток”, происходит погасание одного, а лишь потом засветка другого светодиода.

При использовании других светодиодов, менее ярких, возможно, придется подобрать (чаще всего уменьшить) напряжение стабилизации стабилитронов VD10 и VD11. Что касается стабилитронов VD10, VD11 – то, тут все зависит от желания получить требуемую яркость индикации, и, чтобы не было засветки «чужого” светодиода.

А вот к выбору стабилитрона VD8 нужно относиться поосторожней. Схема в принципе, допускает изменение его напряжения стабилизации в довольно широких пределах (от 3 до 6 вольт), но, есть некоторые нюансы. Резисторы R14 и R16 образуют делитель, уменьшающий напряжение на базе VT3 при ограничении тока. Мысленно замкните нижний вывод R16 на землю, и прикиньте, сколько будет на базе VT3, при МАХ выходном напряжении DA1.1 (считаем = 11 вольт), в нашем случае, на базе VT3 будет около 4.2 вольт.

Это напряжение должно быть МЕНЬШЕ, чем сумма напряжения стабилитрона VD8 и падения на переходе БЭ транзистора VT3 (3.3 + 0.7 = 4 вольта). Иначе, ОУ DA1.2 не сможет закрыть VT3 при перегрузке по току. Напряжение -5 вольт, мы здесь специально не учитываем, создавая тем самым некоторый запас. А если попроще, то, уменьшив напряжение стабилизации VD8, лучше пропорционально этому уменьшить и номинал R16. В нашем случае, при применении VD8 = 3.3 вольтам, оно будет = 3.6 кОм. Правда, при этом уменьшится яркость HL1 в момент ограничения тока, но, это, легко восстановить подбором VD10.

Собрал данную схему (с однополярным питанием, без минусовой подпорки). Все работает нормально, но при токах больше 0,5А на выходе появляются пульсации 50-100мВ (до этого 10-20) и растут с увеличением нагрузки. Пробежался по схеме осциллографом. Пульсации идут начиная с эмиттера VT1, соответственно и дальше по схеме они везде. Поменял транзистор — без толку. Поменял ТЛку-тот же результат. поигрался емкостями 0,1мкф по питанию-ноль эмоций. Пробовал увеличить емкость С8, помогает но не сильно. На халяву ткнул емкость 1000,0х16в между базой VT1 и входным минусом. На выходе при 2,5А — ВСЕГО 2мВ пульсации, и так во всем диапазоне напряжений и токов!

Еще совет, а попробуйте увеличить С7 до 47. 220 мкФ, и глянуть величину пульсаций при этом. Кстати, можно попробовать, подключить С7 между управляющим выводом TL431 и базой VT1, а не между управляющим выводом и катодом TL431, как изначально на схеме. Предыдущие опыты закончились установкой кондера довольно большой емкости в базу Т1. Уменьшение емкости приводило к увеличению пульсаций. А также имел место «синусоподобный» выход на режим. Манипуляции вокруг не принесли желаемых результатов. Но. все убрал и поставил емкость параллельно резистору Р4-30Ком, 22мкф, плюсом к эмиттеру Т1. Получил пульсации 2,5мВ при токе нагрузки 2,9А(больше транс не держит), во всем диапазоне напряжений. Выход на режим стал линейно нарастающим, без всяких всплесков. Емкость менее 10 мкф увеличивает пульсации, а более 22-х уже не уменьшает их. Честно говоря объяснения сему факту найти не могу.

1) Сама идея применить обычный дешевый ОУ хороша, в описании к вышеуказанной схеме подробно разжевано, что и как. Повторяться не буду, скажу лишь, что основа ее схемотехники, это работа ОУ с входными сигналами, находящимися в середине динамического диапазона, то есть в середине его питания (поэтому и не нужно отрицательное смещение для ОУ). Именно для этого и введен делитель, в 2 раза понижающий напряжение опоры, и в эту точку подается выходное напряжение, уменьшенное (смасштабированное) через соответствующий резистор R21. Для этого и применены резисторы R10, R11, R21, — этот кусок схемы повторяет прототип, про который я рассказал выше.

2) Резистор R1 – служит для разрядки силовых электролитов после выключения, это типовое решение. Все-таки 15000 мкФ – это довольно большая емкость. Дело в том, что при вышеописанном включении ООС (про резисторы R10, R11, R21 – я писАл выше), напряжение, на входах ОУ и не должно быть в районе нуля, то есть земли. Оно меняется от 4 до 6 вольт (или около того), как и в схеме прототипа. Поэтому в схеме есть резистор R8, он ограничивает диапазон изменения этого самого напряжения, не от нуля. Какой смысл далее уменьшать опорное напряжение на входе ОУ, когда на выходе блока уже и есть тот самый ноль.

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

4) Стабилитрон VD5 – смещает рабочую точку выходного напряжения ОУ DA1.1 – в середину динамического диапазона, то есть в середину питания. Напряжение выхода ОУ никогда не снижается ниже 5…6 вольт, что нам и требуется, в общем-то, для применения в качестве ОУ обычных, а не Rail-to-Rail, и т. п.

5) Применение в качестве транзистора VT2 – составной структуры типа Дарлингтон, решает сразу две задачи. Во-первых, сильно разгружает по току транзистор VT3 (не надо ставить его на теплоотвод и т. п.), который работает с практически полным входным напряжением схемы, а во-вторых, — позволяет применить в качестве запараллеленных проходников обычные транзисторы, с довольно небольшим коэффициентом усиления, практически не заботясь об их подборе. Попробовать, конечно, можно, поставить на место VT2 обычный транзистор, но, как вам сказать, все это до поры, до времени. Я не просто так акцентировал внимание собирающих на том, что в качестве VT2 – нужен только СОСТАВНОЙ P-N-P транзистор типа Дарлингтон.

6) Что получилось насчет МАХ выходного тока, вам лучше спросить у алфизика. Он, по-моему, снял с этой схемы что-то около 12 ампер выходного тока, я сам удивился. Думаю, комментарии тут излишни, хотя я считаю, что для схемы с непрерывным регулированием такой ток чересчур избыточен. Возникнут другие проблемы, отвода тепла, надежности, и так далее, и тому подобное. Но, как говорится это на усмотрение пользователя, если нравится, как работает схема, что тут еще скажешь.

7) Выбор транзисторов подразумевает, что они имеют требуемый запас по своему допустимому напряжению. Надеюсь, понимаете, что если входное напряжение планируется около 50 вольт, то и транзисторы должны иметь предел как минимум в 80…100 вольт. Но, это касается, в общем-то любой схемы, а не только этой.

Диод VD2 позволяет разрядиться конденсатору фильтра опоры С8 после выключения блока, стабилитроны VD6 и VD7 – задают режим поочередного свечения индикаторных светодиодов HL1 и HL2. Диод VD4 перепускает значительный выброс напряжения на клеммах блока на его входные электролиты для защиты самих проходников (на всякий случай, мало ли какую индуктивную нагрузку подключат к этим самым клеммам).

Диод VD8 защищает проходные транзисторы от попадания на выход слишком большого отрицательного напряжения. Конденсаторы С16 и С17 – обычный тандем конденсаторов на выходе блока питания. Резистор R29 создает небольшую подгрузку выхода для блока питания, при этом улучшаются его динамические параметры, кроме того, при регулировании выходного напряжения в уменьшение – быстрее разряжается выходной С17, это удобнее. Конденсатор С15 устраняет возможность самовозбуда схемы ограничения выходного тока.

Чтобы открыть обычный (не составной . ) кремниевый NPN транзистор, на его базу надо подать напряжение примерно на 0.7 вольта бОльшее, чем на эмиттере. Так вот, если убрать стабилитрон VD5 (соединить эмиттер VT3 с землей), тогда чтобы открыть VT3 на его базе (то есть на выходе ОУ DA1.1) должен быть потенциал + 0.7 вольта. Никакого напряжения около 5…6 вольт мы на выходе ОУ не получим, он будет работать вблизи потенциала земли, а для обычного ОУ, питающегося однополяркой это не есть хорошо. Я для того и поставил стабилитрон VD5, чтобы сместить рабочую точку выходного напряжения ОУ в середину его питания. Резюме – этот стабилитрон нужен обязательно.

Если вам нравится классика (хотя все относительно), сделайте схему с отрицательным смещением, в чем вопрос я не понял. Ведь насильно вас никто не принуждает собирать именно эту схему. На вывод 6 и заведена обратная связь с выхода через резистор R21, просто туда подается и половинное напряжение опоры, созданное с помощью резисторов R10, R11.

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

Попутно совет, лучше вход стабилизатора опоры (это — коллектор VT1, верхний вывод резистора R2 и катод VD2) подключить отдельным проводом сразу к плюсу входных электролитов С6, меньше будет влияние пульсаций при МАХ выходных токах.

Когда я говорил про «два-три резистора”, я имел ввиду добавку именно R10, R11. Именно с их помощью получается так, что нам не нужно подавать на входы ОУ напряжение, равное нулю, чтобы получить на выходе блока этот самый ноль. Почитайте повнимательнее описание схемы-прототипа, там это подробно описано. Вообще, фишка этой схемы в том, что ОУ, регулирующий напряжение не работает на краях своего динамического диапазона, а именно в середине. Поэтому в нее и можно ставить обычный ОУ.

Насчет TL431. Для того, чтобы на этом стабилизаторе не было полного входного напряжения — как раз и введен разгружающий каскад на транзисторе VT1. Прикиньте сами, на его эмиттере 12.5 вольт (так рассчитан делитель R4 и R5 в стабилизаторе опоры), значит, на его базе будет напряжение на 0.7 вольта бОльше, то есть 13.2 вольт. А весь оставшийся излишек напряжения будет падать на транзисторе VT1, ток через TL431 ограничен резистором R3. Резистор R2 задает открывающее напряжение на базе VT1, а TL431 регулируя это напряжение — как раз и стабилизирует напряжение опоры. Конечно, транзистор VT1 будет рассеивать небольшую мощность, я и указывал, что его желательно поставить на небольшой теплоотвод типа флажка, место на плате для этого предусмотрено.

И еще, советую вам обратить внимание на последнюю версию схемы (посты 337288 и 337290). Выход схемы ограничения по току подключен на вход ОУ DA1.1, то есть не внутрь ООС по напряжению, а «снаружи», если так можно выразиться. При превышении уставки тока, транзистор VT7 открывается, и шунтирует вход DA1.1, ограничивая ток на выходе блока. Это схемное решение позволяет избавиться от выбросов на выходе, при выходе из режима ограничения тока. При условии, конечно, что сам по себе канал регулирования напряжения нормально скорректирован с точки зрения ООС.

Источник

Вольтметр/амперметр для лабораторного БП


В ходе размышлений над проектом лабораторного блока питания решил я немного поизучать возможности AVR в качестве измерителя напряжения и тока. Как известно, контроллеры серии ATMega имеют 10-разрядный АЦП, который можно использовать для измерения.

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

Но на этом не заканчивается, в дело вступают проблемы программного характера: не всегда полученное количество отсчетов АЦП можно непосредственно вывести на экран, вступают в силу ошибки накопления, округления и прочие.

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

Итак, что же мы имеем?


Примечание к схеме: на каждый вывод порта B нужно привесить резистор, у меня 680 Ом.

Прибор собран на контроллере ATMega8 в корпусе TQFP-32, это дает нам 2 дополнительных входа АЦП. Обвеса минимум, буквально один блокировочный конденсатор по питанию. Тактирование — внутренняя RC-цепочка на 8 Мгц.

Диапазон измерения напряжения, который я хотел получить — 30В, а тока — 5А. Для входа напряжения применил делитель на резисторах, для входа тока подключил напрямую, в готовой схеме напряжение с шунта будет усиливаться операционным усилителем с таким расчетом, что 5А будет соответствовать 5В на выход. Сейчас вход тока просто открыт, можно мерять напряжение до 5В.

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

Вторая задача, которую пришлось решать — источник опорного напряжения. AVR позволяет использовать 3 источника — напряжение питания, встроенный ИОН 2,56В или внешний AREF. Напряжение питания показалось мне недостаточно стабильным, а встроенный ИОН — маловатым, для измерения 30В будет слишком большой коэффициент деления. К тому же была информация о недостаточной точности этого источника.

Для упрощения расчетов я решил сделать простой ИОН на 5.12В на TL431.

Точное значение опорного напряжения устанавливается многооборотным подстроечником R2, делитель для измерения напряжения тоже дополнен подстроечником R6, потому что точных резисторов необходимого номинала у меня нет. Если у вас есть, вы можете пересчитать под другие номиналы. К тому же, в результате борьбы за точность я изменил максимальное входное напряжение до 32В, так что подстроить оказалось легче, чем перепаивать.

Теперь перейдем к программированию. Здесь есть две задачи: перейти от отсчетов АЦП к вольтам и повысить точность измерения.

После нескольких вариантов пересчета я остановился на следующем.
Задаемся максимальным выходным значением 30.0В, десятичную запятую выкидываем, получается 300. Записываем степени двойки до максимального значащего разряда нашего АЦП и смотрим, какие степени в сумме составляют наше число: 256+32+8+4==300. Теперь, чтобы получить весь диапазон, нужно сделать: value=(ADC>>1)+(ADC>>4)+(ADC>>6)+(ADC>>7);
Удобно для этого пользоваться каким-нибудь табличным редактором, у меня, например, OpenOffice Calc:

Вот тут-то и вылазят все ошибки точности и округления.

Для повышения точности хорошо бы применить программные методы, например оверсемплинг, потому что 10 бит недостаточно даже для одной цифры после запятой в диапазоне 0-30В.
Для того, чтобы поднять разрядность на N бит, нужно сделать 4^N измерений и затем сумму этих измерений поделить на 2^N, то есть сдвинуть вправо N раз.
По-хорошему, нужно добавить еще шум, но я пока решил обойтись без этого.
Код:

Ну и напоследок, несколько фото:
Напряжение, больше 10В:

Напряжение, меньше 10В:

Ток:

Снизу:

В аттаче схема и модель для протеуса, исходник и готовая прошивка (подсунуть протеусу).

PS: кстати, в исходнике есть функция BCDSlow. Она, по-идее, должна быть BCDfast, но на малых значениях проигрывает обычному вычитанию. Я ее переводил с пиковского ассемблера, там она получается быстрая, по сути, все делается сдвигами и сложениями и в циклах получается не больше 9 итераций на каждый десятичный разряд, но на С что-то не заладилось. Можете глянуть на предмет оптимизации.

Комментарии ( 43 )

Прибор собран на контроллере ATMega8 в корпусе TQFP-32, это дает нам 2 дополнительных входа АЦП.

Для того, чтобы поднять разрядность на N бит, нужно сделать 4^N измерений и затем сумму этих измерений поделить на 2^N

А смысл? Все равно ADC0-ADC5 не задействованы.

потому что 10 бит недостаточно даже для одной цифры после запятой в диапазоне 0-30В.

octave:1> 30/1024
ans = 0.029297

около 3 сотых вольта на один разряд ацп.

Пересчет можно и через умножение сделать, про быстродействие же речи не идет? Да и аппаратное умножение есть.

Сильно дрожит младший разряд, не остановишь

AVR121: Enhancing ADC resolution by
oversampling

For each additional bit of resolution, n, the signal must be oversampled four times.

Thescale factor, sf, given by Equation 3-2, is the factor, which the sum of 4n samples should be divided by, to scale the result properly. n is the desired number of extra bit.
Equation 3-2: sf = 2^n

На каждый дополнительный разряд АЦП надо сделать 4^n лишних семплов. После суммирования оверсемплов результат надо побитно сдвинуть вправо n раз (разделить на 2^n).

10 Гц, хотя бы RC первого порядка, тогда и посмотреть, быть может и оверсэмплинг с дизерингом (тьфу ты, мерзопакость какая) не понадобятся.

обновлять показания чаще нескольких раз в секунду.

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

‘* Filename: Вольтметр, 2х диапазонный ампертметр *
‘* Revision: 5.1 *
‘* Controller: ATMEGA8 *
‘* Compiler: BASCOM-AVR 2.0.6.1 *
‘* Author: MACTEPOK *
‘*******************************************************************************
$regfile = «m8def.dat» ‘определяем контроллер
$crystal = 8000000 ‘внутренний генератор
‘$sim
$lib «mcsbyte.lbx» ‘подключаем библиотеку функций

Config Pinc.0 = Input: Portc.0 = 1 ‘кнопка Выбор
Config Pinc.1 = Input: Portc.1 = 1 ‘кнопка Вверх
Config Pinc.2 = Input: Portc.2 = 1 ‘кнопка Вниз

Config Portd = Output: Config Portb = Output ‘порты на выход к которым подключен индикатор

Load1 Alias Portb.3 ‘нагрузка №1
Load2 Alias Portb.4 ‘нагрузка №2
Vibor Alias Pinc.0 ‘кнопка Выбор
Up Alias Pinc.1 ‘кнопка Вверх
Down Alias Pinc.2 ‘кнопка Вниз

Config Adc = Single, Prescaler = Auto, Reference = Avcc ‘настраиваем АЦП
Dim W As Byte, Y As Byte, X As Byte, I As Byte, Z As Byte, Chislo(6) As Integer, Channel_1 As Integer, On1 As Word, Off1 As Word, Channel_2 As Integer, On2 As Word, Off2 As Word, Channel_3 As Integer, Sostoyanie As Byte, Sostoyanie_2 As Byte, Copy_print As Integer, Copy_print_sec As Integer, Copy_var As Integer, _print As Integer, _print_sec As Integer, Pokazaniya As Integer, View_menu As Byte, Booton_flag As Bit, Booton_flag_2 As Bit, Count As Word, Error_flag As Bit
Dim On2_l As Word, On2_h As Word, Off2_l As Word, Off2_h As Word, Diapazon As Byte
Dim Razryad_1 As Byte, Razryad_2 As Byte, Temp_najatiya As Byte, Indicator As Byte
Dim Menu_punkt As Byte ‘пункт меню
Dim Set_flag As Bit ‘флаг режима настройки уставок
Dim Podskaz_flag As Bit, Podskaz_flag_sec As Bit ‘флаги режима отображения подсказок на соответствующих каналах
Dim Default As Eram Byte At &H14 ‘переменная EEPROM для записи начальных уставок для первого включения прибора

‘A Alias Portd.5: B Alias Portd.7: C Alias Portd.3: D Alias Portd.1 ‘порты, к которым подключены сегменты индикатора
‘E Alias Portd.0: F Alias Portd.6: G Alias Portd.4: H Alias Portd.2 ‘
‘Dig1 Alias Portb.0: Dig2 Alias Portb.1: Dig3 Alias Portb.2 ‘ порты, к которым подключены общие аноды 1го индикатора
‘Dig1_sec Alias Portb.5: Dig2_sec Alias Portb.6: Dig3_sec Alias Portb.7 ‘ порты, к которым подключены общие аноды 2го индикатора

A Alias Portd.2: B Alias Portd.6: C Alias Portb.7: D Alias Portb.2 ‘порты, к которым подключены сегменты индикатора
E Alias Portd.0: F Alias Portb.6: G Alias Portd.7: H Alias Portb.5 ‘
Dig1 Alias Portd.3: Dig2 Alias Portd.4: Dig3 Alias Portd.1 ‘ порты, к которым подключены общие аноды 1го индикатора
Dig1_sec Alias Portd.5: Dig2_sec Alias Portb.0: Dig3_sec Alias Portb.1 ‘ порты, к которым подключены общие аноды 2го индикатора

For X = 1 To 6 ‘ присваиваем всем цифрам пустоту, чтоб в момент включения не высвечивались нули
Chislo(x) = 11
Next
‘*********** ___ Переключение типа индикаторов (ОК/ОА) ___ *********************
Readeeprom Indicator, 30
If Vibor = 0 Then ‘ Удерживая кнопку УСТ, подаем питание.
For X = 1 To 200
If X = 150 Then ‘ При длительном нажатии
Set Booton_flag
Toggle Indicator.3 ‘ Переключаем младший (четвертый) бит переменной. Номер бита выбрал произвольно
Writeeeprom Indicator, 30
If Indicator = &B00000000 Then ‘ Если переключили на ОА, зажжем все сегменты идикатора для подтверждения
Reset A: Reset B: Reset C: Reset D: Reset E: Reset F: Reset G: Reset H
Set Dig1: Set Dig2: Set Dig3: Set Dig1_sec: Set Dig2_sec: Set Dig3_sec
End If
If Indicator = &B00001000 Then ‘ Если переключили на ОK, зажжем все сегменты идикатора для подтверждения
Set A: Set B: Set C: Set D: Set E: Set F: Set G: Set H
Reset Dig1: Reset Dig2: Reset Dig3: Reset Dig1_sec: Reset Dig2_sec: Reset Dig3_sec
End If
Waitms 1500
Exit For
End If
If Vibor = 1 Then Exit For
Waitms 10
Next
End If
‘*******************************************************************************
If Default = 255 Then ‘при первом запуске, когда Default=255
Off1 = 120 ‘присваиваем начальный уставки
On1 = 110
‘ Off2 = 60
‘ On2 = 50
On2_l = 800
On2_h = 99
Off2_l = 600
Off2_h = 99
Indicator = &B00000000 ‘ для ОА. Indicator = &B00001000 для ОК
Razryad_1 = &B10111011
Razryad_2 = &B11101110
Writeeeprom On1, 0 ‘ Записываем в EEPROM уставку ON1
Writeeeprom Off1, 5 ‘ Записываем в EEPROM уставку OFF1
‘ Writeeeprom On2, 10 ‘ Записываем в EEPROM уставку ON2
‘ Writeeeprom Off2, 14 ‘ Записываем в EEPROM уставку OFF2
Writeeeprom On2_l, 22
Writeeeprom On2_h, 24
Writeeeprom Off2_l, 26
Writeeeprom Off2_h, 28
Writeeeprom Razryad_1, 16
Writeeeprom Razryad_2, 17
Writeeeprom Indicator, 30
Default = 100 ‘ присваиваем значение 100(произвольное, отличное от 255) и больше этот кусок кода выполняться не будет
End If
Readeeprom On1, 0 ‘ Считываем из EEPROM уставку ON1
Readeeprom Off1, 5 ‘ Считываем из EEPROM уставку OFF1
‘ Readeeprom On2, 10 ‘ Считываем из EEPROM уставку ON2
‘ Readeeprom Off2, 14 ‘ Считываем из EEPROM уставку OFF2
Readeeprom On2_l, 22
Readeeprom On2_h, 24
Readeeprom Off2_l, 26
Readeeprom Off2_h, 28
Readeeprom Razryad_1, 16
Readeeprom Razryad_2, 17

Config Timer0 = Timer, Prescale = 8: On Timer0 Pulse ‘ конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Config Timer1 = Timer, Prescale = 1: On Timer1 Bootons ‘ конфигурируем таймер 1 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts: Enable Timer0: Enable Timer1 ‘ разрешаем прерывания, таймер 0, таймер 1
Start Timer0: Start Timer1
Start Adc ‘ начало преобразования

If On2_l > 999 Then On2 = On2_h Else On2 = On2_l
If Off2_l > 999 Then Off2 = Off2_h Else Off2 = Off2_l

Do
If X > 40 Then ‘ увеличили период опроса АЦП, чтобы значения не прыгали
Stop Timer0: Stop Timer1 ‘ на время преобразования останавливаем таймеры
Channel_1 = Getadc(5) ‘ Вольтметр 0..500 В ‘опрос АЦП (диапазон от 0 до 1023) (1 канал)
‘ Channel_1 = 1023 — Channel_1 ‘инвертирование раскомментировать===========
Channel_1 = Channel_1 / 2.046 ‘пересчет тут любая формула для требуемого диапазона или необходимой характеристики
If Channel_1 > 500 Then Channel_1 = 500 ‘верхний предел показаний

Channel_2 = Getadc(4) ‘ Ток 1,00… 9,99 А ‘опрос АЦП (2 канал)
‘ Channel_2 = Channel_2 ‘пересчет тут любая формула для требуемого диапазона или необходимой характеристики
If Channel_2 > 999 Then Channel_2 = 999 ‘верхний предел показаний
‘ Razryad_2 = &B01110111
Diapazon = 2
If Channel_2 999 Then Channel_2 = 999
‘ Razryad_2 = &B11101110
Diapazon = 1
End If
X = 0 ‘
End If
Start Timer0: Start Timer1
If On1 = Off1 Then Sostoyanie = 0 ‘если значение первого канала АЦП выше уставки OFF1, то выключаем нагрузку №1
Else ‘если уставка ON1 > OFF1 то режим охладителя
If Channel_1 >= On1 Then Sostoyanie = 1 ‘если значение первого канала АЦП выше уставки ON1, то включаем нагрузку №1
If Channel_1 0

через 5 сек)
If Count > 7000 Then ‘задается время автоматического выхода из меню
Count = 0 ‘сброс счетчика
View_menu = 0 ‘ выход из меню в основной режим
End If
‘ H = 1 ‘ выключаем точку на индикаторе
Stop Timer0 ‘останавливаем таймер 0
Select Case View_menu ‘в зависимости от пункта меню, записываем в переменные расчета следующие данные
Case 0:
_print = Channel_1 ‘ основной режим. 1й индикатор показывает значение АЦП 1го канала
_print_sec = Channel_2 ‘ основной режим. 2й индикатор показывает значение АЦП 2го канала
If Diapazon = 2 Then Razryad_2 = &B01110111 Else Razryad_2 = &B11101110

Case 1:
_print = On1 ‘ 1й индикатор показывает значение уставки ON1
_print_sec = Channel_2 ‘ 2й индикатор показывает значение АЦП 2го канала
Case 2:
_print = Off1 ‘ 1й индикатор показывает значение уставки OFF1
_print_sec = Channel_2 ‘ 2й индикатор показывает значение АЦП 2го канала
Case 3:
_print = Channel_1 ‘ 1й индикатор показывает значение АЦП 1го канала
If On2_l = 1000 Then Razryad_2 = &B01110111 Else Razryad_2 = &B11101110
_print_sec = On2 ‘ 2й индикатор показывает значение уставки ON2
Case 4:
_print = Channel_1 ‘ 1й индикатор показывает значение АЦП 1го канала
If Off2_l = 1000 Then Razryad_2 = &B01110111 Else Razryad_2 = &B11101110
_print_sec = Off2 ‘ 2й индикатор показывает значение уставки OFF2

If Podskaz_flag = 0 Then ‘если не выводим на 1й индикатор подсказки, то работаем с числами
Copy_print = _print ‘
Copy_var = Copy_print ‘
For I = 3 To 1 Step -1 ‘ цикл в котором разбивается переменная на 3 числа
Chislo(i) = Copy_print Mod 10 ‘ заносим в масив последнюю цифру от числа Copy_print(123 mod 10 = 3)
Copy_print = Copy_print / 10 ‘ отсекаем последнюю цифру от числа Copy_print (123/10=12)
Next ‘ убираем незначимые нули
If Copy_var 6 Then W = 1 ‘ выбираем какую цифру сейчас включать
Y = 0
Gosub Look: A = Z ‘ переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А
Gosub Look: B = Z
Gosub Look: C = Z
Gosub Look: D = Z
Gosub Look: E = Z
Gosub Look: F = Z
Gosub Look: G = Z

Select Case W ‘ включаем цифру(разряд) которую выбрали (w). Подаем плюс на общий провод конкретной цифры (разряда)
Case 1:
If Indicator = 0 Then
Set Dig3
If Podskaz_flag = 0 Then H = Razryad_1.3 Else H = 1
Else
Reset Dig3
If Podskaz_flag = 0 Then
H = Razryad_1.3
Toggle H
Else
H = 0
End If
End If
Case 2:
If Indicator = 0 Then
Set Dig2
If Podskaz_flag = 0 Then H = Razryad_1.2 Else H = 1
Else
Reset Dig2
If Podskaz_flag = 0 Then
H = Razryad_1.2
Toggle H
Else
H = 0
End If
End If
Case 3:
If Indicator = 0 Then
Set Dig1
If Podskaz_flag = 0 Then H = Razryad_1.1 Else H = 1
Else
Reset Dig1
If Podskaz_flag = 0 Then
H = Razryad_1.1
Toggle H
Else
H = 0
End If
End If
Case 4:
If Indicator = 0 Then
Set Dig3_sec
If Podskaz_flag_sec = 0 Then H = Razryad_2.3 Else H = 1
Else
Reset Dig3_sec
If Podskaz_flag = 0 Then
H = Razryad_2.3
Toggle H
Else
H = 0
End If
End If
Case 5:
If Indicator = 0 Then
Set Dig2_sec
If Podskaz_flag_sec = 0 Then H = Razryad_2.2 Else H = 1
Else
Reset Dig2_sec
If Podskaz_flag = 0 Then
H = Razryad_2.2
Toggle H
Else
H = 0
End If
End If
Case 6:
If Indicator = 0 Then
Set Dig1_sec
If Podskaz_flag_sec = 0 Then H = Razryad_2.1 Else H = 1
Else
Reset Dig1_sec
If Podskaz_flag = 0 Then
H = Razryad_2.1
Toggle H
Else
H = 0
End If
End If
End Select

Start Timer0
Return

Look: ‘ подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму
Z = Chislo(w) * 7: Z = Y + Z ‘ определяем порядковый номер числа из таблици DATA. W — это цифра которую будем выводить 1..2..3, Y это номер сегмента (A=0 B=1 C=2. G=7)
If Indicator = 0 Then
Z = Lookup(z, Cifri_oa) ‘ выбираем из таблици включить или выключить нужный сегмент -OA
Else
Z = Lookup(z, Cifri_ok) ‘-OK
End If
Incr Y ‘Y это номер сегмента (A=0 B=1 C=2. ). Chislo(w) * 7 — переход на начало нужной строки Data.Z = Y + Z — по очереди перебираем сегменты в строке.
Return

Источник

Читайте также:  Вещи своими руками для охоты
Оцените статью