На склад поступили жидко-кристаллические индикаторы и дисплеи от KSE

Барометр-гигрометр-термометр с питанием от таблеточной батарейки. Часть 2. Программные средства

Bosch BME280

- Москва

Программные средства

Программа в уже готовом загрузочном *.hex – формате (EFM8SB10F8G-A-QFN20_4.hex) приведена в дополнительных материалах к статье в разделе Загрузки. Её можно запрограммировать в МК с помощью одного из двух способов программирования, о которых говорилось выше.

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Однако с теми, кто имеет возможность, желание и соответствующие навыки программирования и захочет самостоятельно написать свою программу, автору хотелось бы поделиться некоторыми ключевыми моментами программы, а также рассказать о «багах», обнаруженных автором при программировании BME280 и ЖКИ RDN0007-PAN-##00.

Но вначале о сути самой программы. Она может быть условно разделена на две части. Это основная программа и программа инициализации устройств (InitDevice.c). Об инициализации устройств речь будет идти далее, а здесь кратко остановимся на основной программе. Но прежде несколько слов о BME280.

Эта микросхема разработана по МЭМС-технологии и включает в свой состав 20-разрядный АЦП, имеющий возможность производить передискретизацию и осреднение результатов. Для снижения шума АЦП BME280 оборудована специальным фильтром, который можно включать и выключать, если в нем нет необходимости. У неё 3 режима работы: режим сна (sleep-mode), в котором измерения не производятся и потребление тока минимально, нормальный (normal-mode), когда производятся измерения через определенный и задаваемый интервал времени (от 0.5 до 1000 мс), причем, когда измерения не производятся, BME280 автоматически переходит в sleep-режим, и, наконец, режим принудительного (форсированного) измерения (force-mode); в этом режиме измерения производятся тогда, когда это требуется, и при этом после проведения измерений микросхема также автоматически переходит в sleep-режим. Этот режим (force-mode) и использован в приборе. Для повышения точности измерений в BME280 имеются калибровочные коэффициенты (3 – для температуры, 9 – для давления и 6 – для влажности), которые настраиваются на заводе-изготовителе и записываются в постоянную память. Эти коэффициенты доступны только для чтения. Кроме того, у микросхемы имеется идентификационный номер (60h), который также доступен для чтения. После окончания измерений расчеты давления, температуры и влажности производятся по определённым формулам, в которые входят измеренные АЦП значения этих физических величин с учетом калибровочных коэффициентов. Эти формулы приведены в справочном листке (datasheet). Для обмена информацией с МК, как уже упоминалось, микросхема оснащена двумя интерфейсами: I2C и SPI. Максимальная скорость обмера по SPI составляет 10 Мбод (точнее максимальная частота сигнала, стробирующего данные (SCK), составляет 10 МГц).

Теперь по сути работы программы.

Вначале производится чтение идентификационного номера (ID) BME280 и вывод его на экран ЖКИ, на котором ID отражается в течение около 2 секунд. Если он равен «60», то это означает, что все в порядке, что микросхема именно BME280, и что её связь с МК по SPI работает верно. Далее читаются и запоминаются в оперативной памяти МК (data) калибровочные коэффициенты. После этого происходит инициализация BME280, т.е. в неё загружается требуемый режим работы (в начале – normal-mode), количество осреднений (sampling) по каждому из измерений (давления – P, температуры – Т и влажности – H), фильтр выключается, а время работы в нормальном режиме (standby_time) устанавливается на максимум (1 секунду). Далее включается режим force-mode, и на этом инициализация заканчивается. В этом месте программы устанавливается метка «start», на которую программа возвращается после всех измерений, индикации показаний на ЖКИ и окончания режима сна МК (sleep-mode), т.е. примерно через каждые 5 минут. Значения АЦП, отражающие значения измеренных величин, считываются подряд, по 3 байта для P, Т и H (т.е. всего 9 байт, при этом старший байт H не используется), начиная со старшего байта (Most Significant Byte – MSB) P, т.е. с адреса 0xf7 (BME280_REG_PRESS_MSB). После этого производится расчет T, P и H именно в такой последовательности, поскольку значение Т используется для расчета P и H. Далее рассчитанные значения P, H и Т выводятся на ЖКИ, и МК переводится в режим сна (sleep-режим), выход их которого осуществляется по тревожному сигналу (alarm) от специального таймера (Real Time Clock – RTC). Это событие, как уже указывалось, происходит каждые 5 минут. После этого программа возвращается на метку «start», о которой говорилось выше, т.е. всё повторяется в бесконечном цикле. Вот и вся суть программы. Здесь необходимо добавить, что в sleep-режиме все устройства, включая процессор, отключены (кроме таймера RTC и встроенного в него микромощного НЧ генератора LFOSC), поэтому МК и потребляет ток 0.5 мкА.

Хотя программа и не является особо сложной, автор счел необходимым разъяснить один ключевой момент программы, а именно, – вход и выход в/из режима сна МК, а также два «бага», обнаруженных автором при программировании ЖКИ и BME280.

Рекомендуемая производителем МК EFM8SB10 последовательность входа/выхода в/из sleep-режима, как следует из справочного руководства (Reference Manual – RM), состоит в следующем.

  1. Вначале необходимо отключить все аналоговые периферийные устройства (АЦП, компараторы и т.п.). Но поскольку в данном случае они не используются, их можно отключить ещё на этапе инициализации устройств (см. далее), поэтому этот пункт выполнять не требуется. А вот интерфейс SPI, скорость работы которого определяется системной тактовой частотой (SYSCLK), а она, в свою очередь, определяется частотой работы маломощного генератора LPOSC0 (20 МГц), следует отключить, поскольку следующим пунктом будет отключение генератора LPOSC0 и переключение SYSCLK на частоту работы RTC, а она, в свою очередь, определяется частотой работы микромощного низкочастотного генератора LFOSC0 (16.4 кГц). Поэтому, во избежание неадекватной работы SPI при смене частот SYSCLK, и требуется отключение SPI.
     
  2. Переключить SYSCLK на работу от RTC (16.4 кГц).
     
  3. Войти в sleep-режим, установив в регистре PMU0CF SLEEP-бит и бит выхода из sleep-режима по alarm'у от RTC. PMU0CF – это регистр устройства, управляющего потреблением мощности МК (Power Monitor Unit – PMU). Здесь следует добавить, что никакие логические операции (логического умножения «&» или логического сложения «|») с регистром PMU0CF не допускаются, или, другими словами, в PMU0CF должно быть записано строго определенное число.
     
  4. Выйти из sleep-режима, предварительно выполнив 4 команды NOP (No Operation – нет операции, т.е. пустая команда), чтобы обеспечить повторную синхронизацию НЧ генератора LFOSC0 с процессором. После этого переключить SYSCLK на работу от маломощного ВЧ генератора LPOSC0 (20 МГц) и дождаться установки бита адекватной работы SYSCLK.

Здесь следует добавить, что после того как произойдет событие, по которому осуществляется вход в sleep-режим, в данном случае – по alarm’у от RTC, в PMU автоматически установится бит (флаг) этого события. Поэтому для повторного входа в sleep-режим (через время, определяемое RTC, в данном случае – 5 минут) этот флаг необходимо сбросить программно. Для этого в регистр PMU (PMU0CF) необходимо также записать определенное число, обнуляющее этот флаг и сохраняющее бит входа в sleep-режим по alarm’у от RTC.

В конце выхода из sleep-режима необходимо включить SPI.

Несмотря на такое «пространное» объяснение, по фрагменту основной программы (на C51), связанному с входом и выходом в/из sleep-режима, приведенному ниже, можно убедиться, что это достаточно простая процедура. Здесь необходимо разъяснить, что после входа в sleep-режим (т.е. после выполнения команды PMU0CF=0x84;) сразу следуют 4 пустых команды (_nop_ ();), и на первый взгляд, кажется, что выполнение этих команд начинается сразу же после выполнения предыдущей команды (по крайней мере, так написано в программе). Однако, поскольку в sleep-режиме процессор МК остановлен, а эти команды (инструкции) выполняются именно им, то они не будут выполняться до тех пор, пока не произойдет событие выхода из sleep-режима, а этот выход, в свою очередь, наступит только тогда, когда поступит тревожный сигнал (alarm) от RTC, счетчик которого досчитает до максимального значения и обнулится по авто-ресету, т.е. через 5 минут. Сами же эти 4 NOP'а требуются для синхронизации «проснувшегося» процессора с тактовой частотой НЧ генератора LFOSC0 (16.4 кГц), встроенного в RTC.

//----------------------
// Вход в sleep-режим
//----------------------
      SPI0CN0 &= 0xfe; //Запрет SPI.
      CLKSEL=0x83;     //SYSCLK = частота работы RTC (16 кГц).
      _nop_ ();
      _nop_ ();
      _nop_ ();
      _nop_ ();
      PMU0CF=0x84;     //Вход в sleep и разрешение выхода по alarm от RTC(5 минут).
//------------------------
// Выход из sleep-режима
//------------------------
      _nop_ ();
      _nop_ ();
      _nop_ ();
      _nop_ ();
       CLKSEL=0x04;    //SYSCLK = LPOSC (20 МГц).
       DEL10MS();
       while ((CLKSEL & 0x80)==0); //Ожидание установки SYSCLK = LPOSC.
       PMU0CF=0x24;                //Сброс всех флагов и разрешение alarm по RTC.
       SPI0CN0 |= 0x01;            //Разрешение SPI.
//-----------------------

Теперь по поводу бага при программировании ЖКИ RND0007-PAN-#00. Этот ЖКИ является усовершенствованной версией более старых ЖКИ TI8148 и TIC55. Общим контроллером (драйвером) для этих ЖКИ является ML1001. Эти ЖКИ имеют 8 знакомест, каждое из которых состоит из семи сегментов цифры, сегмента десятичной точки («.») и сегмента «галки» («^»), т.е. всего из 9 сегментов. Таким образом, общее количество сегментов ЖКИ составляет 8 × 9 = 72. Каждый сегмент кодируется определенным битом, откуда следует, что для заполнения всего ЖКИ требуется передать 72 бита. Так вот, в справочном листке ML1001 указано, что для заполнения всего ЖКИ требуется передать 72 информационных бита и ещё 8 пустых бит, чтобы их общее количество составляло 80. На таком принципе и работают ЖКИ TI8148 и TIC55. В отличие от этих ЖКИ, в RND0007-PAN-#00 требуется передать не 80, а 72 бита, т.е. ровно столько, сколько их требуется для всех его знакомест (по 9 бит каждое), иначе все знакоместа сдвигаются влево, (при этом информация первого знакоместа пропадает), а информация последнего знакоместа становится копией предпоследнего (в этом и состоит баг). Здесь необходимо добавить, что вначале передаётся бит точки, затем бит галки и далее – 7 бит сегментов цифры. Передача бит знакомест осуществляется задом наперёд, или, другими словами, последние переданные 9 бит соответствуют первому (левому) знакоместу на ЖКИ (если точки и галки располагаются снизу).

При программировании чтения по SPI из BME280 автор также обнаружил баг. Он состоит в том, что при чтении идентификационного номера (ID) и калибровочных коэффициентов используется стандартная процедура чтения по SPI, а при чтении показаний АЦП эта процедура дает неадекватные значения. Для объяснения этого эффекта и снятия этого бага сделаем некоторое отступление по поводу стандартных протоколов чтения и записи по SPI.

Для того чтобы записать байт по SPI требуется записать его в регистр SPI0DAT, дождаться установки бита (флага) окончания передачи (SPI0CN0_SPIF) и сбросить этот бит. Эта стандартная процедура (подпрограмма) приведена ниже.

void outspi(uint8_t byte) {
    SPI0DAT = byte;        // Вывод байта по SPI
    while (!SPI0CN0_SPIF); // Ожидание окончания вывода байта
    SPI0CN0_SPIF = 0;      // Сброс флага окончания передачи.
    }

При чтении байта по SPI требуется записать в SPI0DAT ничего не значащий фиктивный (подставной – dummy) байт (например, 0xff), дождаться установки флага SPI0CN0_SPIF и сбросить его. Результат чтения будет в регистре SPI0DAT. Подпрограмма чтения по SPI приведена ниже.

uint8_t inspi() {
    uint8_t byte;
    SPI0DAT = 0xff;        // Вывод фиктивного байта.
    while (!SPI0CN0_SPIF); // Ожидание окончания ввода байта.
    SPI0CN0_SPIF = 0;      // Сброс флага окончания приема.
    byte = SPI0DAT;        // Ввод байта в микроконтроллер
    return (byte);
    }

Возвращаясь к прерванной последовательности изложения, следует пояснить, что сама процедура чтения из области памяти BME280 состоит в том, что вначале требуется записать байт адреса, откуда необходимо получить информацию (вышеприведенной подпрограммой записи), а затем – прочитать эту информацию (вышеприведенной подпрограммой чтения). Причем, если требуется прочитать несколько (2 и более) подряд расположенных байт, или, другими словами, массив байт (многократное чтение – multiple byte read), нет необходимости перед чтением каждого байта указывать его адрес. Достаточно записать адрес первого элемента массива, и далее просто читать подряд столько раз, сколько элементов в массиве. Другими словами, перед чтением каждого следующего байта происходит автоматическое инкрементирование адреса.

Например, для чтения первого двухбайтного калибровочного коэффициента температуры (в справочном листке он обозначен как dig_T1), расположенного по адресам 0x88 (старший байт) и 0x89 (младший байт), необходимо вначале записать адрес старшего байта (0x88), а затем произвести двукратное чтение. В этом случае такая процедура чтения работает правильно, и к ней никаких претензий нет.

Иное дело, если требуется прочитать показания АЦП. Эти показания для давления (ADC_P), температуры (ADC_T) и влажности (ADC_H) расположены в памяти BME280 также подряд, начиная с адреса 0xF7 (старший байт показания давления – press_msb). Причем, каждое показание АЦП расположено в трех байтах. Например, показание ADC_P расположено по адресам 0xF7 (старший байт), 0xF8 (средний байт – press_lsb) и 0xF9 (младший байт – press_xlsb). Далее идёт показание ADC_T, а за ним – ADC_H. Таким образом, все три показания занимают 3 × 3 = 9 байт. Если требуется прочитать подряд все 9 байт, то, применив вышеприведенную процедуру многократного чтения, вначале следует записать в BME280 адрес первого элемента этого массива, т.е. 0xF7, а затем осуществить 9-кратное чтение. Однако в этом случае получится полная белиберда. В чём же здесь дело? Как выяснил автор, при записи адреса 0xF7 вышеприведенной подпрограммой записи байта и последующего чтения байта вышеприведенной подпрограммой чтения будет произведена операция чтения не с адреса 0xF7, а со следующего (0xF8). Другими словами, после записи адреса 0xF7 (см. подпрограмму записи) в регистр SPI0DAT сразу же запишется содержимое 0xF7, а при последующем чтении, после записи фиктивного байта (см. подпрограмму чтения) в SPI0DAT запишется содержимое уже следующего байта (0xF8), т.е. после записи адреса происходит его автоматическое инкрементирование, и, таким образом, содержимое регистра 0xF7 теряется.

Решить эту проблему можно двумя способами.

Первый способ – после выполнения подпрограммы записи адреса 0xF7 сразу же прочитать содержимое SPI0DAT (это и будет содержимое адреса 0xF7), а затем уже осуществить чтение подпрограммой чтения, в результате чего получим содержимое адреса 0xF8, и далее прочитать остальные байты стандартным образом.

Второй способ состоит в том, что вначале следует записать (подпрограммой записи) не адрес 0xF7, а адрес на единицу меньше, т.е. адрес 0xF6, а затем уже прочитать все 9 байт. Оба способа, как выяснилось, работают, однако второй, по мнению автора, более предпочтителен, поскольку он позволяет воспользоваться стандартными подпрограммами чтения и записи по SPI. Ниже приведен фрагмент основной программы, где показано, как это сделать. Во-первых, вначале следует установить совмещение (объединение) 4-байтного числа (uint32_t dw) с массивом из четырех однобайтных чисел (uint8_t b[3]) с четырьмя элементами: b[0], b[1], b[2] и b[3]. Это совмещение требуется, чтобы, с одной стороны, иметь возможность работы с 4-байтным числом (ADC_P) для расчетов давления по формулам, приведенным в справочном листке (с учётом калибровочных коэффициентов), с другой – производить однобайтное чтение по интерфейсу SPI (он, как известно, однобайтный). Такое совмещение приводит к тому, что массив из четырех однобайтных чисел b[3] и одно 4-байтное число dw перераспределяют одно и то же место в памяти. Другими словами, массив b[3] строго определяет число dw и наоборот, dw строго определяет массив b[3]. Это совмещение приведено ниже.

union {
uint8_t  b[3];
    uint32_t dw;
      }ret;

Ниже приведен фрагмент основной программы, в котором осуществляется чтение начиная с адреса 0xF6 (BME280_REG_PRESS_MSB – 1), т.е на единицу меньше адреса старшего байта давления (в начале программы установлена директива #define BME280_REG_PRESS_MSB 0xF7). Самый старший элемент массива (ret.b[3]) не используется, поэтому он должен быть обнулён.

ret.b[3] = 0x00;
outspi(BME280_REG_PRESS_MSB - 1); //адрес 0xF6
    ret.b[2] = inspi();           //содержимое 0xF7.
    ret.b[1] = inspi();           //содержимое 0xF8.
    ret.b[0] = inspi();           //содержимое 0xF9.
    adc_P = (ret.dw >> 4) & 0xFFFFF;
.
.
.

Таким образом, прочитав все три байта, можно получить правильные показания АЦП (adc_P) из числа ret.dw. Остальные 6 байт для температуры и влажности читаются аналогично.

Кстати, в справочном листке BME280 в качестве примера приведена последовательность (по времени) многократного чтения по SPI (SPI multiple byte read), как раз начиная с регистра с адресом 0xF6 (Рис. 13 из справочного листка). С учетом вышесказанного на Рисунке 2 приведена эта последовательность со скорректированными адресами.

Последовательность многократного чтения по SPI (адреса скорректированы).
Рисунок 2. Последовательность многократного чтения по SPI (адреса скорректированы).

Перейдем теперь к настройке МК, или инициализации всех его устройств. Эта процедура намного проще написания программы на C51, однако именно она определяет полное функционирование всего МК. Инициализация осуществляется в среде Simplisty Studio v.4 в специальном режиме конфигурации.

В общем меню конфигуратора (Рисунок 3) в настройке нуждаются только те устройства, которые отмечены «галками» (остальные устройства по умолчанию отключены).

Общее меню конфигуратора.
Рисунок 3. Общее меню конфигуратора.

При нажатии соответствующей кнопки в меню справа будет отражаться окно, в котором нужно выбрать те или иные параметры. При нажатии кнопки Clock Control необходимо выбрать Low Power Oscillator и установить делитель для системной тактовой частоты в единицу SYSCLK/1. При этом значение частоты для SYSCLK установится на 20 МГц (или 20,000,000 Гц, Рисунок 4а). В настройках для SPI (Рисунок 4б) необходимо разрешить работу SPI (Enabled), установить 3-проводный режим Master (Master 3-wire mode), установить фазу (Clock Phase) и полярность (Clock Polarity), а также выбрать скорость работы, т.е. в данном случае выбрать коэффициент деления SYSCLK (SPI0CKR) равным единице. В этом случае частота импульсов SCK установится равной 5 МГц. В опциях Interrupts, Supply Monitor и Voltage Regulators необходимо установить запрет (в связи с простотой подробности не показаны). Нажав кнопку PMU, необходимо выбрать разрешение выхода из sleep-режима по тревожному сигналу от таймера RTC (Enable RTC alarm Wake-up Source), отмеченное синим цветом на Рисунке 4в. Это очень важный момент. Если этого не сделать, то после входа в sleep-режим программа «зависнет». И последнее, что необходимо сделать, – это настроить параметры работы RTC в соответствии с Рисунком 4г. Здесь надо добавить, что при работе счетчика RTC от внутреннего микромощного НЧ генератора LFOSC0 частотой около 16 кГц этот счетчик будет считать каждый поступивший импульс не нулевым, а первым битом, или, другими словами, содержимое RTC будет увеличиваться на единицу так, как будто к RTC подключен кварцевый резонатор частотой 32 кГц. Т.е. RTC будет считать в 2 раза быстрее. Поэтому, выбрав программированное значение тревожного сигнала для RTC (Alarm Programmed Value) равное 10,000,000, которое соответствует периоду в 10 минут (Actual Alarm Period – предпоследняя строчка в окне Рисунка 4г), получим, что этот период на самом деле будет равен 5 минутам. Также необходимо разрешить сам тревожный сигнал от RTC (Enable RTC Alarm) и авто-ресет RTC по Alarm'у (Enable Alarm Auto-reset). Опция авто-ресет автоматически сбрасывает (обнуляет) содержимое таймера RTC по достижению максимального значения (5 минут), т.е RTC не останавливается, а продолжает работу с начала. Кроме того, необходимо разрешить работу RTC (Enable RTC oscillator) и запустить его (RTC Timer Run Control – Start).

а) Конфигурирование устройств МК. (а) - выбор системной тактовой частоты (SYSCLK), (б) - выбор режима работы SPI, в - настройка PMU, (г) - настройка RTC, (д) - настройка портов МК (DefaultMode PortI/O).
б) Конфигурирование устройств МК. (а) - выбор системной тактовой частоты (SYSCLK), (б) - выбор режима работы SPI, в - настройка PMU, (г) - настройка RTC, (д) - настройка портов МК (DefaultMode PortI/O).
в) Конфигурирование устройств МК. (а) - выбор системной тактовой частоты (SYSCLK), (б) - выбор режима работы SPI, в - настройка PMU, (г) - настройка RTC, (д) - настройка портов МК (DefaultMode PortI/O).
г) Конфигурирование устройств МК. (а) - выбор системной тактовой частоты (SYSCLK), (б) - выбор режима работы SPI, в - настройка PMU, (г) - настройка RTC, (д) - настройка портов МК (DefaultMode PortI/O).
д) Конфигурирование устройств МК. (а) - выбор системной тактовой частоты (SYSCLK), (б) - выбор режима работы SPI, в - настройка PMU, (г) - настройка RTC, (д) - настройка портов МК (DefaultMode PortI/O).
Рисунок 4. Конфигурирование устройств МК. (а) – выбор системной тактовой
частоты (SYSCLK), (б) – выбор режима работы SPI, в – настройка PMU,
(г) – настройка RTC, (д) – настройка портов МК (DefaultMode PortI/O).

Далее необходимо прейти в режим настройки портов (Default Mode PortI/O). На экран выведется корпус МК с портами (Рисунок 4д). Опциями skip (пропуск) необходимо «передвинуть» порты интерфейса SPI (SPI0_SCK, SPI0_MISO и SPI0_MOSI) в правую часть корпуса, чтобы их легче было соединить с BME280 – так, как это показано на схеме Рисунок 1 (и на разводке – см. далее Рисунок 5а). «Пропущенные» порты отмечены красными крестиками. Порты Р0.1, P0.2 и P0.3, подключаемые к ЖКИ, настроить как цифровые выходы (Digital Push-Pull Output) со слабым токовым выходом (Low drive). При этой опции потребление тока портом существенно снижено. Для наглядности в правой части Рисунка 4д показана конфигурация порта P0.2, отмеченного на корпусе (слева сверху) черным прямоугольником. Порты SPI P0.7(SPI0_SCK), P1.1(SPI0_MOSI) и порт P1.2 (вывод 11, CSB) также настроить как Digital Push-Pull Output, a порт P1.0 (SPI0_MISO) – как цифровой вход (Digital OpenDrain I/O), т.е. выход с открытым стоком (и со слаботочной подтяжкой Pull-ups Enabled).

а) Разводка и общий вид платы устройства: (а), (в) - вид со стороны расположения компонентов, (б), (г) - вид с обратной стороны. б) Разводка и общий вид платы устройства: (а), (в) - вид со стороны расположения компонентов, (б), (г) - вид с обратной стороны.
в) Разводка и общий вид платы устройства: (а), (в) - вид со стороны расположения компонентов, (б), (г) - вид с обратной стороны. г) Разводка и общий вид платы устройства: (а), (в) - вид со стороны расположения компонентов, (б), (г) - вид с обратной стороны.
Рисунок 5. Разводка и общий вид платы устройства: (а), (в) – вид со стороны расположения компонентов,
(б), (г) – вид с обратной стороны.

После того как произведена настройка (конфигурация) всех устройств МК, необходимо нажать кнопку с двойной дискетой в левой верхней строке меню всего экрана, чтобы записать эту конфигурацию на диск.

При этом на C51 сгенерируется текст программы инициализации устройств InitDevice.c (чтобы написать её вручную, да ещё без ошибок, а это несколько страниц текста на C51, уйдёт не один день), к которой будет обращение из основной программы в самом начале её работы. После этого основную программу необходимо оттранслировать, выбрав в меню экрана опцию Project и в отрывшемся окне – подопцию Build Project. После трансляции создастся файл EFM8SB10F8G-A-QFN20_4.hex, о котором уже упоминалось в начале этого раздела статьи, а в нижней части экрана в специальном окне, отражающем результат трансляции, будет следующее сообщение:

Program Size: data=121.1 xdata=0 const=0 code=4959
LX51 RUN COMPLETE.  0 WARNING(S),  0 ERROR(S)

Из этого сообщения следует, что программа использует практически всю внутреннюю оперативную память (data=121.1 байт), размер которой 128 байт, внешняя дополнительная оперативная память с непрямой адресацией размером 512 байт не используется (xdata=0), а размер кодовой части программы составляет около 4.8 КБ (code=4959), т.е. укладывается в максимальный размер программной памяти для этого МК, равный 8 КБ.

Разводка платы устройства и её внешний вид

Разводка платы сделана автором с помощью программы SprintLayOut v.6, ссылка на файл разводки в формате *.lay6 приведена в разделе Загрузки. Из рисунков разведенной платы и её внешнего вида (Рисунок 5) можно заключить, что её разводка очень проста, а сама плата миниатюрна (размер всего 11×14 мм). Здесь следует добавить, что при программировании МК с помощью USB DEBUG адаптера по интерфейсу C2 припаивать разъем для его программирования с помощью COM-порта компьютера не обязательно. В этом случае в отверстия контактов «земли» и питания (+3 В) этого разъёма необходимо вставить тонкий лужёный медный провод и пропаять его с двух сторон платы (как это видно на Рисунке 5в).

Конструкция устройства

Прибор сконструирован в корпусе размером 114×35.7×25.8 мм (G535G Gainta). Все стойки, установленные на внутренних поверхностях двух половин корпуса, были удалены, а стойки, предназначенные для скручивания половин корпуса саморезами, были переклеены в места ближе к боковым стенкам, чтобы они не мешали установке ЖКИ, батарейки и платы. Для чтения показаний ЖКИ на лицевой половине корпуса было прорезано окно, а ЖКИ закреплен на внутренней поверхности этой половины корпуса. К этой поверхности приклеены пластиковые прямоугольные пластины по размеру дисплея, к которым он приклеен полосками, вырезанными из пористой ленты с двусторонним липким слоем. К внутренней поверхности второй половины корпуса такой же лентой приклеены батарейка и плата. Для доступа воздуха к плате в этой же половине корпуса просверлены 6 отверстий (они хорошо заметны на Рисунке 6а). На лицевую поверхность корпуса наклеены полоски бумаги с напечатанными словами «Давление• Влажность• Температура» и символами «мм рт.ст.», «%» и «°C» (Рисунок 6б).

Конструкция прибора: (а) - вид в открытом корпусе, (б) - общий вид в сборе.

Конструкция прибора: (а) - вид в открытом корпусе, (б) - общий вид в сборе.

Рисунок 6. Конструкция прибора: (а) – вид в открытом корпусе, (б) – общий
вид в сборе.

Результаты работы прибора

Для проверки правильности показаний устройства автор использовал достаточно «древний» прибор БМ 2, которому уже более 40 лет и который работает до сих пор (Рисунок 7). Правда, около 10 лет назад БМ 2 был откалиброван с помощью прецизионного анероида и прецизионного гигрометра. Как следует из сравнения показаний двух приборов, они показывают приблизительно одинаковые давления (756 мм рт. ст.) и обведенное синим овалом место расположения стрелки, показывающей давление БМ 2 (правее риски 755). Показания же влажности несколько различаются: стрелка, показывающая влажность у БМ 2 (зелёный овал), расположена около риски в 45%, а настоящий прибор показывает влажность 40%. Что касается температуры, то оба прибора показывают приблизительно одинаковые значения (23 °C у настоящего прибора) и конец красной полоски подкрашенного спирта у градусника БМ 2 (между рисок 23 и 24).

Сравнение показаний устройства с показаниями прибора БM-2.
Рисунок 7. Сравнение показаний устройства с показаниями прибора БM 2.

Для проверки показания прибора при отрицательных температурах он был помещён в морозилку холодильника приблизительно на полчаса, где показал температуру –9° C (Рисунок 8). Замороженные продукты были отодвинуты к задней стенке морозилки smiley.

Показание прибора, помещенного в морозилку холодильника.
Рисунок 8. Показание прибора, помещенного в морозилку холодильника.

Заключение

Применение МК EFM8SB10 и сопряженного с ним по интерфейсу SPI MEMS-датчика BME280, потребляющих доли мкА в состоянии сна, совместно с 8-разрядным 7-сегментным ЖКИ RND0007-PAN-#00 позволили сконструировать простой и недорогой прибор, измеряющий атмосферное давление, влажность и температуру с обновлением информации раз в 5 минут. Сверхнизкое энергопотребление дало возможность непрерывной работы прибора в течение 5 лет при питании от небольшой литиевой батарейки CR2477 таблеточного типа.

Литература

  1. Кузьминов А. Ю. Связь между компьютером и микроконтроллером. Современные аппаратные и программные средства. М.: «Перо». 2018.
  2. Кузьминов А. Программирование микроконтроллеров EFM8 с помощью встроенного загрузчика программ. Радио. 2018. № 12.

Материалы по теме

  1. Datasheet Bosch Sensortec BME280
  2. Datasheet Silicon Labs EFM8SB10F8-QFN20

Загрузки

  1. Дополнительные материалы к статье

Содержание цикла «Барометр-гигрометр-термометр с питанием от таблеточной батарейки»

  1. Часть 1. Принципиальная схема
  2. Часть 2. Программные средства
39 предложений от 19 поставщиков
Модуль высокоточного датчика атмосферного давления, температуры и влажности BME280 - очередного датчика в линейке датчиков от Bosch Sensortec. Управление возможно по...
ЗУМ-СМД
Россия
BME280
Bosch
163 ₽
BME280
Bosch
198 ₽
T-electron
Россия и страны СНГ
BME280 atmospheric pressure temperature humidity sensor module
560 ₽
BME280
Bosch
от 1 053 ₽
Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя