|
| |||||||
|
Опубликовано 2010-09-20 15:21:28 автором Ruslan Измерение температуры на AVR. Термометр на AVR на DS18B20. Урок avr 11В устройствах автоматики очень часто нужно контролировать какой-либо параметр окружающей среды: температуру, влажность, освещенность, давление и т.д. Для этого существуют датчики - устройства, которые преобразуют одну физическую величину в другую. Для измерения температуры существует очень много разнообразных датчиков, от простейших контактных (биметаллические, ртутные) до сложных преобразователей температуры в напряжение, частоту, ток и т.д. Сегодня я покажу, как цифровой датчик температуры DS18B20 подружится с микроконтроллером avr atmega8.
Диапазон измеряемых температур от –55°C до +125°C и точностью 0.5°C. Разрешающая способность по умолчанию установлена 12-бит, но может быть изменена пользователем на 9, 10, или 11 бит. Еще одна особенность DS18B20 - это возможность работать без внешнего питания, он может питаться от линии данных (“parasite power”), при отсутствии внешнего источника. Эта способность реализуется за счет того что внутри датчика есть конденсатор, который заряжается через подтягивающий резистор от высокого уровня на линии данных. Этот метод часто называют «Паразитным питанием». Давайте соберем простой термометр на DS18B20 и микроконтроллере atmega8. Задача:Цифровой термометр должен измерять температуру и выводить ее на lcd дисплей.Схема термометра выглядит следующим образом В CodeVision есть специальная библиотека для работы с DS18B20. В ней находятся все необходимые функции для работы с ним. Для того, чтобы использовать данный датчик в своих конструкциях, необходимо выполнить ряд несложных процедур по подключению датчика. На физическом уровне датчик подключается к одному из выводов любого порта. Вывод GND соединяется с общим проводом, вывод Vdd подключается к +5 В, а вывод DQ к линии выбранного порта. При этом на вывод DQ относится подтягивающий резистор (обычно 4,7 к), второй вывод которого подключается к +5 В. Программа выглядит так
#include <mega8.h>
#include <delay.h>
// 1 Wire Bus functions
//указываем, куда подключен датчик
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=0
#endasm
#include <ds18b20.h> //библиотека для работы с датчиком ds18b20
// Alphanumeric LCD Module functions
//указываем, куда подключён экран
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h> //библиотека для LCD
#include <stdio.h> // библиотека, в которой живет функция sprintf
char lcd_buf[16]; // масив, в котором формируются данные для вывода на lcd
float temperature; // переменная, в которой будет храниться значение температуры
void main(void)
{
lcd_init(16); // инициализация LCD на 16 символов
w1_init(); // // инициализация шины 1 wire
while(1)
{
temperature = ds18b20_temperature(0); //получаем температуру от датчика 0
sprintf(lcd_buf,"t=%.1f\xdfC",temperature); // формируем строку для вывода
lcd_clear(); // чистим дисплей
lcd_puts(lcd_buf); // выводим содержимое массива lcd_buf на дисплей
delay_ms(1000); // делаем задержку в 1 секунду
};
}
По программе вроде все понятно, единственное только - надо в свойствах проекта указать (s)printf features float и частоту мк выставить на 1 mhz, для этого переходим Project->Configure-> C Compiler и выставляем все как на скриншоте Сейчас мы сделаем еще один термометр но с выводом температуры на Led (семисегментный индикатор). C термометром на семисегментнике не все так просто, как кажется на первый взгляд. Дело в том что функция ds18b20_temperature блокирует выполнение основного потока, пока датчик не пришлет значение температуры, а это около одной секунды. Вот исходный код функции
float ds18b20_temperature(unsigned char *addr)
{
unsigned char resolution;
if (ds18b20_read_spd(addr)==0) return -9999;
resolution=(__ds18b20_scratch_pad.conf_register>>5) & 3;
if (ds18b20_select(addr)==0) return -9999;
w1_write(0x44);
delay_ms(conv_delay[resolution]); вот на этом delay_ms главный поток и останавливается
if (ds18b20_read_spd(addr)==0) return -9999;
w1_init();
return (*((int *) &__ds18b20_scratch_pad.temp_lsb) & ((int) bit_mask[resolution]))*0.0625;
}
а у нас-то индикация на семисегментнике динамическая, это значит что семисегментник будет зависать на период измерения температуры. Чтобы решить эту проблему, нам придется вручную посылать команды DS18B20. Алгоритм такой: послали команду на измерение температуры, и дальше занимаемся своими делами через полторы секунды спросили у датчика, измерил ли он температуру, если да, то получаем данные и выводим их на семисегментник. Посылать команды датчику мы будем с помощью функции w1_write. Давайте приступим к написанию кода Вывод значения температуры на дисплей состоит из следующих шагов:
Комментарии - (4)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||