AC-DC и DC-DC преобразователи напряжения Top Power на складе ЭЛТЕХ

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

Bosch BME280

- Москва

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

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

Выбираем оптимальный датчик влажности: обзор решений Winsen, HOPERF, Novosense и других компаний

Однако с теми, кто имеет возможность, желание и соответствующие навыки программирования и захочет самостоятельно написать свою программу, автору хотелось бы поделиться некоторыми ключевыми моментами программы, а также рассказать о «багах», обнаруженных автором при программировании 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. Программные средства
63 предложений от 23 поставщиков
BME280 модуль датчика температуры давления влажностиОбмен данными осуществляется через интерфейс I2C или SPI.Применяется м. б. для подключения к метеостанциям, контроля состояния...
Триема
Россия
BME280
Bosch
299 ₽
BME280
Bosch
от 579 ₽
Десси
Россия
Датчик давления, температуры и влажности BME280 (4 контакта). Питание: 3-5В. Измерения: темп. -40…+85°, влажн.0-100%, давл.300-1100 ГектоПаскаль. Интерефейс: I2C.
770 ₽
Maybo
Весь мир
BME280
Bosch
по запросу
ТМ Электроникс. Электронные компоненты и приборы. Скидки, кэшбэк и бесплатная доставка
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя