Регистр защелка своими руками
Иногда требуется ОЧЕНЬ много выходных портов. Особенно если хотим сделать что нибудь на светодиодах. Гирлянду какую-нибудь навороченную. Что делать? Брать под это дело ATMega128 с ее полусотней выводов? Избыточно — для ламеров. Ставить i 2 с расширитель портов? Дорого. Для мажоров. Тут на помощь из вековых глубин выплывает старая добрая дискретная логика. На этот раз нас выручит грошовый сдвиговый регистр. Возьму, для примера, 74HC164 он же, для любителей совковых трешевых микросхем в неубиваемом каменном корпусе, наш КM555ИР8.
У него есть 8 выходов и четыре входа. R-сброс, С-тактовый, А1 и А2 вход. На самом деле, внутри они заведены через логический элемент 2И-НЕ и идут на D триггеры. D — это такой тип триггера, который по тактовому импульсу схватывает и отправляет на выход то, что у него на входе. Как видишь, тут они цепью стоят ,передавая бит от одного к другому и нет принципиальной разницы сколько их тут будет, восемь штук или восемь миллиардов. Но чем больше, тем дольше по этой эстафете гнать данные до конца. Поэтому мы смело можем эти регистры соединять последовательно.
Получается вот такая схема:
От МК, как видно, требуется только четыре выхода. Одним (RESET) мы сбрасываем состояние регистра. Из второго (Data) побитно вылазит байтик, а тактовый CLC обеспечивает продвижение битов по регистру. Самих регистров тут три. Они сцеплены паровозом. Когда переполняется первый, то биты из него вылазят во второй, потом в третий. Итого, 24 вывода.
Катоды диодов подключены все вместе через транзистор и как только будет слово мы подаем сигнал Ready и зажигаем всю эту ботву.
Наполнять регистр просто:
1) Поднимаем и держим RESET в 1
2) Выдаем первый (старший) бит на Data.
3) Опускаем в 0 и поднимаем в 1 тактовый выход. На восходящем фронте происходит занос в регистр и сдвиг всей цепочки на один шаг.
4) Повторить со второго пункта пока все биты не выдадим.
А для сброса достаточно уронить Reset в ноль на пару микросекунд.
Все просто :)
З.Ы.
Кружок на входе регистра означает, что вход инверсный. Т.е. подал ноль — сработало
Треугольник на входе показывает по какому фронту произойдет срабатывание. Запомнить просто: _/ \_ — это, типа, импульс. А треугольник, как стрелочка, указывает на нужный фронт. ->_/ \_ передний (восходящий фронт) и _/ \_ ИнтерфейсЦифра
Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!
А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.
Схема использует компаратор напряжения с защелкой, который сохраняет состояние превышения предварительно установленной пороговой величины.
При превышении напряжения, поданного на вход "INPUT", заранее установленного с помощью резисторов К1 и R2 значения, выход микросхемы ІС1 переходит на высокий уровень, посредством транзистора Q2 активирует вход "STROBE" (Строб) и препятствует изменению сигнала на выходе на низкий уровень. Высокий уровень на входе "RESET" (Сброс) закрывает транзистор Q1, лишает выход с открытым коллектором микросхемы ІС1 напряжения питания и устраняет условие защелкивания. Компаратор работает с напряжениями питания в диапазоне от +5 до +/-15 В.
. EURASIA HF Championship, 5.02.2022, Суббота, 06-18UTC, CW,SSB, 160-10м. Призы по лоторее. Ткнуть мышью.
Разъём управления режимами SDR-1000 и считывания состояния SDR-1000
Ноги растут из LPT
Надо сказать, что исторически управление трансивером SDR-1000 первоначально было завязано на разъём LPT компьютера, а точнее на адаптер LPT, расположенный в компьютере. Впоследствии с появлением различных способов управления SDR-1000 через USB стало не всегда обязательным вникать в структуру данных LPT, т.к. важнее понимать сам принцип управления SDR-1000. Тем не менее некоторая краткая информация о LPT, адаптированная для нашего случая, будет полезной.
Все три регистра адаптера LPT имеют свои три внутренних адреса в компьютере. К примеру, если в PowerSDR указан порт LPT1 с базовым адресом 378h, то регистр данных адаптера LPT будет иметь этот указанный адрес 378h. Регистр состояния имеет адрес на единицу больше, т.е. 379h. Регистр управления ещё на единицу больше, т.е. 37Ah. На этом краткий экскурс в LPT можно завершить.
Общая информация о сигналах (стробах) C0. C3
Сигналы C0. C3 применительно к SDR-1000 принято называть стробами из-за их короткой длительности. На LPT они существуют в виде импульсов положительной полярности. Передний и задний фронты стробов отстоят друг от друга на очень малое время. По этой причине для управления трансивером можно формировать стробы как положительной, так и отрицательной полярности. В оригинальном SDR-1000 стробы положительной полярности, существующие на LPT, подаются напрямую на регистры-защёлки, т.е. в данном случае рабочий фронт строба - передний (положительный). В SDR-1000UA стробы инвертированы инверторами 74HC14, и поэтому регистры-защёлки защёлкиваются по заднему фронту стробов.
Стробы напрямую завязаны на регистры-защёлки (это две микросхемы 74AC574 для стробов C0, С1 и две микросхемы 74LCX574 для стробов C2, C3). Количество регистров-защёлок равно количеству линий C0. С3, т.е. четыре штуки. Вообще, регистры-защёлки это своего рода ворота для управляющих байтов, поступающих в трансивер. Образно говоря, имеются четверо ворот. Каждая микросхема регистра-защёлки всегда готова отреагировать на появление положительного фронта соответствующего строба. При этом регистр-защёлка запоминает байт, выставленный на линиях D0. D7 разъёма, и выдаёт его на свои выходы. Байт хранится на выходах регистра-защёлки до тех пор, пока не придёт другой строб.
Каждый строб (C0, C1, C2, C3) отвечает за свою группу данных на шине D0. D7. Например, если на шину D0. D7 выставлен один из байтов частоты DDS, то затем следует возникновение строба C2.
Далее будут рассмотрены группы данных на шине D0. D7, за которые отвечают стробы. Самая навороченная группа соответствует стробу C1 и поэтому будет рассмотрена в последнюю очередь. Все фрагменты схем взяты из SDR-1000UA.
Группа данных на шине D0. D7 для строба C0
Ну тут как бы всё просто. При включении строба C0 получаем на выходе байт для управления внешними устройствами через разъём X2. Это внешний усилитель мощности (пин X2_7) и антенный коммутатор (пины X2_1. X2_6). Для справки, пины антенного коммутатора программируются в меню Setup>Ext.Ctrl программы PowerSDR. Кстати, на выходе регистра-защёлки есть ещё сигнал GAIN для переключения усиления в тракте ПЧ на величину 20дб. С точки зрения протокола обмена SDR-1000 совершенно нет необходимости вникать как это всё работает. Просто PowerSDR выставит нужный байт на шину D0. D7 и защёлкнет его в регистре при помощи строба C0.
Группа данных на шине D0. D7 для стробов C2 и C3
Здесь посложнее будет. Два регистра-защёлки призваны обслуживать DDS AD9854. DDS имеет внутри себя регистры для хранения байтов частоты, их там 6 штук. Сами регистры имеют уникальные адресы. Сигналы A0. A5 это и есть двоичный адрес регистров DDS, отвечающих за хранение байтов частоты внутри DDS. Сигналы D0. D7 (не путать с шиной данных SDR-1000) это собственно сами байты частоты, загружаемые в DDS по указанным адресам регистров DDS. Сигнал WR это отрицательный строб, производящий запись байта частоты в DDS по указанному адресу регистра DDS. Сигнал RST положительной полярности просто сбрасывает DDS в исходное состояние при включении оборудования.
Для справки (с точки зрения протокола обмена SDR-1000 в это сильно вникать не надо), каждая записываемая в DDS частота преобразуется программой PowerSDR по формуле в нужный код и разбивается на шесть байтов. Для примера возьмём частоту 3495275 Гц (3,495275 МГц):
(3495275 x 281474976710656) / 200000000 = 4919162246111(округлено до целого) и преобразуем в шестнадцатиричное 047954EB13DFh.
В формуле число 281474976710656 это 2^48 (разрядность аккумулятора фазы DDS AD9854), а число 200000000 это внутренняя частота DDS (200 МГц).
Итак, мы получили шестнадцатиричное число 047954EB13DFh. Вот его-то и посылает PowerSDR в DDS побайтно начиная с старшего байта - сначала 04h, далее 79h, 54h, EBh, 13h, DFh. Всего шесть байтов частоты по количеству регистров частоты. Адресы регистров частоты в DDS соответственно 04h, 05h, 06h, 07h, 08h, 09h.
Рассмотрим поведение PowerSDR при загрузке в один из регистров частоты DDS одного байта частоты. Надо сразу сказать, что сигнал записи WR является битом в байте адреса регистра частоты (особенность схемы SDR-1000), что вынуждает три раза устанавливать адрес регистра на шину данных SDR-1000 при манипуляциях с битом WR (не удобно, но ничего не поделаешь):
1. Установка байта частоты на шину данных SDR-1000.
2. Включение и выключение строба C2 для защёлкивания байта частоты в соответствующем регистре-защёлке.
3. Установка на шину данных SDR-1000 адреса соответствующего регистра частоты DDS.
4. Включение и выключение строба C3 для защёлкивания адреса в соответствующем регистре-защёлке.
5. Снова установка на шину данных SDR-1000 адреса регистра DDS, но бит WR переведён в активное состояние.
6. Включение и выключение строба C3 для защёлкивания (ещё раз!) адреса в регистре-защёлке. Так как бит WR в активном состоянии, то произошла запись байта частоты в регистр DDS. Результат достигнут!
7. Снова установка на шину данных SDR-1000 адреса регистра DDS, но бит WR возвращён в неактивное состояние.
8. Включение и выключение строба C3 для защёлкивания (ещё раз!) адреса в регистре-защёлке.
Для справки. Вообще-то описанный выше порядок действий несколько стилизованный. Анализ сигналов показывает, что PowerSDR просто обожает оставлять строб C3 в единичном активном уровне после защёлкивания байта в регистр-защёлку. И только когда требуется ещё что-нибудь защёлкнуть, то строб переводится в нулевое неактивное состояние, а затем сразу в единичное. Выше я уже говорил, что полярность стробов в принципе не имеет значения, поэтому описанное в этом абзаце просто примите к сведению.
Группа данных на шине D0. D7 для строба C1
Это cамая навороченная группа данных на шине D0. D7. Для начала посмотрим на регистр-защёлку, которая защёлкивает необходимые байты при поступлении рабочего фронта строба C1. Бит "приём-передача" (RX=0, TX=1) и бит MUTE (запрещает звук от приёмника) являются простыми сигналами. Остальные биты (SER, SCK, SCLR, A0, A1, DCDR) управляют сдвиговыми регистрами, о которых будет речь далее. Схема №1:
А вот и схема №2 монстра со сдвиговыми регистрами. Чтобы понять как это работает, надо приложить некоторые умственные усилия:
Теперь перейдём к общим рассуждениям о работе схемы сдвиговых регистров. Задвигаемый байт побитно записывается сразу во все сдвиговые регистры. Но только одному регистру будет разрешено выдать задвинутый байт на свои выходы. Иначе говоря, всякий задвигаемый байт соответствует только своему регистру. Выбор регистра производится дешифратором 74HC139.
Дешифратор 74HC139 управляется двоичным двухразрядным кодом и имеет инверсные выходы. Сигнал DCDR разрешает дешифратору выдать нулевой уровень на один из выходов. Значение двоичного кода на входах A0 и A1 определяет на каком из выходов появится нулевой уровень. Если сигнал DCDR находится в единичном уровне, то дешифратор не работает и на всех его выходах присутствует единичный уровень.
Чтобы дешифратор 74HC139 выбрал требуемый сдвиговый регистр, необходимо сначала установить код A0 и A1 на входах дешифратора, затем переключить DCDR в нулевой уровень, и наконец вернуть DCDR в единичный уровень.
Надеюсь, теперь понятно что, чтобы изменить всего лишь один бит на выходе одного из сдвиговых регистров (например включить аттенюатор) следует произвести кучу действий с кучей байтов. При этом изменение всего лишь одного бита потребует прописывания заново всех остальных битов на выходах этого сдвигового регистра.
Примерный порядок действий следующий:
1. Выставить байт XX10000X на шину данных D0. D7 (схема №1). Два старших бита не надо трогать, их значение нужно взять из предыдущей операции. Младший бит это информационный бит SER, который надо задвинуть в сдвиговые регистры в схеме №2. По стробу C1 байт защёлкнется в регистр-защёлку.
2. Выставить тот же байт на шину данных D0. D7, но бит SCK должен быть переведён в единичное состояние. По стробу C1 байт защёлкнется в регистр-защёлку. В результате информационный бит SER будет записан в сдвиговые регистры (схема №2).
3. Выставить тот же байт на шину данных D0. D7, но бит SCK должен быть переведён в исходное нулевое состояние. По стробу C1 байт защёлкнется в регистр-защёлку.
4. Повторить пункты 1,2,3 семь раз для каждого нового информационного бита SER. Итого будет восемь битов SER.
5. Выставить байт XX100000 на шину данных D0. D7, в котором установить нужные значения битов A0 и A1 для выбора нужного сдвигового регистра в схема №2. По стробу C1 байт защёлкнется в регистр-защёлку.
6. Выставить тот же байт на шину данных D0. D7, но бит DCDR должен быть переведён в нулевое состояние. По стробу C1 байт защёлкнется в регистр-защёлку.
7. Выставить тот же байт на шину данных D0. D7, но бит DCDR должен быть переведён в исходное единичное состояние. По стробу C1 байт защёлкнется в регистр-защёлку. В результате задвинутый во все регистры байт появится на выходах только одного нужного сдвигового регистра.
Получение байта состояния трансивера
Программа PowerSDR постоянно отслеживает состояние SDR-1000, получая сигналы S3. S7 в виде байта (младшие биты 0. 2 игнорируются) с периодичностью около 4 мс (время определено опытным путём и не является абсолютно достоверной информацией). Смотрим схему ниже.
Сигнал S3 - блокировка приёма при помощи внешнего сигнала на разъёме X2 "Ext Control". Крайне скудная информация об этом сигнале в связи с его практической невостребованностью.
Сигналы S4,S5 - обслуживание телеграфного ключа (простого и автоматического). В современных версиях PowerSDR эти сигналы не обрабатываются (исключены) в связи с большими временными задержками при обслуживании ключа. Ключ следует подключать на COM-порт компьютера (смотреть документацию на SDR-1000).
Сигнал S6 - в режиме передачи обслуживание АЦП измерителя мощности и КСВ. АЦП присутствует в оригинальном SDR-1000, но отсутствует в SDR-1000UA, где установлен только разъём для стыковки с АЦП. Ничего не мешает изготовить дополнительный модуль АЦП и встроить его в SDR-1000UA.
Сигнал S7 - педаль включения передачи.
Обслуживание АЦП (измеритель КСВ и мощности)
Показанная ниже схема является выжимкой из схемы оригинального SDR-1000 и схемы SDR-1000UA.
Программа PowerSDR обслуживает АЦП только в режиме передачи при помощи регистра DD19 в SDR-1000UA. Принцип управления регистрами описан выше, в параграфе " Группа данных на шине D0. D7 для строба C1".
Для управления АЦП используются следующие сигналы: ADC CLK для тактирования АЦП; ADC DI для выбора конфигурации АЦП и метода измерения (сказано громко, но на самом деле там всё просто); ADC CS для разрешения работы АЦП. Результат измерения (сигнал S6) выводится на разъём LPT в виде последовательного байта. При измерении КСВ обслуживание АЦП производится дважды, т.е. для падающей волны и для отражённой волны, а при измерении мощности только для падающей волны. Показанный на схеме дополнительный узел на транзисторе (в SDR-1000UA этот узел отсутствует) предназначен для сигнализации программе PowerSDR, что внешнее автоматическое согласующее устройство находится в режиме активной настройки.
Ниже показана диаграмма сигналов АЦП, взятая из даташита.
- Процесс обслуживания АЦП начинается с установки нулевого уровня сигнала ADC CS, разрешающего работу АЦП. Далее на информационный вход ADC DI устанавливают единичный уровень и подают положительный фронт тактового сигнала ADC CLK. В результате АЦП, приняв этот START BIT, оживает и ждёт сигналы конфигурации.
- Затем на информационный вход ADC DI устанавливают снова единичный уровень и подают следующий положительный фронт тактового сигнала ADC CLK. В результате в АЦП устанавливается конфигурация - "два независимых аналоговых входа". Один вход для падающей волны, а другой для отражённой.
- Далее на информационный вход ADC DI устанавливают нулевой или единичный уровень в зависимости от того, на каком аналоговом входе необходимо произвести измерение - на входе падающей волны или на входе отражённой волны (или наоборот, точно не помню). При этом подают очередной положительный фронт тактового сигнала ADC CLK.
- Затем отрицательный фронт тактового сигнала ADC CLK переводит выход АЦП из третьего (высокоимпедансного) состояния в нулевое состояние, а последующие тактовые импульсы выводят последовательно биты байта измерения на выход АЦП. Заметьте, что сначала выводится байт с первым старшим битом, а затем байт дублируется, но уже с первым младшим битом. Я не знаю как в этом случае поступает PowerSDR - использует оба байта, или только один. Ведь по идее достаточно вывести только первый байт с первым старшим битом и завершить работу установкой ADC CS в единичное состояние.
Ситуация, когда в микроконтроллере не хватает выходов, встречается довольно часто. Для решения подобной проблемы воспользуемся сдвиговым регистром 74HC595.
74HC595 — восьмиразрядный сдвиговый регистр с последовательным вводом, последовательным/параллельным выводом информации, с триггером-защелкой и тремя состояниями на выходах регистра.
Регистр контролирует 8 выходов, занимая всего 3 выхода микроконтроллера. Кроме этого можно собрать каскад из нескольких таких регистров.
Регистр может выдавать полученные сигналы параллельно или последовательно. Последовательная передача бит необходимо при каскадировании нескольких регистров. Первые 8 бит сигнала передаются на следующий регистр для дальнейшего параллельного вывода информации.
Выходы регистра могут быть в одном из трёх состояний:
- логический ноль;
- логическая единица;
- высокоомное (высокоимпедансное) состояние.
В высокоомном состоянии выходы отключены от схемы. Отключить можно только все выхода регистра вместе (по одному нельзя).
В исходном состоянии выводы регистра находятся в высокоомном состоянии. Это значит, что другие элементы могут изменять напряжение на них, не влияя на работоспособность и логику микросхемы. Это может быть полезно, если одними и теми же элементами планируется управлять при помощи разных регистров — когда активен один (сигнал LOW на входе OE), следует перевести второй в высокоомное состояние (сигнал HIGH на входе OE). Если регистр всего один, можно смело подключать OE к земле. Также к земле подключается выход GND. Для нормального функционирования регистра также следует подключить вход MR к рельсе питания. Туда же подключаем Vcc.
К минусам использования сдвигового регистра стоит отнести невозможность использования широтно-импульсной модуляции (ШИМ), потому что выходы регистра могут иметь только логические значения HIGH (1) и LOW (0).
Распиновка входов/выходов регистра
Регистр работает на интерфейсе SPI: выводы DS, ST_CP, SH_CP — это шины управления.
Соберём стенд с одним сдвиговым регистром.
- GND (пин 8) на землю;
- Vcc (пин 16) к питанию 5В;
- OE (пин 13) на землю;
- MR (пин 10) к питанию 5В;
Подадим питание на регистр и сделаем выходы активными. При таком подключении в момент подачи питания на схему на выходах будут случайные значения. Можно контролировать выводы MR и OE непосредственно с Arduino (обнуляя входы и/или подключая выходы в нужный момент). Но не стоит из-за этого нервничать, так как значения регистра и выводов будут перезаписаны, как только программа начнёт работать.
Для начала следует отметить, что библиотека SPI в данном примере использоваться не будет.
В место неё будет использовать функцию shiftOut() — выводит байт информации на порт вход/выхода последовательно (побитно).
У функции всего четыре параметра:
Объявим переменные и присвоим им соответствующие значения.
После этого отправим на регистр байт. Для этого снимем защёлку (ставим LOW) — начинаём передачу данных (регистр принимает сигналы с Arduino).
Отправляем данные (отправляем байт в цифровом или двоичном виде) = 0b00000001.
В конце ставим защёлку (ставим HIGH) — заканчиваем передачу.
В итоге весь наш код имеет следующий вид:
Заливаем прошивку в контроллер. Смотрим на результат.
Непосредственно управление регистром осуществляется с помощью входов DS, SH_CP и ST_CP. Когда происходит переключение SH_CP (clockPin) с LOW на HIGH, в регистр считывается значение с DS (1 бит). При переключении ST_CP (latchPin) с LOW на HIGH заканчивается прием информации и выводы переходят в назначенное состояние.
Напишем функцию (вместо 3-х строк) для оптимизации кода:
Чтобы использовать регистр, как расширитель портов, нужно управлять каждым разрядом по-отдельности.
Напишем под него функцию, что будет принимать 2 параметра: номер разряда и уровень, который нужно этому разряду присвоить: HIGH или LOW.
Микроконтроллер начинает отсчёт с нуля. Чтобы не было путаницы будем отнимать единицу от номера текущего разряда. Другими словами — пользователь работает с 1 — 8 разрядами, а контроллер воспринимает это, как работу с 0 — 7.
Перезаписываем изменения в массиве:
Формируем байт (из 8 битов) и отправляем его на регистр. Объявляем переменные: value — формируемый байт (по умолчанию с нулевым значением); add — хранить байт текущего разряда.
Проверяем очередной разряд в массиве. Если он должен иметь высокий уровень, то прибавляем к переменной value переменную add и переходим на следующий разряд.
Включаем 1, 4, 5 и 8 разряды по-отдельности.
Для очистки регистра напишем функцию и вызовем её в setup (в программах представленных в статье — эта функция не использовалась):
Регистру можно отправлять только полный байт (8 бит — 0b00000000). Чтобы изменить состояние одного разряда регистра (включить или выключить) нужно послать ранее отправленный байт с изменением одного нужного бита.
Программа-счётчик выводит значения байта от 0 до 255 в двоичной системе счислений.
Читайте также: