Применение цифровых датчиков давления HP03SA, HP03MA производства HopeRF (Hope Microelectronics) Китай. Схема, прошивка, исходный код.


05.03.2011

HP03SA, HP03MA - недорогие цифровые датчики атмосферного давления, работающие по двухпроводному интерфейсу I2C.

HP03SA, HP03MA – миниатюрный гибридный модуль, изготавливаемого на основе пьезорезистивного датчика давления и интерфейсной микросхемы аналогово-цифровых преобразователя. Формат цифровых данных читается в виде 16-разрядного слова, соответствующего измеряемому ADC напряжению в зависимости от давления и температуры. Реальное разрешение - 15 разрядов.

HP03SA и HP03MA обладают малым током потребления около 500 микроампер и при этом могут питаться напряжением от 2.2В до 3.6В. В датчиках есть функция автоматического переключения в режим экономии энергии, т.е. спящий режим. Поэтому они идеально подходят для носимых устройств, где энергопотребление играет немаловажную роль.

Для связи с микроконтроллером используется 2-проводная последовательная шина I2C. С помощью дополнительной калибровки датчика производитель добивается более высокой точности измерений. Для этого во внутренней памяти датчиков хранятся 11 уникальных корректирующих коэффициентов. Вычисления температуры и давления выполняются с использованием этих коэффициентов. Поскольку в датчике имеется термодатчик, температура учитывается в вычислениях давления, чем достигается термостабилизация показаний датчика давления.

См. также Датчик малых давлений BMP085 и Atmega

Основные характеристики датчиков:

* встроенный датчик давления * абсолютный диапазон измеряемого давления: 300kPa…1100kPa * 16-разрядный  ADC * 11 поправочных коэффициентов во внутренней памяти для программной компенсации * последовательный I2C-интерфейс * один вывод тактирования 32.768kHz * одна аппаратная линия сброса * высокая экономичность * разрешение ADC: 15bit * напряжение питания: 2.2V…3.6V * ток потребления в рабочем режиме: менее 500uA * ток потребления в режиме отключения: менее 1uA * внешние компоненты не требуются * разрешение датчика: 0.1kPa * относительная точность (750kPa…1100kPa): ±1kPa * абсолютная точность (750kPa…1100kPa): ±1.5kPa * максимальная ошибка по температуре (-20°C…+60°C): ±3kPa * долговременная стабильность (12 месяцев): 2kPa * зависимость от напряжения питания (2.4V…3.6V): ±1.5kPa * температурная точность: ±0.8°C

HP03SA имеет текстолитовое основание (9.5x9.0x4.8mm), удобное для ручного монтажа.

HP03MA имеет компактное текстолитовое основание (6.9x6.3x3.1mm) для автоматического монтажа. Также успешно монтируется вручную.

Оба рассчитаны на температурный диапазон: -20°C…+60°C.

HP03SA отличается от HP03MA исполнением корпуса. Все прочие характеристики одинаковы. На практике HP03SA показывали более стабильный результат и меньший разброс параметров в отличии от миниатюрных собратьев HP03MA.

На рисунках Приведены рекомендуемые в документации схемы сопряжения датчиков и микроконтроллеров. А так же схемы их корпусов.

  

Реальная схема может быть следующая:

Она отличается от предложенной схемы отсутствием подтягивающего резистора 10 КОм. В предложенном примере используется встроенные подтягивающие резисторы микроконтроллера серии ATmega.

Пример программы для Atmega8:


#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "i2cmaster.h"

//#define F_CPU 3686400L

// Порт XCLR Датчика
#define XCLR_DDR DDRD
#define XCLR_PORT PORTD
#define XCLR PIND0

// Порт Тактирования АЦП Датчика
#define MCLK_DDR DDRD
#define MCLK_PORT PORTD
#define MCLK PIND1

// Калибровочные коэффициенты
long int c1, c2, c3, c4, c5, c6, c7, a, b, c, d;
// Значение АЦП
long int d1, d2;
// Температура
long int t;
// Давление
long int Pressure;
//#############################################################################
// Возведение двойки в степень
//
long int pow2(uint8_t i)
{
long int uiData;
uiData=2;
i=i-1;
while(i) {
uiData *= 2;
i--;
}
return uiData;
}

#define fospEEPROM_ADR  0xA0    // Адрес EEPROM
#define fospADC_ADR     0xEE    // Адрес ADC
#define PRESSURE        0xF0
#define TEMPERATURE     0xE8
#define mm_rt_st        0.7500638    // мм. рт. ст. (@ 0 гр. C)
//#############################################################################
// Инициализация HP03
//
void HP03Init(void)
{
// Сброс HP03
XCLR_PORT &= ~(1<<XCLR);
_delay_ms(200);
XCLR_PORT |= (1<<XCLR);
_delay_ms(200);
XCLR_PORT &= ~(1<<XCLR);
_delay_ms(200);
}

//#############################################################################
// Считывает два байта
//
unsigned int HP03_Get2Bytes()
{
unsigned int HiTemp, LowTemp;
HiTemp=i2c_readAck();
LowTemp=i2c_readAck();
return (((int)HiTemp)  <<  8) + LowTemp;
}

//#############################################################################
// Чтение калибровочных коэффициентов из EEPROM (HP03)
//
void HP03ReadCoeff(void)
{
unsigned int ret;

ret = i2c_start(fospEEPROM_ADR);    // Адрес EEPROM

if(ret)
{
// датчик не обнаружен
i2c_stop();
}
else
{
i2c_write(0x10);                  // Адрес коэффициентов в EEPROM
i2c_start(0xA1);

c1=HP03_Get2Bytes();
c2=HP03_Get2Bytes();
c3=HP03_Get2Bytes();
c4=HP03_Get2Bytes();
c5=HP03_Get2Bytes();
c6=HP03_Get2Bytes();
c7=HP03_Get2Bytes();

a = i2c_readAck();
b = i2c_readAck();
c = i2c_readAck();
d = i2c_readNak();

i2c_stop();
}
}

//#############################################################################
// Чтение данных АЦП (HP03)
//
unsigned int HP03ReadValue(unsigned char n)
{

unsigned int ret;
unsigned int temp;
temp = 0;

ret=i2c_start(fospADC_ADR); // Адрес ADC

if(ret)
{
// датчик не обнаружен
i2c_stop();
}
else
{
i2c_write(0xff);
i2c_write(n);    // Pressure(0xF0), Temperature(0xE8)
i2c_stop();

_delay_ms(50);

i2c_start(fospADC_ADR);  // Адрес ADC
i2c_write(0xfd);

i2c_rep_start(0XEF);  // Адрес ADC

temp = HP03_Get2Bytes();

i2c_stop();
}

return temp;

}

//#############################################################################
// Вычисление температуры и атмосферного давления
// с учетом калибровочных коэффициентов
//
void PressureTemperatureMeasure(void)
{
long int  dUT;
long int  off, sens, x;

XCLR_PORT |= (1<<XCLR);

d1 = HP03ReadValue(PRESSURE);
d2 = HP03ReadValue(TEMPERATURE);

XCLR_PORT &= ~(1<<XCLR);

//if(d2 >= c5) { dUT = (d2-c5) - (((d2-c5)/pow2(7))*((d2-c5)/pow2(7))*a)/pow2(c); }
//else {         dUT = (d2-c5) - (((d2-c5)/pow2(7))*((d2-c5)/pow2(7))*b)/pow2(c); }
if(d2 >= c5) { t = a; }
else { t = b; }
dUT = (d2-c5) - (((d2-c5)/pow2(7))*((d2-c5)/pow2(7))*t)/pow2(c);

t = (250 + ((dUT*c6)/pow2(16)) - dUT/pow2(d));///10; // Вычисляем температуру в градусах по шкале Цельсия

off = (c2+(c4-1024)*dUT/pow2(14))*4;
sens = c1+(c3*dUT)/pow2(10);
x = (sens*(d1-7168))/pow2(14)-off;

//Pressure = (x*100/pow2(5)+c7*10);
Pressure = ((x*100/pow2(5)+c7*10)/100)*mm_rt_st;    // Вычисляем давление в миллиметрах ртутного столба
}

//=============================================================================
//#############################################################################
// Тактирование АЦП Датчика
// Тактовая частота процессора 3.6864 МГц
//
ISR(TIMER0_OVF_vect) {
if ((MCLK_PORT & (1<<MCLK)) == 0) {
MCLK_PORT |= (1<<MCLK);
}
else {
MCLK_PORT &= ~(1<<MCLK);
}
}
//#############################################################################
//#############################################################################
int main(void){

// Настраиваем порт для Сброса и Синхронизации датчика
XCLR_DDR |= (1<<XCLR);
MCLK_DDR |= (1<<MCLK);

// Настраиваем таймер для тактирования АЦП
TCCR0 = (1<<CS00);

// Разрешаем прерывания
TIMSK = (1<<TOIE0);

// Запускаем таймера
TCNT0 = 0;

sei();

i2c_init();

// TWI PULL UP Включаем внутренние подтягивающие резисторы, поэтому наружные резисторы можно не устанавливать.
PORTC |= ((1<<PINC4) | (1<<PINC5));

HP03Init();
HP03ReadCoeff();

while(1) {
PressureTemperatureMeasure();
// Выводим переменные
// t - температура
// Pressure - давление
}

}

Скачать пример для HP03

P.S. В примере использована частота кварца 3.6864 МГц. Это абсолютно НЕ принципиально. Будет работать и от внутреннего RC-генератора. Хотя в документации указано, что АЦП датчика необходимо тактировать частотой 32768 Гц, это не обязательное условие. На практике АЦП датчика можно тактировать меньшей частотой. Я снижал до 15000  Гц, при этом работоспособность сохранялась.

См. также:

Схеми і прошивки
Коментарі:
bevice говорить:
16.09.2011 17:55
Индусский код в изобилии =)
степень двойки делается так: (1&lt;&lt;x) или макросом _BV(x) - сильно быстрее чем умножать
прерывание таймера (для тактирования датчика) вообще можно записать одной простой строкой:
ISR(TIMER0_OVF_vect){
 MCLK_DDR ^= _BV(MCLK);
}

спасибо за примеры

admin говорить:
19.09.2011 11:26
Спасибо за конструктивную критику.
По первому пункту принимается.
Именно двойку в степень проще смещением. Это факт.

функция pow2 - раньше возводила в степень (больше 0) любое число. И была усечена именно для этого примера. Это не сложно заметить.
Если Вам, как мне, придется, скажем, пересчитывать давление в высоту, понадобиться возводить в степень другие числа.
Вернув функции второй параметр (вместо двойки), получим универсальный механизм.

Что касается прерывания таймера (для тактирования датчика), то Ваш код, несмотря на то, что визуально выглядит проще, увы, в памяти занимает на 6 байт больше.  Ну и по поводу MCLK_DDR тоже возникает вопрос...

bevice говорить:
30.09.2011 17:48
Насчет памяти на XOR - не больше - факт, XOR в AVR одна команда eor
на AMS оно как-то так (могу ошибаться):
LDI r16, 1
IN r17, PORTD
EOR r17,r16
OUT PORTD, r17
c if/else точно больше: 2 инструкции LDI,  операция сравнения,  три логические, и OUT/IN в любом случае больше.

Про степень - я так и подумал;)

Александр говорить:
12.01.2012 10:47
Ув. автор. Использую датчик HP03SA в своей конструкции. Контроллер PIC18F25K20. Столкнулся с проблемой - не могу вычитать коэффициенты в ЕЕПРОМ - вычитываются все ФФ, за исключением 2-х последних коэффициентов - 6 и 9 соотв. Меняя стартовый адрес ЕЕПРОМ, обчитал всю область вокруг, начиная с 00 - отличны от ФФ только эти 2 байта. Результат АЦП вычитывается вроде нормальный - по крайней мере, он меняется при изм. температуры. Ножка сброса устанавливается корректно - для чтения ЕЕПРОМ низкий, АЦП - высокий. Питание 3.3В, подтяжка шины - 10 кОм. Не сталкивались ли вы с битой ЕПРОМиной? Спасибо.

admin говорить:
12.01.2012 11:19
Была проблема с датчиками HP03MA (тот же датчик, но в другом корпусе). Тоже читались не все данные, но данные с АЦП считывались. Долго разбирался, оказалось, попалась бракованная партия. До сих пор 6 штук валяется. Другой вариант (маловероятный), существуют датчики HP02SA. Внешне один в один HP03SA. У них 5 коэфициентов и нельзя вычислить температуру, только давление. Стоят почти вдвое дешевле. Возможно, продавцы "попутали".

Александр говорить:
12.01.2012 11:54
Спасибо за ответ. Вот сейчас для проверки еще раз вычитал область ЕЕПРОМ по адресам 0-64. Везде ФФ, и только в 2-х ячейках "6" и "9". Придется заказывать новый датчик, видимо...

Александр говорить:
17.01.2012 17:44
Вопрос решился.  Приехал другой датчик - все чудесно читается.

Okey говорить:
24.04.2013 16:45
В даташите на этот НР03МА непонятно пронумерованы выводы в таблице, по отношению к схеме включения и размерам. Все наоборот. Где правда?

andre говорить:
25.04.2013 07:45
В документации на изображении http://www.avislab.com/blog/wp-content/uploads/2011/03/HP03M.png слева вид сверху, справа датчик перевернут. Обращайте внимание на метку (в виде точки), обозначающую первый вывод. Из за этого и путаница.

P.S. Рекомендую обратить внимание на датчик давления bmp085 http://www.avislab.com/blog/bmp085/. Я в свое время перешел на него и до сих пор безмерно счастлив. Характеристики лучше и стабильнее. Цена меньше.

Додати коментар
Code
* - обов'язкові поля

Архіви