Например TDA7294

РадиоКот > Схемы > Цифровые устройства > Бытовая техника

Термометр со шкальным индикатором

Автор: uldemir
Опубликовано 26.03.2014.
Создано при помощи КотоРед.

Кто-то скажет: “опять термометр”. Хотя эта конструкция вряд ли предназначена для повторения. Скорее, это просто был тренировочный полигон, для закрепления изученного материала. Таким образом, я надеюсь, этот рассказ будет интересен тем, кто, как и я делает первые шаги в изучении языка VHDL для программирования ПЛИС. Поэтому, хотя это почти законченная конструкция, проще и дешевле её было бы изготовить на базе микроконтроллера. А так, её можно использовать, чтобы потренироваться на какой из готовых “отладочных” плат.

 

Когда появилась возможность приобрести шкальный индикатор BG12201 с самосканированием, возник вопрос: "А чтобы эдакое на нём собрать?". А в это же время на форуме прозвучала мысль про термометр на таком индикаторе. Сделать термометр не проблема - один микроконтроллер справится со всем. Но подумалось, что хорошо бы индикатор подключить с использованием CPLD. Тем не менее, ставить микроконтроллер для измерения температуры и CPLD для отображения, чтобы удовлетворить мечту, казалось не разумным. Зачем CPLD, если микроконтроллера и так, более чем хватает. И тут во время ночной бессонницы родилась бредовая идея - а может, всё же, обойтись без... микроконтроллера? В качестве температурного датчика применить широкораспространённый ds18s20 (ds18b20) и обработку протокола 1-wire сделать аппаратно, на железной логике в CPLD. Таким образом и родилась конструкция двухканального термометра со шкальным индикатором.

 

Театр, как известно, начинается с вешалки. Радиотехническая конструкция - с источника питания. Эта конструкция питается от стандартных 12 вольт постоянного тока. При помощи линейного стабилизатора LM1117-33 из них получается 3.3в для питания логической части и далее с помощью LDO стабилизатора LP2985-18 из 3.3 вольт получаем 1.8 вольт для питания ядра CPLD. Питание индикатора обеспечивается обратноходовым преобразователем на таймере NE555. Для питания индикатора необходимо 250 вольт анодного напряжения. Но для правильной работы, необходима так же подача напряжения смещения на катоды порядка 72-х вольт и 100 вольт на выключенные аноды. Все эти напряжения снимаются с отводов того же трансформатора, на котором формируется 250 вольт. Использованный преобразователь описан на сайте dos4ever.com. Обратная связь заведена с наиболее потребляющего напряжения - 250 вольт.


Схема тактируется от RC-генератора на микросхеме LTC6090 - она способна генерировать довольно стабильные импульсы в широком диапазоне частот и имеет встроенные делители частоты на 10 и 100. В данной схеме элементами R26, C3 она настроена на генерацию частоты около 1МГц, что обеспечивает каждый такт с интервалом в 1 мкс.

На транзисторах VT3 - VT6 собран интерфейс 1-wire. Транзисторы VT5 и VT6 формируют низкий уровень на шинах (обоих одновременно), а транзисторы VT3 и VT4 предназначены для обеспечения сильной подтяжки (strong pull up) на этих же шинах во время выполнения датчиками температурного преобразования при паразитном питании. Резистор R12 не позволяет открыться этим транзисторам при включении во время переходных процессов (просто перестраховка - на неинициализированных выходах CPLD xc2c256 наличиствует подтяжка к плюсу питания).

 

На транзисторах VT11 - VT14 выполнены катодные ключи. Когда соответствующий ключ открыт на катод индикатора подается низкий потенциал. При закрытом ключе через резисторы R22-R25 на катоды подается напряжение смещения 72 вольта. На аноды индикатора подается или 100 вольт смещения через диоды VD5 и VD6, или 250 вольт, если открываются анодные ключи VT8, VT10.

 

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

 

Схема, запрограммированная в логическую матрицу описывалась на языке VHDL. Сборка проекта производилась с помощью ISE WebPack версии 9.2i или позднее. Для облегчения ознакомления с логикой приведена часть структурной схемы на рисунке - это только интерфейс взаимодействия с термодатчиком. Названия на структурной схеме совпадают с названиями сигналов в исходном тексте.

Блок 1-wire предназначен для формирования временных интервалов на выходе owout. В зависимости от сигнала wr_res модуль формирует или сброс, или слот данных. Он содержит 10-ти разрядный счетчик counter, который запускается сигналом ow_run и этот сигнал снимается по окончании отсчета. Длительность отсчета зависит от сигнала wr_res. Если выполняется слот данных, то в начале цикла активизируется сигнал owout, который откроет транзисторы VT5, VT6, которые в свою очередь притянут шины к низкому уровню. Этот уровень сохранится или только одну микросекунду, если надо вывести лог.1 или дольше (90 мкс, допустимо от 60 до 120 мкс), если надо вывести лог.0, в зависимости от сигнала dataout. Для выполнения чтения - просто выполняется запись лог.1, а на, примерно, 12-й микросекунде состояние линии owin защелкивается в триггере и из триггера выводится на шину datain. Сигнал с datain поступает на два сдвиговых регистра: простой - tempshift, где накапливается температура, и с обратными связями для подсчета crc, где считается контрольная сумма. Для иллюстрации привожу диаграммы из даташита на термодатчик. Сами даташиты легко находятся на сайте производителя www.maximintegrated.com.

 

Если выполняется сброс, то сигнал owout удерживает линию более 480 мкс (выбрано 512мкс) на низком уровне и затем, не менее 480 мкс линия остаётся в высоком, во время которого датчик должен сообщить о своём присутствии выдав presence pulse, который в этой конструкции просто игнорируется (наличие отсутствия датчика определяется по ошибочной контрольной сумме во время считывания температуры.

 

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

  • Сброс
  • 0xCC (skip_rom)
  • 0x44 (convert_T)
  • теперь надо ждать окончания конвертации или опрашивая статус датчика, или просто отмеряя временной интервал.
  • Сброс
  • 0xCC (skip_rom)
  • 0xBE (read scratch pad)

после чего надо прочитать 9 байт, подсчитывая CRC, которая по окончании должна быть равна 0.

 

Температура для каждого из датчиков ds18b20 и ds18s20 имеет несколько отличающийся формат. ds18b20 выдаёт формат с более высокой разрешающей способностью, но так как отображаться температура будет только с точностью в пол-градуса, младшие разряды можно просто опустить. (Далее в таблице упоминается еще датчик ds1822. Он был добавлен позже, поэтому в таблицах фигурирует, а в тексте часто оказывается забыт. Извините.) Из-за этого необходимо в сдвиговый регистр температуры задвигать биты из разных мест в потоке. Но прежде, необходимо выяснить с каким датчиком имеем дело. Для этого до начала преобразования температуры производится чтение сериального номера устройства командой 0x33 (read_rom). Сериальный номер начинается c кода семейства, далее следует 48-ми битный сериальный номер и завершается 8-ми битной контрольной суммой. Из всего этого нас интересует только код семейства, который для ds18b20 имеет значение 0x28, для ds18s20 - 0x10, а для ds1822 - 0x22. Так как данные передаются начиная с младшего бита, отличие видно уже на 4-м бите:

ds18b20 0 0 0 1 0 1 0 0
ds1822 0 1 0 0 0 1 0 0
ds18s20 0 0 0 0 1 0 0 0

Поэтому из всего номера считываем первые 4 бита и по 4-му биту устанавливаем флаг sensortype, который для ds18b20 равен лог.1. Алгоритм прост: если за эти 4 считывания была хоть одна лог.1 - предполагаем датчик с повышенной разрядностью, если нет - то это ds18s20. Остальные данные не считываются, а выполняется сброс шины для передачи команды выполнения преобразования температуры. Формат температуры для разных датчиков выглядит следующим образом:

ds18b20

ds1822

2-4 2-3 2-2 2-1 20 21 22 23 24 25 26 S S S S S

ds18s20

2-1 20 21 22 23 24 25 26 S S S S S S S S

Для отображения используются только 9 бит с 2-1 до первого знакового "S" (выделены цветом). Поэтому для ds18b20 заполнение буфера следовало бы начать пропустив первые три бита из прочитанного scratchpad. Но, для упрощения, чтение начинается одинаково для обоих видов сенсоров, а вот завершение разделяется. Лишние биты сами вывалятся из регистра. Всё время чтения scratchpad данные параллельно засылаются в регистр CRC, где накапливается циклическая контрольная сумма. По окончании чтения scratchpad в регистре содержится контрольная сумма. Проверка на совпадение производится классическим способом используя особенное свойство CRC: если к потоку добавить контрольную сумму этого потока, то общий CRC будет равен нулю. Поэтому после считывания идущего следом значения CRC при правильном чтении, в регистрах должны быть одни нули. Если хоть один бит не равен нулю, на выход crcerror подаётся низкий логический уровень зажигающий красный светодиод, индицирующий недостоверность считанных данных.

 

Последовательной подачей управляющих сигналов на эти модули занимается модуль микрокоманд. Весь микрокод состоит из чуть менее 256 состояний (восьмиразрядный счетчик). Состояние сохраняется в счетчике state. Типовой шаг состоит из двух состояний. В первом (обычно четном) состоянии устанавливаются необходимые сигналы (например, wr_res и ow_run) для запуска необходимого процесса (в данном случае сброс шины 1-wire), а во втором шаге ожидается его выполнение (снятие сигнала ow_run). Второй такой модуль, который сообщает о завершении своей работы - модуль временной задержки (delaycnt). Он ничего не делает, пока его состояние равно нулю. Если туда записать какое-либо число, счетчик начнёт уменьшать своё значение с каждым циклом сканирования шкалы, который занимает около 15 мс, пока не досчитает до 0. Остальные модули: CRC и tempshift, выполняют свои действия за один такт и никакого сигнала готовности не генерируют.

 

Эта схема легко масштабируется и может одновременно управлять сразу несколькими шинами 1-wire. В конкретной схеме используется шкальный дисплей с 2-мя шкалами, и, соответственно, нужны два датчика и два канала обработки. Поэтому присутствуют сигналы owin, datain и модули tempshift, crc в двух экземплярах.

 

По окончании чтения scratchpad, если контрольная сумма равна нулю - результат, находящийся в tempshift можно использовать для отображения температуры. При отладке это значение выводилось на 4-х значный семисегментный светодиодный индикатор. Но в данной конструкции, этот результат передаётся узлу управляющему шкальным индикатором. Для отображения результат переносится из tempshift1 в scale1reg, а из tempshift2 в scale2reg путём прибавления смещения, определяющего, где на шкале будет 0 градусов цельсия. Так как шкала содержит 201 элемент, и было решено, что элементы будут отличаться на пол-градуса, шкала способна отобразить интервал в 100 градусов. Было выбрано отображать интервал от -45 до +55 градусов, как наиболее реальный диапазон для бытового термометра. Разумеется, в исходном коде легко сместить этот диапазон. Однако, следует помнить, что у датчика нижняя граница -55 градусов, а верхняя, в данной конструкции ограничена использованием паразитного питания датчика, при котором на высоких температурах увеличивается погрешность (при нормальном питании максимум +125). Таким образом к значению tempshift прибавляется смещение шкалы и результат записывается в scale1reg (или scale2reg). Далее в тексте я их буду называть scaleXreg, подразумевая, что это относится как к scale1reg, так и к scale2reg.

 

9-й разряд регистра scaleXreg, является признаком переполнения. Если он установлен в “1”, то в таком случае шкала не зажигается. Этот бит устанавливается также принудительно в случае ошибки CRC. Это было задумано с целью, если отрицательная температура ниже отображаемого пространства, то “столбик” термометра опускается ниже видимого. При температуре превышающей - светится вся шкала. Конечно, если температура сильно превышает максимум (где-то на 30 с лишним градусов), тоже происходит переполнение и шкала гаснет. Но так как это сильно за пределами расчетного диапазона измерений - дефектом можно не считать.

 

Для работы шкалы с самосканированием, на её катоды надо подавать определённую последовательность импульсов. В самом начале надо подать низкий потенциал на катод сброса (cathodes(0)) и удерживать его 140 микросекунд. Затем этот уровень снимается с катода сброса и подаётся на первый катод (cathodes(1)), где он должен быть 70 микросекунд. Далее, аналогично, низкий потенциал подаётся на второй и третий катоды, на каждом удерживаясь по 70 микросекунд. Следующий катод, на который будет подан низкий потенциал - снова первый, затем второй, третий и снова первый. Во время такого переключения облако ионизированного газа будет перемещаться от одного катода к соседнему. Такая последовательность должна повторяться до тех пор, пока не будет просканирован 201 элемент, после чего цикл начинается по-новой с катода сброса, чтобы зажегся сегмент в самом начале шкалы.

 

Шкала будет освещена, пока наличествует анодное напряжение конкретной шкалы. Для того, чтобы шкала светилась только до определенного места, когда облако ионизированного газа достигнет его, необходимо снять анодное напряжение. Таким образом, при сканировании, постоянно инкрементируется счетчик scan и его значение сравнивается со значением scaleXreg. Как только оно будет превышено - с соответствующего анода (anodes(0) или anodes(1)) напряжение снимается.

 

Это базовая работа со шкалой. Однако, у газоразрядных приборов существует небольшая проблема - если какой из катодов долго не горит, а поблизости горит другой катод, не горящий катод “отравляется” распыляемым металлом с работающего катода, и со временем, зажигание этого катода может стать затруднённым. Это будет выражаться в том, что шкала больше “не захочет” зажигаться там, где она долго не горела. Поэтому в такого рода устройствах необходимо предусмотреть процедуру “антиотравления”, которая на некоторое время будет зажигать все элементы, чтобы сохранить их дальнейшую работоспособность. Это происходит с периодом в 32 измерения температуры. После 32-го измерения, индикатор не отображает температуру, а последовательно зажигает и гасит шкалы (screensaver), до выполнения следующего замера.

 

Для облегчения считывания шкалы, SLvik на форуме предложил некоторые элементы “выделять” яркостью. Яркость увеличивается за счет того, что сегменты засвечиваются не на 70 мкс, а на более долгое время (константы bold, semibold). Так как такой режим не является паспортным, чтобы сегменты постоянно светящиеся более ярко “не пригорели”, после каждой отработки “screensavera” шкала сдвигается на один элемент и соответственно, изменяется смещение прибавляемое к значению регистра tempshift при записи регистра scaleXreg. Во время работы “screensavera” выделение шкалы выключается.

 

Интерфейс 1-wire сделан “классически” с транзисторами по причине большого числа свободных выводов у ПЛИС, чтобы эти два входа не выглядели уж больно одиноко. Для макетирования вполне можно поменять тип выводов owin и отказаться от выходов owout и spullup. Для этого необходимо вывод выполнить в виде ввода/вывода с третьим состоянием. В заголовке для этого входы следует описать как “owin1 inout STD_LOGIC; owin2 inout STD_LOGIC;” и переместить описание spullup и owout в раздел сигналов. Далее размещаем следующий код:

 

owin1 <= ‘1’ when spullup=’1’ else ‘0’ when owout=’1’ else ‘Z’;
owin2 <= ‘1’ when spullup=’1’ else ‘0’ when owout=’1’ else ‘Z’;

 

Таким образом, можно датчик присоединить прямиком. Единственное, что требуется - резистор подтяжки. Но и его можно попробовать заменить, запрограммировав у кристалла подтяжку pullup (у тех, у которых есть такая возможность). Правда, это только мои теоретические домыслы - на практике еще проверены не были.

 

Как уже упоминалось, схема рассчитывалась на индикатор производства Burrough BG12201. Но при желании, её можно адаптировать под любой другой шкальный индикатор с самосканированием, и даже, отечественного производства. Конкретно, автор попытался вполне успешно подключить ИН-34-1, снизив разрешение отображения температуры до одного градуса на деление. Аналогично, не представляется проблемой применение других индикаторов подобного типа. Для тех индикаторов, у которых не 3 группы катодов, а 5 (например, ИН-36) - необходимо добавить еще пару катодных ключей, а регистр thriphase увеличить на те же 2 регистра, и обеспечить необходимую логику переключений. Разумеется, необходимо так же подстроить блок питания, чтобы он выдавал необходимые напряжения для выбранного индикатора.

 

Проект также возможно перенести на CPLD и FPGA других типов. В схеме используется CPLD xc2c256 и на таком же кристалле термометр запускался на плате CoolrunnerII Starter Kit, путём подключения к разъёму периферии маленькой макетной платы, с установленным транзистором, резистором подтяжки и термодатчиком. Эта же макетная плата и проект, позже удачно были запущены на плате от Digilent “BASYS2”, на которой установлена FPGA Spartan-3E xc3s500. Поэтому, возможно попробовать этот проект перенести и на другие типы ПЛИС имеющих достаточные ресурсы.

 

На случай, если кто захочет повторить эту конструкцию приложены файлы проектов Eagle CAD. Трансформатор наматывается на каркасе под сердечник типоразмера EFD20. Первичная обмотка содержит 25 витков провода диаметром 0.45мм, вторичная 288 витков проводом 0.12мм, с отводами от 85-го и 117-го витков. Сердечник берется из материала N87 производства EPCOS с зазором 0.25мм в центральном керне.


Файлы:
Eagle v6 project
Исходный текст VHDL


Все вопросы в Форум.


ID: 1902

Как вам эта статья?

 Нравится
 Так себе
 Не нравится

Заработало ли это устройство у вас?

 Заработало сразу
 Заработало после плясок с бубном
 Не заработало совсем

51 5 7
1
Подробно