Работа с BASCOM AVR (обзор статей грамотных людей) 2
Статьи публикуются по мере поступления. Для упорядоченного тематического
поиска воспользуйтесь блоком "Карта сайта"
Такое решение предоставляют нам прерывания.
Прерывания изменяют нормальный ход выполнения программы и заставляют
МК реагировать на внешние события так же, как и на внутренние.
Нам достаточно немного изменить код:
Pind.2 настроен на вход. Не забудьте про подтягивающий резистор 10кОм!
Config Int0 = Falling заставляет сработать прерывание по спаду сигнала, т.е. при переходе с высокого уровня на низкий. Когда происходит прерывание Int0, программа переходит на метку Stopbutton. Нужно включить прерывания как в целом, так и конкретно Int0! В цикле Do-Loop "какое-то запутанное задание" - это мигание светодиодом.
Купить
Программаторы, средства разработки и отладки для DSP,
средства разработки и отладки для ПЛИС-ПАИС
Подпрограмма Stopbutton выводит "stop!" на ЖК индикатор, затем продолжает работу основной программы с того места, где она была прервана. Здесь светодиод зацикленно включается и выключается, а большая часть времени ухожит на задержку Waitms. При нажатии на кнопку происходит переход на метку Stopbutton. На ЖКИ выводится "stopъ!", и программа возвращается к светодиоду. Однако написание слов на ЖК индикаторе - далеко не единственое применение прерываний. Почему? Узнаете сами, немного позже. Для начала обзор прерываний, реализуемых в AT90S2313:
Прерывания AT90S2313
A. Внешние прерывания:
Int0 внешнее прерывание на PortD.2, pin 6
Int1 внешнее прерывание на PortD.3, pin 7
Counter0 прерывание по переполнению, PortD.4, pin 8
Counter1 прерывание по переполнению, PortD.5, pin 9
Timer1 прерывание по захвату, PortD.5, pin 9
Timer1 прерывание по сравнению, PortD.5, pin 9
Serial Rx прерывание по окончании приема
Analog comparator0 прерывание компаратора, PortB.0, pin 12
Analog comparator1 прерывание компаратора, PortB.1, pin 13
B.Внутренние прерывания:
Timer0 прерывание по переполнению
Timer1 прерывание по переполнению
Serial data register прерывание по опустошению
Serial Tx прерывание по окончании передачи
Все прерывания в AVR имеют одинаковый приоритет. Это отличает их от других микроконтроллеров, где вы можете задать приоритет для каждого вида прерывания по отношению к другому. Если вы используете другой AVR микроконтроллер, используйте BASCOM файл *.def для определения доступных видов прерывания. А также почитайте даташит (обязательно!).
ВКЛ/ВЫКЛ прерываний
Когда вы пишете программу на BASCOM, прерывания по умолчанию отключены. Их нужно включить с помощью команды:
Это может оказаться полезным, если у вас есть серьезный фрагмент в коде, выполнение которого нельзя прервать ни под каким предлогом:
Подпрограммы прерываний
Каждое прерывание должно иметь свою подпрограмму обработки событий. Подпрограмма - это фрагмент кода с меткой, набором команд и функцией возврата Return. Для каждого включенного прерывания вы должны указать подпрограмму, на которую нужно перейти при происхождении события:
В тот момент, когда программа прерывается и переходит к подпрограмме обработки прерывания, все включенные прерывания отключаются на время работы этой подпрограммы. Когда ее выполнение достигает оператора Return и переходит к тому месту в главном коде, на котором его выполнение было прервано, отключенные прерывания снова включаются. Это делается для того, чтобы подпрограммы обработки не прерывали сами себя (это как змея начала бы кушать себя с хвоста!). Такое поведение, отличающееся от микроконтроллеров большинства других фирм, заложено в самой AVR архитектуре, не в BASCOM. Делайте подпрограммы обработки прерываний как можно короче! Помните, что ваша программа прерывается, чем бы она ни занималась, и она не должна быть прервана надолго. Старайтесь не делать в прерываниях ничего сложнее, чем изменение счетчиков или флагов. Фрагменты обработки этих данных лучше всего разместить в главном коде. Сравните две программы - вот эту:
Во втором случае подпрограмма Stopbutton максимально сокращена, в ней только устанавливается флаг Stopflag. А он уже обрабатывается в главном коде. Однако будьте внимательны! В таком случае прерывание может быть обработано намного позже, чем оно произошло!
Еще про int0/int1
Int0 и Int1 - внешние прерывания. Обычно они вызываются кнопками, переключателями, импульсами или логическими уровнями с других цепей. Вы можете предопределить, как обработчик прерываний будет реагировать на изменение сигнала:
Таким образом, прерывания генерируются, пока сигнал на Intx низкий, по спаду и по фронту. Low Level создает прерывания все время, пока управляющий уровень низкий. Например:
В подпрограмме обработки значение счетчика увеличивается и отображается на дисплее четыре раза в секунду.
В справке BASCOM недокументирован (как считает pa3ckr) тот факт, что Low Level - конфигурация прерывания по умолчанию. Однако прерывание по фронту или по спаду намного распространеннее.
Неприятное явление дребезга
Идеальная кнопка переключает состояние строго с разомкнутого на замкнутое и наоборот. Однако, реальные кнопки обладают "дребезгом". При нажатии кнопка "генерирует" серию импульсов, причем у некоторых экземпляров эта серия длится до 50 миллисекунд. Вот осциллограмма сигнала нажатия кнопки, подключенной к земле через 10килоомный подтягивающий резистор:
На самом деле это очень даже хорошая кнопочка - дребез у нее длится всего 0.5 мс. Таким образом, если ваша программа реагирует на спад или фронт, вы получите кучу прерываний вместо одного. Поэтому нам необходимо реализовать функцию антидребезга, например, добавив задержку:
время обработки прерывания отключаются, программа среагирует только на первый импульс. Выберите значение константы Debouncetime так, чтобы оно было больше наибольшего времени дребезга используемых кнопок. Также в BASCOM есть команда Debounce, которую тоже можно использовать в прерываниях.
Что за GIFR?
В вышеприведенном примере, в подрограмме прерывания есть странная строка Gifr=64. Что это за Gifr за такой? Уберите эту строчку и посмотрите, что получится: практически в любом случае "stop!" будет выведено на ЖКИ два раза. Как же такое возможно?
А посмотрите вот этот пример
После очистки ЖКИ включается светодиод. Затем следует трехсекундная задержка, после чего гаснет светодиод и включаются прерывания. Теперь сбросьте МК и попробуйте нажать кнопку, пока включен светодиод. У вас есть три секунды, так что думаю, у вас не возникнет проблем (а иначе - вам делать нечего тут! прим. WildCat'a). После погасания светодиода включается Int0, и вы заметите, что программа переходит к подпрограмме Stopbutton. Поэтому, даже если вы нажмете кнопку перед включением прерываний, данные о срабатывании где-то сохранятся, и после включения прерывание немедленно выполнится. Вот что происходит в AT90S2313 (да и в других МК AVR). Даже если соответствующее прерывание НЕ включено, данные о его срабатывании хранятся в "General Interrupt Flag Register" (GIFR или Главный Регистр Флагов Прерываний). Это один из тех редчайших случаев, когда даже пользователям BASCOM придется вникнуть во внутреннее строение AVR (я вас не заставляю!) Регистр GIFR имеет восемь бит, из которых шестой и седьмой зарезервированы для Int0 и Int1 соответственно:
И вот что происходит в нашей программе interrupt-debounce-self.bas: В подпрограмме обработки, когда прерывания выключены, данные о срабатывании все равно приходят из-за дребезга контактов. Прерывания отмечаются в GIFR нулевым битом. Для Int0 это шестой бит, для Int1 - седьмой. Все, что нужно сделать для устранения нашей проблемы - это установить соответствующие биты в GIFR перед командой Return в подпрограмме обработки. Тогда дальнейшие (бесполезные) прерывания после продолжения работы обрабатываться не будут.
Зарегистрированные имена регистров
Теперь мы знаем, что есть несколько зарегистрированных имен регистров. Избегайте их использования в ваших программах. Используйте справку BASCOM (запустите справку, нажмите "Поиск" и введите "AVR internal registers") и даташит AT90S2313 (table 1, страницы 15 и 16).
Таймеры и счетчики
В AT90S2313 есть два таймера/счетчика (убедитесь, что вы прочитали 27 страницу... ну вы поняли, чего). Timer0 - это восьмибитный таймер/счетчик, может принимать значения от 0 до 255.
С командой Config мы можем настроить его, как нам заблагорассудится:
Config Timer0 = Timer, Prescale = 1|8|64|256|1024
Здесь Timer0 настроен на счет тактовых импульсов. Он считает тактовые импульсы с выхода делителя с настраиваемым коэффициентом 1, 8, 64, 256 или 1024. Таймер считает время, в течение которого он изменяется с 0 до 255. Пусть в нашем проекте стоит кварц 4МГц и делитель на 1024. Тогда таймер будет увеличивать значение каждые (коэффициент/тактовая частота, 1024/4.000.000)=0,256 миллисекунд. Тогда переполняться он будет каждые 255*0,256=65 миллисекунд. Time1 аналогичен Timer0, но он 16-битный, он считает до 65535 до переполнения. Таймеры начинают отсчет с момента конфигурации.
Вот пример использования timer0 (вам нужен AT90S2313 с подключенным дисплеем):
Конечно, главное отличие в том, что здесь переменная Timercounter представлена как Word. Текущие значения таймеров в любой момент могут быть прочитаны и записаны в переменную соответствующего типа. Эти два примера используют свободно запущенные таймеры. Их можно запустить и остановить в любой момент:
Прерывания по таймеру
Наиболее распространенное использование таймеров - создание прерываний через равные промежутки времени для выполнения какого-то задания, например, проверки состояния порта, или наоборот, вывод импульса.
Вот пример генератора импульсов (используйте схему с кнопкой "Stop", выход на portb.1):
В результате на выходе мы получим красивый меандр с периодом примерно 8 миллисекунд на portb.1:
AT90S2313 довольно шустрый! Попробуйте настроить деление на 1 и проверьте результат на portb.1. Период сигнала примерно 120 микросекунд.
Вся эта прелесть работает, пока время работы подпрограммы меньше времени включения/выключения сигнала. Попробуйте вставить команду Cls в прерывание. Вы увидите, что период возрастет со 120 микросекунд до 12 миллисекунд!
Длительность задержки
Во всех этих примерах прерывание создается по переполнению счетчика таймера. Это значит, что мы ограничены в выборе времени тактовой частотой, коэффициентом деления и размерностью регистра таймера. Один из способов создания определенного промежутка времени - не давать таймеру свободно заполняться от 0 до максимального значения, а задавать некоторое ненулевое значение регистра после каждого переполнения. Мы можем выбрать его таким образом, чтобы получить нужное время заполнения от этого значения до максимума:
После каждого переполнения Timer1 в его регистр помещается значение 65100, поэтому перед каждым прерыванием он считает от 65100 до 65535. Это занимает (65536 - 65100) * 0,25 = 109 микросекунд. Изменяя константу Timer1pre, вы можете задать время включения/выключения с точностью 0,25 микросекунд.
Подсчет внешних импульсов
Timer0 и Timer1 могут быть настроены на счет внешних импульсов на выводах T0 и T1:
Config Timer0 = Counter, Prescale = 1|8|64|256|1024, Edge = Rising|Falling
Config Timer1 = Counter, Prescale = 1|8|64|256|1024, Edge = Rising|Falling
Вы можете выбрать счет по фронту или по спаду. Также вы можете задать предделитель для счета. Особенно интересен Timer1, так как он может считать до 65535 перед переполнением. Имена Timerx, Counterx и Capturex в BASCOM соответствуют именам регистров, поэтому нельзя использовать одноименные переменные в программе, что не есть хорошо. Когда Timer0 и Timer1 используются для подсчета внешних импульсов, контроллер будет квантовать входы со своей тактовой частотой. Это значит, что для точного подсчета частота следования импульсов не должна превышать половины тактовой частоты. Для безопасности старайтесь подавать импульсы на вход с частотой ниже 40% от тактовой. Так, для кварца 4МГц частота следования импульсов не должна превышать 1,6МГц. Проверьте это на ТТЛ генераторе, подключенном к T1 (Portd.5, 9 нога для AT90S2313):
Timer1 может работать в режиме "Capture" (захвата). Это значит, что Timer1 считает тактовые импульсы через предделитель, и, когда на вход ICP (portd.6, 11 нога) приходит импульс, содержимое Timer1 копируется в регистр Input Capture. Таким способом можно точно измерить время между двумя импульсами: Config Timer1 - Timer, Prescale = 1|8|64|256|1024, Capture Edge = Rising|Falling
Компаратор на Timer1
У Timer1 есть регистр сравнения CompareA (в BASCOM также есть регистр CompareB, но он отсутствует в AT90S2313). В этот регистр можно положить конкретное значение. Когда значение Timer1 сравняется со значением CompareA, предописанное действие даст результат на OC1 (Portb.3, 15 нога): Config Timer1 = Timer, Prescale = 1|8|64|256|1024, Compare A = Clear|Set|Toggle|Disconnect, Clear Timer = 0|1
Действием может быть:
- Установить OC1
- Сбросить OC1
- Переключить OC1
- Отключить OC1
С помощью Clear Timer можно очистить Timer1, когда произойдет прерывание CompareA. Наиболее используемая функция - Toggle (переключение). Она используется для генерирования точной частоты на OC1.
Подключите маленький динамик последовательно с резистором в несколько сот Ом к OC1 (Portb.3, 15 нога) и слушайте музыку...
Прерывания UART
В AT90S2313 есть три вида UART прерываний:
1. Tx ready - когда последний бит передан и буфер отправки пуст. Такой вид используется при работе в полудуплексном режиме, и вы должны знать, когда переходить с передачи на прием. В полнодуплексном режиме (по умолчанию) такое прерывание не требуется.
2. Буфер передачи пуст. Это прерывание возникает, когда символ из буфера данных переписан в буфер отправки. Его можно использовать, чтобы знать, что пора отправлять следующий символ. Вам это прерывание особенно не потребуется, так как при передаче строки BASCOM все сделает за вас.
3. Rx ready - когда по UART получен символ и помещен в буфер данных. Этот символ нужно считать как можно скорее, пока не пришел следующий. BASCOM также сам обрабатывает и прием строк по UART, но это прерывание можно использовать, например, для изменения порядка выполнения программы:
В AT90S2313 есть аналоговый компаратор на Ain0 (12 нога) и Ain1 (13 нога). Компаратор можно настроить так, что по его переключению включается Timer1 Capture. Также он может создавать прерывание:
Config ACI = On|Off, Compare = On|Off, Trigger = Rising|Falling|Toggle
При включении этого режима, при переключении компаратора включается Timer1 Compare. Срабатывание можно настроить по фронту (Ain0 > Ain1), по спаду (Ain0 < Ain1) или по переключению (Ain0 > Ain1 и Ain0 < Ain1). Возможное применение аналогового компаратора - восьмибитный ЦАП, однако вам потребуется полностью свободный PortB для размещения R-2R ЦАП. Это довольно глупое занятие, гораздо практичнее использовать внешний I2C чип, например PCF8591, в котором есть один ЦАП и четыре АЦП (восьмибитных).
Работа с EEPROM
EEPROM - встроенная энергонезависимая память (Flash-память) микроконтроллера. В AT90S2313 доступно 128 байт EEPROM. В более крупных МК доступны большие объемы. EEPROM обычно используется для хранения данных, которые редко изменяются. Вы можете использовать его для хранения калибровочных данных, которые используются при расчетах. EEPROM не стоит использовать в качестве оперативной памяти из-за небольшого лимита циклов перезаписи (читаем даташит!). Читать и записывать данные в EEPROM можно с помощью соответствующих команд Readeeprom и Writeeeprom. Но перед их использованием нужно особым образом разместить данные в энергонезависимой памяти. Это можно сделать двумя способами. Первый - использовать $eeprom:
Строку $eeprom необходимо разместить в программе перед тем местом, в котором происходит обращение к константам в памяти. Эта команда заставляет переключаться BASCOM с работы с блоками данных Data на блоки Eeprom. Команда $data выполняет обратное действие. Лучше всего разместить строку $eeprom перед строкой Data.
Вот пример работы с EEPROM в BASCOM:
Здесь переменная ADCcal объявлена как переменная типа byte в ERAM (EEPROM). В принципе, это не настоящая переменная. Все, что мы можем сделать:
Если данные в EEPROM размещались при помощи команды $eeprom, то BASCOM создаст отдельный .eep файл. Поэтому компилирование текущего проекта даст два выходных файла (.bin и .eep). Сначала запрограммируйте МК как обычно, загрузив в него .bin файл. Затем вручную запустите TWinavr, нажмите WRITE, выберите "EEPROM files" в списке типов файлов и откройте eeprom0.eep. На этот раз TWinavr запрограммирует энергонезависимую память. Для работы с EEPROM годятся оба метода, но предпочтение можно отдать первому, потому что при использовании значений в EEPROM по умолчанию гораздо удобнее отдельно запрограммировать зону этой памяти.
Протокол I2C и BASCOM
IIC (I2C) - это сокращение от Inter-IC. I2C - разработка компании Philips, начатая в 80-х годах. В наши дни бытовая техника сделала резкий скачок в сторону усложнения схемотехники. В одном устройстве встречается множество микросхем. Как следствие - запутанная разводка и плотный монтаж печатных плат. Philips решила, что неплохо было бы использовать простую последовательную шину.
Купить
Программаторы, средства разработки и отладки для DSP,
средства разработки и отладки для ПЛИС-ПАИС
Вместо широких параллельных шин можно было бы использовать всего два проводника. В такой шине один провод отвечает за данные, а второй - за тактовые импульсы, SDA и SCL соответственно. I2C стандарт 1992 года использует семибитные адреса, что позволяет одновременное подключение до 128 ИС к одной шине. Более подробно про этот протокол можно почитать в спецификации I2C.
Адресация в I2C
Число микросхем на одной шине ограничено 128, потому что каждому чипу соответствует 7-битный адрес. Сравните это, например, с домами на одной улице. Если у нескольких домов будет один и тот же номер, то почтальон придет в замешательство, не зная, куда бросить извещение о посылке с деталями. Адреса задаются частично аппаратно в микросхеме, частично их можно задавать вручную путем подключения соответствующих выводов к питанию/земле. Это позволяет независимо подключать несколько одинаковых микросхем к одной шине. Для примера рассмотрим известную PCF8574P. Это восьмибитный расширитель портов общего назначения. В нем аппаратно установлен адрес 0100 A2 A1 A0. Часть 0100 уже прошита в чипе, а часть A2 A1 A0 можно задать вручную. Мы можем сделать это, подключая соответствующие выводы к + питания или земле:
Вот тут микросхема слева имеет адрес 0100100, а справа - 0100000.
Стандарты I2C
Изначально стандарт I2C работал с тактовой частотой до 100кГц. В 1992 году был добавлен Быстрый режим с максимальной частотой 400кГц. Также в этом варианте была реализована 10-битная адресация. В 1998 году появился Высокоскоростной режим с максимальной скоростью 3,4 Мбит/с. (вероятно, Philips сочла Мбит/с более удобной величиной, чем килогерцы) Быстрый и высокоскоростной режимы одинаково хорошо работают с частотой и 100кГц. Подробнее про стандарт. Philips обладает патентом на I2C. Это значит, что любая компания, желающая выпускать микросхемы с поддержкой I2C должна заплатить за это и подписать соглашение.
Большинство микроконтроллеров AVR обладают двухпроводным интерфейсом (угадайте, что это), по крайней мере, так сказано в документации. Это, конечно же, пресловутый I2C. Видимо, эта терминология используется из жадности и нежелания платить деньги Philips за то, чем все и так прекрасно пользуются. Стандарт I2C предусматривает подтягивающие резисторы на SDA и SCL. Это одна из наиболее распространенных ошибок. Забудьте про подтягивание, и ваша схема будет безупречно не работать. Как правило, хватает резистора в 10кОм. Иногда, при достижении максимальной скорости обмена, можно импользовать более низкие значения. Проверьте даташиты микроконтроллера и вашей микросхемы.
Иногда можно встретить резисторы 100-330 Ом в линиях. Это делается для уменьшения взаимного влияния. Длина шины I2C не ограничена. Единственное, что общая емкость линии с подключенными устройствами не должны превышать 400 пФ. Устройство, начинающее передачу, называется Ведущим (Master, мастер), а устройство, к которому оно обращается, - Ведомым (соответственно, Slave, мазохист раб). Во всех наших примерах AT90S2313 выступает в роли ведущего устройства. Ведомое устройство молчит всегда, пока его не спросит ведущее. Тактовые импульсы на SCL тоже обеспечивает ведущее устройство. Мастер отвечает за временные интервалы в передаче. Если ведомое устройство должно вернуть какие-то значения мастеру, он также должен отвечать за все временные интервалы. I2C позволяет работу нескольких ведущих устройств на одной шине, однако во всех наших примерах только один "мастер" и один или несколько "рабов".
Что можно учинить с I2C?
Главное преимущество стандарта - это использование всего двух ног контроллера, что актуально для небольших МК. Конечно, за такое удобство придется платить - передача одного байта займет время передачи 8 бит + время начала/окончания передачи. Поэтому I2C безусловно медленнее параллельной шины. Однако, если вы не гонитесь за мегибитами, I2C - идеальный вариант. Многие изготовители выпускают занятные микросхемы с I2C. Philips, как изобретатель, лидирует в этом деле. Иногда можно встретить целые модули с I2C интерфейсом (ТВ-тюнеры, дисплеи...).
Что же делать?
Вот что мы решили препарировать:
- Philips PCF8574
- TI PCF8574
- On-Semi JLC1562B
- Philips PCF8591
- Natsem LM76
- Philips graphics display LPH7653
- Linear Technology LT6904
PCF8574 - это восьмибитный расширитель портов общего назначения. Он добавляет 8 дополнительных пинов ввода/вывода. Используйте его для подключения светодиодов, реле или клавиш/клавиатуры. У него есть выход прерывания, на котором появляется низкий уровень после любого изменения состояния входов. После чтения состояния портов его уровень автоматически возвращается в высокий. Это очень удобный способ вызова прерывания при вводе. Контроллер тут же читает что изменилось и принимает решение.
Заметка: Philips выпускает две модификации чипа: PCF8574 и PCF8574A. Они отличаются только адресом!
PCF8574: 0100. A2 A1 A0
PCF8574A: 0111. A2 A1 A0
Изучите эти мелочи подробнее в даташите.
Если вам нужно больше портов ввода/вывода, используйте PCF8575 той же Philips. Это уже 16-битный расширитель портов.
Texas Instruments выпускает одноименные чипы, одинаковые по характеристикам (и корпусам). On-Semi JLC1562B так же восьмибитный расширитель общего назначения, но у него есть кое-что еще: 6-битный ЦАП и компаратор на младших пяти разрядах. Однако у него нет выхода прерывания. Компаратор совместно с ЦАП и некоторым программным кодом может таинственно превращаться в 6-битный АЦП. PCF8591 от Philips имеет один 8-битный ЦАП и четыре 8-битных АЦП. Аналоговые входы можно настроить как одиночные, так и на сложение и вычитание сигналов. Вот вам датаshit для ковыряния. Компания National Semiconductor выпускает микросхему термометра LM76. Сами они заявляют, что назначение этих чипов - 'оценка' температуры, так что не надейтесь на космическую точность. В общем, подробнее в очередном связанном документе. В чипе находится температурный датчик и 12-битный АЦП (+ знаковый разряд). LPH7653 от Philips - это маленький графический дисплей, вероятно, выдранный из старого телефона. Даташита на него никто никогда не видел, но говорят, что кто-то знает, как управлять им. LT6904 от Linear Technology - волшебный чип-синтезатор частоты от 1 кГц до 64 МГц. Конечно, этот список - всего лишь маленький пример того, что нам доступно для экспериментирования. На самом деле в природе существует гораздо больше хороших микросхем, ищите их на сайтах ведущих производителей по запросу I2C.
Стандартные команды чтения/записи
Команды чтения и записи I2C работают с одним байтом за раз. Стандартная процедура записи такая:
Ошибки I2C
В BASCOM зарезервирована переменная Err типа Bit. Если происходит ошибка I2C, в нее помещается 1. Правда никому не известно, что с ней делать. На самом деле, что? Обычно ошибки возникают из-за аппаратных проблем, поэтому вряд ли пользователь сможет что-то сделать.
Простая светодиодная мигалка
Давайте забацаем простую мигалку, используя PCF8574. Соберите на макетной плате схедующую несложную схему:
Затем наберите такую программу:
Скомпилируйте код и загрузите в чип. Теперь светодиоды моргают как на контроллере, так и на расширителе портов. Но заметьте, что мигают они в противофазе, это потому диод на расширителе подключен катодом к выходу. Когда на выходе 1, то диод с обеих сторон видит напряжение питание, и гореть он не может. Когда на выходе 0, то ток течет через светодиод в лапку расширителя, и диод светится.
Просмотров: 13449 |
Добавил: Chinas
| Рейтинг: 0.0/0
|