Главная » Статьи » Cтатьи |
Подключение датчика ds18b20 к микроконтроллеру ATmega8535
Небольшой обзор DS18B20 – это цифровой термометр с программируемым разрешением, от 9 до 12–bit, которое может сохраняться в EEPROM памяти прибора. DS18B20 обменивается данными по 1-Wire шине и при этом может быть как единственным устройством на линии так и работать в группе. Все процессы на шине управляются центральным микропроцессором. DS18B20 состоит из ПЗУ содержащее 64-битный последовательный код, который позволяет, общаться с множеством датчиков DS18B20 установленных на одной шине, контроллера MicroLAN, температурного датчика, двух регистров для хранения верхнего и нижнего порогов температуры и регистра конфигурации. Регистр конфигурации позволяет пользователю устанавливать разрешающую способность цифрового преобразователя температуры к 9, 10, 11, или 12 битам, это и влияет на время конвертирования температуры. Термометр не содержит внутреннего источника, а использует "паразитное” питание от однопроводной шины. Однако при измерении температуры и записи данных в ЭППЗУ ток потребления микросхемы превышает 1 мА, в то время как максимальный ток, который может обеспечить ведущий шины с помощью нагрузочного резистора 1,5…5 кОм, составляет 3,3…1 мА. Применение внешнего источника питания ускоряет преобразование температуры, поскольку от ведущего шины не требуется ожидания в течение максимально возможного времени преобразования. В этом случае все приборы DS18B20, расположенные на шине, могут выполнять преобразование температуры одновременно и во время обмена данными шины MicroLAN. После завершения преобразования полученное значение сравнивается с величинами, хранящимися в регистрах TH и TL. Если измеренная температура выходит за установленные пределы, устанавливается сигнальный "флаг” (впрочем, его установка производится после каждого измерения). Выходные температурные данные DS18B20 калиброваны в градусах Цельсия. Внешний вид датчика в разных, корпусных исполнениях Расположение выводов 1- GND – корпус. 2- DQ – линия ввода\вывода данных. 3- Vdd – питание датчика. Схема подключения На один датчик С множеством датчиков Программная часть. Подключение одного датчика Подключим единственный датчик к микроконтроллеру atmega8535. Теперь начинаем творить программную часть. Подключаем к основному коду программы заголовочный файл ds18b20.h #include <ds18b20.h> Чтобы начать работать с одним датчиком, достаточно воспользоваться двумя функциями: Функция инициализации ds18b20_init( адрес датчика, нижний порог Т, верхний порог Т, разрешающая способность ); функция чтения температуры ds18b20_temperature( адрес датчика ); Структура будущей программы ... ... void main( void ) { ... ... if( //инициализация ds18b20 ) //Проверяем, есть ли устройство на линии 1-wire { while( 1 ){ //Цикл, в котором выполняется чтение и вывод значения температуры на LCD if( ) { } //Проверяем считанную температуру на отрицательное значение if( ) { } //Аварийное состояние считанной температуры } }else{ } //Ошибка - устройство не найденно } Полный код программы: //Цель: производим чтение температуры и выводим на LCD индикатор #include <mega8535.h> #include <delay.h> #include <stdio.h> #include <lcd.h> #asm .equ __lcd_port=0x15; PORTC #endasm #include <ds18b20.h> #asm .equ __w1_port=0x1B; PORTA .equ __w1_bit=0 #endasm int temper; //Переменая для хранения значения температуры unsigned char lcdBuff[16]; //Массив для хранения фоматированной строки #pragma rl+ char *str1="найден датчик ds18b20"; char *str2="датчик ds18b20 отсутствует"; #pragma rl- void main( void ) { lcd_init( 16 ); lcd_clear( ); if( ds18b20_init( 0, 30, 60, DS18B20_12BIT_RES ) ) //инициализация датчика. Анализ присутствия датчика { lcd_clear( ); lcd_puts( str1 ); delay_ms( 1000 ); while( 1 ){ temper=ds18b20_temperature( 0 ); //Чтение температуры, адрес нуль delay_ms( 30 ); //Анализ на отрицательную температуру if( temper>1000 ) { temper=4096-temper; temper=-temper; } //если переменая temper больше 1000 //То вычитаем от 4096 значение //переменой temper и далее //присваиваем ей знак минус if( temper>60 ) { /* какая-либо функция, например alarm ( ); */ } //Аварийное состояние считанной температуры sprintf( lcdBuff,"t %u\xdfC", temper ); //помещаем форматированую строку в массив //выводим на индикатор значение температуры lcd_clear( ); lcd_gotoxy( 0,0 ); lcd_puts( lcdBuff ); } }else{ lcd_clear( ); lcd_puts( str2 ); } } Если необходимо выводить значение температуры с точностью до одной сотой, необходимо в функции sprintf заменить тип формата %u на %.3f ( как использовать этот тип формата, будет описано ниже ) и переменную temper объявить как float. Описание программной части Функция инициализации датчика ds18b20: unsigned char ds18b20_init( unsigned char *addr, signed char temp_low, signed char temp_high, unsigned char resolution ); *addr – адрес датчика ( ROM данные ), к которому обращается микроконтроллер в случае, когда их много. Если датчик один, то всегда нуль. temp_low - значение нижнего порога температуры temp_high - значение верхнего порога температуры resolution – установка разрешающей способности цифрового преобразователя температуры к 9, 10, 11, или 12 битам. Принимает значения: • DS18B20_9BIT_RES • DS18B20_10BIT_RES • DS18B20_11BIT_RES • DS18B20_12BIT_RES Функция возвращает положительное значение в случае присутствия датчика на линии 1-wire. Функция чтения температуры: float ds18b20_temperature( unsigned char *addr ); *addr – адрес датчика, к которому обращается микроконтроллер в случае, когда их много. Если датчик один, то всегда нуль. Функция возвращает число с плавающей точкой значения температуры ( тип float ) Подключение двух датчиков При подключении более одного датчика ds18b20 на линию 1-wire, необходимо выполнять чтение ROM каждого датчика, чтоб обращаться к каждому индивидуально. Используя функцию w1_search, производим поиск устройств 1-wire, тем самым выясняем их количество на линии и производим чтение ROM данных каждого датчика: unsigned char devices; unsigned char rom_code[2][9]; devices=w1_search( 0xF0, rom_code ); //0xF0 можно заменить на DS18B20_SEARCH_ROM_CMD Переменная devices будет содержать целое число найденых устройств 1-wire ( датчики ds18b20 ), а массив rom_code будет содержать 8байт ( 64бита ) уникального кода датчика ds18b20. Этот код имеет следующий состав: Теперь по прочитанному ROM-коду можно обращаться к соответствующим датчикам. Полный код программы #include <mega8535.h> #include <delay.h> #include <stdio.h> #include <lcd.h> #asm .equ __lcd_port=0x15; PORTC #endasm #include <ds18b20.h> #asm .equ __w1_port=0x1B; PORTA .equ __w1_bit=0 #endasm #pragma rl+ char *str1="ЧТЕНИЕ ТЕМПЕРАТУРЫ"; char *str2="No SENSOR!"; #pragma rl- unsigned char devices; unsigned char LcdBuffDevices[20]; unsigned char RomCode[2][9]; unsigned char LcdBuff1[20]; unsigned char LcdBuff2[20]; void main( void ) { lcd_init( 20 ); lcd_clear( ); devices=w1_search( DS18B20_SEARCH_ROM_CMD, RomCode ); //поиск датчиков на линии 1-wire if( devices ) { sprintf( LcdBuffDevices,"DS18B20 = %u", devices ); //выводим информацию о кол-ве датчиков lcd_gotoxy( 0,1 ); lcd_puts( LcdBuffDevices ); lcd_gotoxy( 0,0 ); lcd_puts( str1 ); ds18b20_init( &RomCode[0][0], 30, 60, DS18B20_12BIT_RES ); //инициализация первого датчика ds18b20_init( &RomCode[1][0], 30, 60, DS18B20_12BIT_RES ); //инициализация второго датчика while( 1 ) { //чтение температуры первого датчика sprintf( LcdBuff1,"t1 %.2f \xefC", ds18b20_temperature( &RomCode[0][0] ) ); lcd_gotoxy( 0,2 ); lcd_puts( LcdBuff1 ); //чтение температуры второго датчика sprintf( LcdBuff2,"t2 %.2f \xefC", ds18b20_temperature( &RomCode[1][0] ) ); lcd_gotoxy( 0,3 ); lcd_puts( LcdBuff2 ); } }else{ lcd_gotoxy( 0,0 ); lcd_puts( str2 ); } } Текст и значение температур выводил на 4 строчный по 20 символов индикатор. Проект использования двух датчиков ds18b20 Впрочем инициализацию можно не выполнять, в том случае, если от датчика не требуется чтение «аварии», тем более по умолчанию установлено 12 битное значение преобразования температуры. Вспомним функцию sprintf ( Функция sprintf стандартной библиотеки stdio.h ).Используем тип формата f – число с плавающей точкой в записи с фиксированной десятичной точкой, т.е: %.0f – без вывода после запятой t 20 'C %.1f – единицы t 20.6 'C %.2f – десятки t 20.62 'C %.3f – сотки t 20.625 'C Чтобы данный тип формата работал в функции, необходимо в среде CodeVisionAVR зайти в Configure the project выбрать вкладку C Compiler, Code Generation выбрать из списка (s)printf Features строку float, width, precision Цикл программы, в котором происходит чтение температуры датчиков while( 1 ) { //чтение температуры первого датчика sprintf( LcdBuff1,"t1 %.2f \xefC", ds18b20_temperature( &RomCode[0][0] ) ); lcd_gotoxy( 0,2 ); lcd_puts( LcdBuff1 ); //чтение температуры второго датчика sprintf( LcdBuff2,"t2 %.2f \xefC", ds18b20_temperature( &RomCode[1][0] ) ); lcd_gotoxy( 0,3 ); lcd_puts( LcdBuff2 ); } Можно изменить на такой, более удобный unsigned char num=1; while( 1 ) { //чтение температуры датчиков ( испытание на два датчика ) do{ sprintf( LcdBuff1,"t%u %.2f \xefC",num, ds18b20_temperature( &RomCode[j][0] ) ); lcd_gotoxy( 0,j ); lcd_puts( lcdBuff ); if( --num<devices ){}else{ num=1; } }while( ++j<devices ); if( j==devices ) { j=0; } } Подключение датчиков на разные биты порта Такой фокус с библиотекой для датчика ds18b20 не получиться, т.к. компилятор не будеть понимать с какого именно бита одного и такого же порта происходит обращение к датчику. В случае с собственно написанной библиотекой успех будет положительным, т.к. мы сами определяем с какого бита производить обращение к датчику ds18b20. | |
Просмотров: 79502 | Комментарии: 25 | | |
Всего комментариев: 25 | 1 2 » | |||||||||||||
| ||||||||||||||
1-10 11-17 | ||||||||||||||