Перейдем теперь к описанию цифровой части схемы Рисунок 1.
Для программирования микроконтроллера имеются две возможности.
Первая – с помощью адаптера USB DEBUG по двухпроводному интерфейсу C2. Для этого используется 3-контактный разъем XB. На этот разъем подаются сигналы C2D, RST/C2CK и «земля». Эти сигналы подаются из USB DEBUG-адаптера по кабелю, на одном конце которого расположен ответный 3-контактный разъем, а на втором – ответный 10-контактный разъем (SCM10), который подключается к выходному 10-контактному разъему JTAG (IDC-10) USB DEBUG-адаптера. Схему такого кабеля можно найти в [1, 3, 4]. С разъема XB сигналы RST/C2CK и C2D поступают, соответственно, на выводы 5 и 6 МК. RC-цепочка R1, R2, C1 предназначена как для штатной работы микроконтроллера, так и для режима программирования по интерфейсу C2.
Вторая возможность программирования микроконтроллера – с помощью встроенного загрузчика (boot_loader) программ по UART0 (TTL-вариант интерфейса RS-232). В этом случае используется разъем XRS. На этот разъем выведены сигналы TxDM, RxDM, напряжение питания +3.5 В и «земля». К разъему XRS подключается плата-переходник (ее разводка приведена далее), а к этой плате подключается одноканальный преобразователь уровней интерфейса RS-232 в уровни TTL и обратно. Схему и разводку платы такого преобразователя можно найти в [4, 5]. Эта плата подключается к COM-порту компьютера (COM1) кабелем по схеме, также приведенной в [5]. Там же подробно описана методика программирования микроконтроллера EFM8LB12 с COM-порта компьютера. Для программирования микроконтроллера с помощью встроенного загрузчика программ boot_loader’а необходимо заземлить сигнал C2D в разъеме XB. Для этого на контакты 1 и 2 разъема XB необходимо установить перемычку (джампер). Справа от разъема XB это показано пунктиром, рядом с которым написано слово «boot» (Рисунок 1).
Для сопряжения микроконтроллера с ЖКИ используется интерфейс SPI. Для этого предназначен 6-штырьковый разъем XЖ. На этот разъем выведены сигналы MOSI и SCK интерфейса SPI, 2 сигнала выбора кристалла: CSML, CSST, напряжение питания +3.5 В и «земля». С платой ЖКИ (см. далее) плата вольтметра соединяется кабелем, на одном конце которого расположен ответный 6-контактный разъем XЖК (Рисунок 2а). Этим разъемом кабель подключается к плате вольтметра (Рисунок 1). На втором конце кабеля расположен 6-контактный разъем XЖ1К. Этим разъемом кабель подключается к плате ЖКИ (см. далее).
Для калибровки нуля и полной шкалы АЦП используются два разъема: XC1 и XC2. При калибровке нуля контакты 2 и 3 разъема XC1 и контакты 1 и 2 разъема XC2 необходимо замкнуть, для чего на них требуется надеть перемычки (джамперы). В этом случае на вход АЦП будет подан нулевой (земляной) потенциал, а сигнал CAL0 (вывод 12 DD1) установится в состояние лог. 0. Это нулевое состояние сигнала CAL0 после включения питания приведет к тому, что будет запущена подпрограмма калибровки нуля.
При калибровке полной шкалы на контакты 1 и 2 разъема XC1 и контакты 2 и 3 разъема XC2 необходимо надеть перемычки (джамперы). В этом случае на вход АЦП будет подано опорное напряжение Vref (3 В), а сигнал CAL1 установится в состояние лог. 0. Это нулевое состояние сигнала CAL1 после включения питания приведет к тому, что будет запущена подпрограмма калибровки полной шкалы. Подробная методика калибровки нуля и полной шкалы будет приведена в разделе статьи о настройке устройства (см. далее).
Рисунок 4. | Принципиальная схема сопряжения ЖКИ ИЖЦ-13-8-7 с контроллерами КР1820ВГ1. |
Схема сопряжения ЖКИ ИЖЦ 13-8-7 с двумя контроллерами КР1820ВГ1 и с МК (Рисунок 4) достаточно проста. Это известная схема, которая приводится, например, в [6, 7]. Несмотря на большое количество проводов, схема легко разводится (см. далее), при этом размер платы примерно в 1.5 раза меньше размера самого ЖКИ. Хотя дисплею ИЖЦ 13-8-7 уже около 30 лет (первое упоминание о микросхеме КР1820ВГ1 и подобном ЖКИ, насколько это известно автору, было еще в 1990 году [8]), автор выбрал именно этот ЖКИ благодаря следующим его особенностям:
- Размер цифр довольно большой и по высоте составляет около 14 мм, благодаря чему цифры легко читаются.
- Максимальный контраст ЖКИ имеет при питании 3-4 В, что как нельзя лучше подходит к напряжению батарейки (3.5 В).
- ЖКИ имеет достаточно широкий угол обзора.
- Для сопряжения с микроконтроллером по интерфейсу SPI устройству требуется всего 6 проводов (включая питание и «землю»).
- Потребление тока устройством составляет не более 200 мкА (см. далее).
- Устройство уникально просто программируется (об это см. ниже), а значит, не требует от микроконтроллера большого объема программной памяти (и больших усилий программиста).
- Стоимость ИЖЦ 13-8-7 составляет не более 200 – 300 руб., а стоимость КР1820ВГ1 – не более 30 руб. ЖКИ и контроллеры достаточно распространены, и их легко приобрести.
Единственный недостаток устройства – для него требуется плата сопряжения по схеме Рисунок 4.
В настоящее время существует масса современных ЖКИ с уже встроенным контроллером. Однако, хотя они и имеют некоторые из особенностей, перечисленных выше, но ни одного современного ЖКИ со встроенным контроллером, который бы обладал всеми вместе перечисленными свойствами, автору найти не удалось. Поэтому автор и выбрал этот ЖКИ.
Хотя подпрограмма вывода информации на дисплей входит в общую программу для микроконтроллера (ее уже оттранслированный вариант в hex-формате можно скачать из дополнительных материалов к статье на сайте журнала), для понимания сути работы дисплея автору хотелось бы привести три ключевых момента его функционирования, тем более, что они в некоторой степени касаются схемы на Рисунке 4.
Первый момент касается принципа вывода цифр на дисплей.
Каждая цифра ЖКИ состоит из 7 сегментов, обозначенных буквами А – G, десятичная точка рядом с цифрой – еще один (восьмой) сегмент, обозначенный буквой H. Кроме того, над каждой цифрой имеется черточка (о ней позже) – это еще один (девятый) сегмент.
Предположим, необходимо вывести цифру «5» (она изображена слева сверху схемы Рисунок 4). Для вывода, очевидно, требуется «зажечь» сегменты A, C, D, F и G. Каждый сегмент кодируется своим битом в выводимом байте. Старший бит байта – сегмент A, младший – сегмент H (точка). В соответствии с этим, для вывода «5» необходимо, чтобы биты для сегментов A, C, D, F и G были бы равны 1, а биты сегментов B, E и H (если точка не нужна) – нулю. В этом случае байт, соответствующий цифре пять с точкой «5.», будет равен 10110111b или B7h (верхняя цифра слева от D2 на Рисунке 4).
Каждый из двух контроллеров (D1 и D2) управляет 4 цифрами ЖКИ. D1 – левыми (верхними справа на Рисунке 4), D2 – правыми. Для вывода 8 цифр на ЖКИ в каждый контроллер необходимо последовательно записать по 4 байта (+ по одному служебному байту), и цифры немедленно появятся на дисплее. Один из двух контроллеров D1 и D2 является ведущим (master) и называется старшим. Это контроллер D2. Контроллер D1 является ведомым (slave) и называется младшим. При работе контроллеров в режиме «старший – младший» генератор контроллера D2 вырабатывает синхроимпульсы, которыми синхронизируется контроллер D1. При инициализации необходимо в каждый из контроллеров записать в определенной последовательности соответствующие коды (в подробности вдаваться не будем, они приведены в [6, 7]). После инициализации устройство готово к приему информации для вывода на дисплей.
Каждый контроллер имеет вход данных DI (вывод 7), стробирующий (или тактовый) вход CLK (вывод 14) и вход выбора кристалла Chip Select – CS (вывод 4). Питание и «земля» подаются на выводы 5 и 6, соответственно.
Последовательность записи байт состоит в следующем.
Вначале 4 байта данных (цифры) и байт 5 со служебным кодом и кодом черточек записываются в младший контроллер. Пятый байт состоит из двух полубайт (их еще называют тетрадами или нибблами): в старшем полубайте расположен код черточек, а в младшем – служебный код (подробности см. в [6, 7]). Перед записью пяти байт в младший контроллер необходимо на его CS (CSML) подать низкий уровень напряжения (лог. 0), а после записи 5 байт – вернуть CSML в высокий (неактивный) уровень. При этом на CSST (D2) должен быть высокий уровень (лог. 1). Запись 5 байт в старший контроллер происходит аналогично. После записи всех 10 байт число немедленно появляется на дисплее.
Здесь следует добавить, что если в программе организовать массив байт, соответствующих выводимым цифрам (от 0 до 9), т.е. массив длиной 10 байт (например, М[10]), и придать элементам этого массива значения, равные кодам выводимых цифр, соответствующих местоположению элементов в массиве (т.е. нулевому элементу массива придать значение FCh – это код выводимого «0» (см. Рисунок 4), первому элементу придать значение 60h (код «1») и т.п.), то вывод цифр существенно упрощается: ведь местоположение элемента в массиве – это индекс массива. Другими словами, если, например, индекс массива, предположим, j = 5, то для вывода цифры «5» необходимо просто вывести М[5]; и в этом случае цифра «5» появится на дисплее. Поэтому, если, например, имеется число 2.57490, то для того чтобы вывести его на дисплей, требуется вывести М[2], M[5], M[7] и т.д., а чтобы поставить точку после двойки, можно, например, логически сложить M[2] с 1, т.е. вывести M[2]|1 (напомню, знак «|» – оператор побитного логического сложения в Си, а 1 – младший бит байта, т.е. бит точки H).
Как видно из вышеописанного, простота записи информации в устройство очевидна.
Второй момент касается интерфейса, по которому требуется выводить цифры на дисплей. Самый простой способ вывода – по интерфейсу SPI. В этом интерфейсе в качестве данных используется линия MOSI, а в качестве стробирующего импульса – линия SCK. Вывод байта по SPI (в программе для МК) очень простой. Для вывода байта необходимо записать его в регистр SPI0DAT, дождаться установки бита окончания передачи и сбросить это бит. Все остальное сделают аппаратные средства МК. Что касается совпадения требуемой для КР1820ВГ1 временной диаграммы с временной диаграммой вывода по SPI, то здесь проблем нет (почти). При использовании интерфейса SPI имеются два (в том числе) регистра управления: это регистр полярности (POL), определяющий, каким способом – фронтом (POL = 0) или спадом (POL = 1) импульса SCK будет производиться стробирование бит данных (для КР1820ВГ1 требуется фронтом) и регистр фазы (PHA), определяющий первым (PHA = 0) или вторым (PHA = 1) импульсом SCK будет стробироваться первый бит данных (требуется первым). Таким образом, при POL = 0 и PHA = 0 временная диаграмма вывода байт по SPI будет совпадать (логически) с требуемой. Кстати, эти значения (POL = 0 и PHA = 0) приняты в микроконтроллерах EFM8 по умолчанию, что означает, что их даже настраивать не нужно (они и так уже настроены).
Но для полного совпадения требуется еще настроить необходимую скорость передачи (или частоту следования импульсов SCK). Эта скорость передачи определяется значением делителя системной частоты (SYSCLK) процессора МК, которая устанавливается программно и в данном случае равна 18 МГц. В среде Simplicity Studio можно выбрать либо скорость (частоту SCK), тогда автоматически подсчитается значение коэффициента делителя, либо выбрать значение коэффициента делителя, тогда автоматически подсчитается тактовая частота импульсов SCK. Максимальная частота стробирующих импульсов для КР1820ВГ1 равна 500 кГц. Если выбрать коэффициент делителя равным, например, 20, то тактовая частота SCK установится равной 428.571 кГц, т.е. чуть больше 400 кГц (чтобы был некоторый запас, например, 100 кГц). Таким образом, на первый взгляд кажется, что при выводе байт по интерфейсу SPI проблем нет.
Практически так оно и есть, правда, тут есть одна загвоздка. Дело в том, что КР1820ВГ1 требует вывод байта младшим битом вперед, т.е. например, при выводе цифры – это бит десятичной точки (бит H – см. Рисунок 4), а в интерфейсе SPI (МК) принят обратный порядок следования бит – первым выводится старший бит байта. Можно было бы, конечно, написать подпрограмму, которая бы каждый раз перед выводом перекомпоновывала выводимый байт задом наперед. Но такая подпрограмма, во-первых, отнимет много времени для своей работы, что снизит скорость обмена с дисплеем, а во-вторых, что неизбежно, займет дополнительно некоторое место в программной памяти. Однако решить эту проблему можно иным и достаточно простым способом. Для этого надо заранее переписать код каждой цифры (в том числе и служебные коды) задом наперед. Если код «пятерки» с точкой был 10110111b = B7h, то, переписав биты в обратном порядке, получим: 11101101b = EDh. На Рисунке 4 «переписанный» код цифры «5.», отражаемой на ЖКИ, показан в скобках. Если такие переписанные коды вставить в массив цифр от 0 до 9, о котором говорилось выше, то все будет идеально работать. Здесь необходимо добавить, что и служебные полубайты и полубайты черточек также необходимо переписать задом наперед. Это и было сделано в подпрограмме вывода информации на дисплей.
Третий момент касается вопроса: а как вывести на дисплей число с плавающей запятой, полученное в результате аналого-цифрового преобразования? Ведь в результате расчетов напряжения именно такие числа и получаются. Причем, в зависимости от диапазона измерения, десятичная точка может стоять как после первой цифры, так и после второй. Пусть такое число с плавающей запятой, например, равно 18.5047. В памяти МК число с плавающей запятой, как известно, занимает 4 байта, и где в этих байтах искать сами цифры и десятичную точку? К счастью, этот вопрос решается довольно просто. В Си есть функция распечатки символов (в том числе и цифр). Это функция printf(). Функция производит форматный вывод символов в стандартный поток данных. Под стандартным потоком данных может подразумеваться вывод массива символов через какой-либо интерфейс (например, UART). Но есть еще одна функция: sprintf(), которая вместо вывода символов в стандартный поток данных заполняет этими символами определенную область оперативной памяти микроконтроллера, а именно – массив, название которого присутствует в параметрах этой функции. Если, например, число с плавающей запятой F = 18.5047, то записав
sprintf(buf3,"%7.4f",F);
мы получим в массиве buf3 семь символов (байт), из которых 6 будут символами цифр, а один (третий) будет символом десятичной точки. Что это за символы, и в каком коде они выводятся? Вывод символов функцией sprintf() осуществляется в коде ASCII. В этом коде, как известно, цифра (от 0 до 9) занимает один байт. Младший полубайт – это сама цифра, а старший равен 3. Другими словами, символ «0» кодируется как 30h, «1» – как 31h, «2» как 32h и т.д., «9» как 39h. Таким образом, «убрав» тройку из каждого старшего полубайта цифры (символ точки при этом не нужен, поскольку и так известно, где ее поставить), можно получить искомые цифры (которые уже далее вывести на дисплей). Как убрать эту тройку? Можно от каждого элемента массива buf3 просто отнять 30h, но лучше просто вообще обнулить старший полубайт, логически умножив каждый элемент массива buf3 на число 0fh, записав buf3[i]& = 0x0f;, где i – индекс массива buf3 (он изменяется от 0 до 7), а & – оператор побитного логического умножения в Си. Формат “%7.4f” в функции sprintf() означает, что выводится число с плавающей запятой, состоящее из 7 символов, у которого имеется 4 знака после запятой (4 символа), сама запятая (десятичная точка) – третий символ и два знака перед запятой (еще 2 символа).
Далее, подставив полученные значения buf3 как индекс в вышеописанный массив M[i] (вместо i), получим число «18.5047» уже на дисплее.
Однако и здесь кроется одна загвоздка. Дело в том, что функцию sprintf(), производящую форматный вывод чисел с плавающей запятой, можно применять, если имеется достаточно оперативной памяти, т.е. для нее требуется внешняя оперативная память (xram), которая, в свою очередь, требует применения так называемой large-модели памяти.
В программе EFM8LB1_ADC_Autoscan_Large_Buffer.c, поставляемой компанией Silicon Laboratories как пример работы АЦП, производится осреднение 2048 двухбайтных слов (4096 байт), являющихся результатами работы АЦП. Осреднение, т.е. расчет среднего значения, производится в целых числах, а результат осреднения также в целых числах (в милливольтах – это тысячи мВ) выводится в стандартный поток данных по интерфейсу RS-232 в компьютер. Вывод осуществляется функцией printf(), работающей, естественно, также с целыми числами. При этом используется так называемая small-модель, a в качестве оперативной памяти для программы используется только внутренняя оперативная память микроконтроллера (128 байт), тогда как внешняя (xram) практически полностью занята – там как раз находятся результаты АЦП (4096 байт). Другими словами, в этой программе не используются расчеты с числами с плавающей запятой, а функция printf(), работающая с целыми числами, в small-модели разрешена.
В программе автора (для МК), приведенной в [1], вообще не производится никаких расчетов. Результаты работы АЦП в целых числах (просто суммы) без обработки выводятся по интерфейсу SPI и далее по интерфейсу USB передаются в компьютер. А в компьютере уже (программой для компьютера) производятся все расчеты с плавающей запятой и форматный вывод этих чисел на монитор. В этой программе автора (для МК) также используется small-модель. При этом, как показано в [1], уже при 16-кратном осреднении 2048 двухбайтных слов пятый знак после запятой в результатах работы АЦП не меняется, из чего делается вывод, что 32-кратное осреднение избыточно. Но что мешает вместо 16-кратного осреднения 2048 двухбайтных слов (4096 байт) использовать 32-кратное осреднение, но уже 1024 двухбайтных слов (2048 байт)? Ведь как по времени, так и по точности это будет одно и то же. А раз так, то половина оперативной памяти (xram) емкостью 2048 байт освободится, в связи с чем можно уже применить large-модель и функцию sprintf(), производящую форматный вывод чисел с плавающей запятой. В программе для вольтметра так и сделано. Мало того, высокая скорость работы АЦП позволила производить не 32-кратное осреднение, а 64-кратное (для большей надежности). Даже при таком осреднении вывод результатов на дисплей производится приблизительно 5 раз в секунду, т.е. каждые 0.2 секунды, что для глаза практически незаметно.
Резюмируя все вышесказанное по поводу вывода информации на ЖКИ, можно отметить, что такой вывод достаточно прост и не требует большого объема программной памяти.
Подсчитаем ток, потребляемый устройством. Все нижеприведенные данные, в том числе и на батарейки, взяты из соответствующих справочных листков (datasheet).
|
Микроконтроллер EFM8LB12 при системной частоте (SYSCLK) 18 МГц и работе АЦП на частоте 18 МГц (см. далее) потребляет ток в районе 5 мА
|
Напряжение батарейки ER18505 (BAT1, Рисунок 2г) при токе 5.6 мА упадет до 3.5 В, а емкость – приблизительно до 4 А·ч., в связи с чем время непрерывной работы составит: 4000 мА·ч/5.6 мА ≈ 700 часов.
Потребителями батарейки ER14250 (BAT3, Рисунок 2г), в соответствии со схемой Рисунок 1, являются:
|
Напряжение батарейки ER14250 при токе 0.2 мА упадет до 3.55 В, емкость составит 1.1 А·ч, а время непрерывной работы будет: 1100 мА·ч/ 0.2 мА = 5500 часов.
Единственным потребителем энергии второй батарейки ER14250 (BAT2, Рисунок 2г) является резистор R8 номиналом 27 кОм (Рисунок 1). В самом худшем случае, если выходное напряжение ОУ DA2 будет равно 3 В, то падение напряжения на R8 составит 3 В + 3.5 В = 6.5 В, а ток: 6.5 В/27 кОм = 0.24 мА. При таком токе напряжение батарейки составит 3.55 В, а емкость упадет до 1.1 А·ч. Время непрерывной работы составит 1100 мА·ч/0.24 мА = 4583 ч ≈ 4500 часов.
Таким образом, время непрерывной работы устройства определяется временем работы батарейки ER18505, которое составляет 700 часов.
Здесь необходимо добавить, что срок службы батареек составляет около 10 лет, а падение их выходного напряжения в течение всего срока службы составит не более 0.1 В.
Литература
- Кузьминов А. Повышение разрешающей способности АЦП микроконтроллера EFM8LB12. Современная электроника. 2018. № 8, 9
- Кузьминов А. Преобразователь интерфейсов USB-SPI на базе нового 51-совместимого микроконтроллера EFM8UB1. Современная электроника. 2017. № 1 – 3
- Кузьминов А. Преобразователи интерфейсов USB-SPI с гальванической развязкой на базе нового 51-совместимого микроконтроллера EFM8UB30
- Кузьминов А. Ю. Связь между компьютером и микроконтроллером. Современные аппаратные и программные средства. – М.: «Перо». 2018
- Кузьминов А. Программирование микроконтроллеров EFM8 с помощью встроенного загрузчика программ. Радио. 2018. № 12
- Ридико Л. Автомобильные часы-термометр-вольтметр. Схемотехника. 2001. № 3
- Пархомчук А. Схемы управления устройствами отображения информации. Электроника: Наука, Технология, Бизнес. 2007. № 5
- Иванюта Е., Климович Н., Кособрюхов В. Микросхема КР1820ВГ1 для управления мультиплексным ЖК-индикатором. Микропроцессорные средства и системы. 1990. № 3
- Кузьминов А. Изготовление устройств на печатных платах с высоким разрешением в домашних условиях. Технологии в электронной промышленности. 2010. № 8 – 10, 2011. № 1, 2
- Кузьминов А. Технология изготовления печатных плат с высоким разрешением в любительских условиях. Радио. 2017. № 10
- Кузьминов А. Как использовать фольгу обратной стороны печатной платы в качестве общего провода. Радио. 2019. № 2