Среда, 06.08.2025, 09:07
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Помоги сайту
Поддержи наш сайт
Через WebMoney
U222865683087
R391933670808
Z877043628365
E649133782052

или пополни нашу SMS копилку
SMS.копилка

Ссылки

 Каталог статей
Главная » Статьи » Учимся работать с AVR

Простой термометр на LCD (DS18B20)
Привет.
Вот в этом уроке я покажу вам как быстро спаять простой термометр.
Для этого нам понадобиться ATMega8, LCD(16*2), DS18B20, печатная плата, панелька для микроконтроллера.

Итак, приступим, сначала откроем Code Vision AVR.
Создаем новый проект, без использования мастера, потом создаем текстовый документ с расширением ".с"
и добавляем туда следующий код:

 #include <mega8.h>               //библиотека ввода\вывода
#include <delay.h>               //библиотека задержки
#asm                             //сообщаем куда подключен датчик
        .equ __w1_port=0x15; PORTC
        .equ __w1_bit=3
#endasm                 
#asm                             //сообщаем куда подключён экран
    .equ __lcd_port=0x18
#endasm
#include <lcd.h>                 //библиотека для LCD
#include <1wire.h>               //библиотека работы с 1Wire
#include <ds18b20.h>             //библиотека для работы с датчиком ds18b20
#include <stdio.h>               //ненаю что за библиотека, но без неё неполучается
char lcd_buffer[33];             //масив с данными для экрана
void main(void)                 
{
unsigned char devices;         //переменная в которой количество присоеденённых датчиков
int temp;                        //переменная для хранения температуры
lcd_init(16);                    //инициилизация LCD, и говорим что он на 16 символов
devices=w1_init();               //ищим датчики
while(devices>0)                 //бесконечный цикл, если датчик подключон
      {
          temp=ds18b20_temperature(0);  //читаем температуру 
          if (temp>1000){               //если датчик выдаёт больше 1000
             temp=4096-temp;            //отнимаем от данных 4096
             temp=-temp;                //и ставим знак "минус"
          }
          sprintf(lcd_buffer,"t=%i.%u\xdfC",temp,temp%1);    //записуемв масив для экрана температуру и всё такое
          lcd_clear();                //чистим дисплей перед выводом
          lcd_puts(lcd_buffer);        //выводим масив на LCD
          delay_ms(500);              //ждём 500мс
      };
}

потом компилируем и выбираем частоту 8 МГц.
Прошиваем, и еще прошиваем фюзы на ту же частоту

Дальше дело за аппаратной частью,

Вот и все, 15 минут и термометр готов!!!

Схема и прошивка принадлежит Kirk99

Категория: Учимся работать с AVR | Добавил: my-avr (07.09.2008)
Просмотров: 105383 | Комментарии: 67 | Рейтинг: 4.2/19 |
Всего комментариев: 67« 1 2 3 4 5 6 »
35 Дима  
0
А LM75 я так понимаю дескретность по 0.5 градуса?

37 HiSER  
0
Да

34 Дима  
0
Спасибо друзья что с буфером подсказали никак не мог догнать почему 33 =))) У меня то 4 строки 20 символов получается мне надо 80 ?

36 HiSER  
0
Не обязательно, смотря как будешь выводить на экран.
Если все сразу то 81, 1 байт на 0-й символ (окончание строки).

33 lameruga  
0
вот вариант с точностью до 0.1, правда здесь дисплей от Nokia 3310. Датчик подключен на PD2.

/*****************************************************
ATmega8
4,000000 MHz
*****************************************************/
#include <mega8.h>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x12 ;PORTD
.equ __w1_bit=2
#endasm
#include <1wire.h>
// DS1820 Temperature Sensor functions
#include <ds18b20.h>
#include <delay.h>
// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS18B20 3
// number of DS1820 devices
// connected to the 1 Wire bus
unsigned char ds18b20_devices;
// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];
#include <3310lcd.c>
#include <stdio.h>

// Declare your global variables here
float temper;
int temper_int,temper_fl,min=0;

void temperature(void) // функция по работе с термо-датчиком
{
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
temper_int=temper; // отбор целой части от температуры
if(temper<0) // при отрицательной температуре
{
temper_fl=(temper-temper_int-0.0625)*10; // дробная часть
temper_int=-((temper_int*10)+temper_fl); // температура*10
min=1; // минус
}else // при положительной
{
temper_fl=(temper-temper_int)*10; // дробная часть
temper_int=(temper_int*10)+temper_fl;// температура*10
min=0; // плюс
}
}
void main(void)
{
// Determine the number of DS1820 devices
// connected to the 1 Wire bus
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
ds18b20_init(0,-35,35,DS18B20_12BIT_RES); // переключения термометра в 12 битный режим

LcdInit(); // LCD module initialization

while (ds18b20_devices>0 )
{
// Place your code here
delay_ms(500);
temperature(); // вызываем функцию температуры
LcdClear(); // очищаем LCD
if(min==1) // если минус
{
sprintf(lcd_buf,"-%u.%u\x80C",temper_int/10,temper_int%10); //вывод отрицательной температуры
}else
{
sprintf(lcd_buf,"+%i.%d\x80C",temper_int/10,temper_int%10); // вывод положительной
}
LcdStringBold(1,2);
LcdUpdate(); // вывод на дисплей
};


}


32 cancerogen  
0
вот вариант с точностью до 0.1, правда на дисплее от Nokia 3310. Здесь датчик подключён на PD2.

/*****************************************************
ATmega8
4,000000 MHz
*****************************************************/
#include <mega8.h>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x12 ;PORTD
.equ __w1_bit=2
#endasm
#include <1wire.h>
// DS1820 Temperature Sensor functions
#include <ds18b20.h>
#include <delay.h>
// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS18B20 3
// number of DS1820 devices
// connected to the 1 Wire bus
unsigned char ds18b20_devices;
// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];
#include <3310lcd.c>
#include <stdio.h>

// Declare your global variables here
float temper;
int temper_int,temper_fl,min=0;

void temperature(void) // функция по работе с термо-датчиком
{
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
temper_int=temper; // отбор целой части от температуры
if(temper<0) // при отрицательной температуре
{
temper_fl=(temper-temper_int-0.0625)*10; // дробная часть
temper_int=-((temper_int*10)+temper_fl); // температура*10
min=1; // минус
}else // при положительной
{
temper_fl=(temper-temper_int)*10; // дробная часть
temper_int=(temper_int*10)+temper_fl;// температура*10
min=0; // плюс
}

}
void main(void)
{
// Determine the number of DS1820 devices
// connected to the 1 Wire bus
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
ds18b20_init(0,-35,35,DS18B20_12BIT_RES); // переключения термометра в 12 битный режим

LcdInit(); // LCD module initialization

while (ds18b20_devices>0 )
{
// Place your code here
delay_ms(500);
temperature(); // вызываем функцию температуры
LcdClear(); // очищаем LCD
if(min==1) // если минус
{
sprintf(lcd_buf,"-%u.%u\x80C",temper_int/10,temper_int%10); //вывод отрицательной температуры
}else
{
sprintf(lcd_buf,"+%i.%d\x80C",temper_int/10,temper_int%10); // вывод положительной
}
LcdStringBold(1,2);

};


}


31 urii  
0
#include <stdio.h> библиотека строковой переменной я так думаю иначе lcd_puts не прокатит

30 Мирослав  
0
В строчке lcd_buffer,"t=%i.%u\xdfC",temp,temp%1 есть ошибка, правильно lcd_buffer,"t=%i.%u\xdfC",temp,temp%10

29 Vanek_21  
0
mor_ivan@sibmail.com

28 Vanek_21  
0
Добавил к данной схеме два светодиода зеленый и красный на порт PC0 и PC1 соответственно; и данные температуры пересылаются по Uart. Если датчик подключен, то моргает зеленый, если нет, то красный. Подправил прогу теперь есть проверка на подключения датчика, то есть датчик можно включить после подачи питания. Если что-то не понятно, пишите на ящик.
собственно программа:

#include <mega8.h> //библиотека ввода\вывода
#include <delay.h> //библиотека задержки
#asm //сообщаем куда подключен датчик
.equ __w1_port=0x15; PORTC
.equ __w1_bit=3
#endasm
#asm //сообщаем куда подключён экран
.equ __lcd_port=0x18
#endasm
#include <lcd.h> //библиотека для LCD
#include <1wire.h> //библиотека работы с 1Wire
#include <ds18b20.h> //библиотека для работы с датчиком ds18b20
#include <stdio.h>
char lcd_buffer[33]; //создаем масcив с данными для экрана
void usart_tx(unsigned char data)
{ // передача по UART
while ( !(UCSRA & (1<<5)) ); //ждём очистки регистра данных UART
UDR=data; //отправить
}
void main(void)
{
unsigned char devices; //переменная в которой количество присоединённых датчиков
int temp; //переменная для хранения температуры
lcd_init(8); //инициализация LCD, и говорим что он на 8 символов в каждой стоке
UCSRA=0x00; UCSRB=0x08; //настройка Uart на передачу, скорость 2400
UCSRC=0x86; UBRRH=0x00;
UBRRL=0xCF;
DDRC.0=1; DDRC.1=1; //настройка порта PС0 и PС1 на выход
devices=w1_init(); //инициализация датчика
while(devices==0) /* проверка на подключение датчика если его нет,то будем быстро мигать (период 0.3 сек) и передавать по UART 241 до устранения неисправности*/
{
delay_ms(150); // пауза 150 мС
PORTC.1 = 1; // вЫкл светодиод
delay_ms(150); // пауза 150 мС
PORTC.1 = 0; // вкл светодиод
sprintf(lcd_buffer,"Error NoConnect!"); //задаем массив для выдачи ошибки
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd_buffer); //Выводим Error No Connect!
while ( !(UCSRA & (1<<5)) ); //ждём остки регистра данных UART
UDR=241; //отправляем 241
devices=w1_init(); //ищем датчики
};
while(devices>0) //бесконечный цикл, если датчик подключен
{
PORTC.0=0; //гасим светодиод
temp=ds18b20_temperature(0); //читаем температуру
usart_tx(temp); //отправляем на комп результат температуры
if (temp>1000)
{ //если датчик выдаёт больше 1000
temp=4096-temp; //отнимаем от данных 4096
temp=-temp; //и ставим знак "минус"
}
usart_tx(temp); //отпровляем на комп результат температуры
sprintf(lcd_buffer,"\xAF\xAA\xAA 1A61t=%i.%u\xdfC",temp,temp%1); //задаем массив реквизитов
lcd_clear(); //чистим дисплей перед выводом
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer); //выводим массив на LCD
devices=w1_init(); //инициализация датчика
while(devices==0) /* проверка на подключение датчика если его нет, то будем быстро мигать (период 0.3 сек) и передавать по UART 241 до устранения неисправности*/
{
delay_ms(150); // пауза 150 мС
PORTC.1 = 1; // выкл светодиод
delay_ms(150); // пауза 150 мС
PORTC.1 = 0; // вкл светодиод
sprintf(lcd_buffer,"Error NoConnect!"); //задаем массив выдачи об ошибки
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd_buffer); //Выводим Error No Connect!
while ( !(UCSRA & (1<<5)) ); //ждём очистки регистра данных UART
UDR=241; //отправляем 241
devices=w1_init(); //ищем датчики
};
PORTC.0=1; //зажигаем светодиод
delay_ms(150); // пауза 150 мС
};
}


27 misha  
0
онм не шарят как несколько инициировать )))))))))

26 Genych  
0
25 Onkel (19.02.2010 14:12)
касательно DS18B20 - работает он у меня на проге сгенеренной Code Vision, но имею следующую засаду - мк (атмега8) дает команду ds18b20_temperature(NULL) ( у меня он один висит на 1wire) и висит 746 мс, а мне надо байты принимать/передавать, ацп запускать и прочее. Ну думаю, можно дать команду "меряй", а потом быстренько считать. А вот таких команд по раздельности в CV нет. Пробовал следующее

ds18b20_init(Null,18,25,3); // инициализация проходит, возвращает 1 как положено
w1_write(0xcc); // scip rom, все равно на шине он один
w1_write(0x44); // команда мерять Т
w1_write(0xBE); // read scratchpad
Tlow=w1_read(); // считываю в переменную мл. разряд результата преобразования
Thigh=w1_read();// считываю в переменную ст. разряд результата преобразования
w1_init();// обрубаю передачу, больше мне ничего не нужно от термометра

ну так ничего не считывается - обе переменные FF, пробовал и с задежками между всеми командами.

Ошибка у меня или как - то по - другому надо обмен с DS делать?

Всё правильно. Только эта функция не случайно висит 750мс - это максимальное время преобразования температуры датчиком. Поэтому я делаю почти так же только после команды преобразования температуры (w1_write(0x44); // команда мерять Т) иду делать то, что мне нужно, а считывание температуры произвожу после того как пройдет приблизительно время преобразования. Можно сделать две отдельные функции - одну на запрос преобразования, вторую на считывание.


1-10 11-20 21-30 31-40 41-50 51-55
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright My-AVR © 2025
Наша кнопка
У нас появилась кнопка, код кнопки:

Лаборатория самоделок на микроконтроллерах AVR

Форма входа
Наш опрос
Как вам материалы на сайте
Всего ответов: 864
Статистика/Друзья
CY-PR.com



Онлайн всего: 1
Гостей: 1
Пользователей: 0

РадиоКОТ - популярно об электронике. Авторские схемы, новые разработки. Обучение по электронике, микроконтроллерам, ПЛИС. Форум Сайт по радиоэлектронике. У нас все просто и интересно… ARV Reserch: Электроника — просто, полезно, увлекательно. Электронные устройства и программные средства для радиолюбителей и профессионалов, только авторские разработки, плагиата нет! Разработки на заказ. AVR projects Создание электронных роботов своими руками Схемы и программы на AVR http://ur5yfv.ucoz.ua/BANNER.gif Блог начинающего эмбеддера. Дай волю паяльнику! Самоделки на all-make.ru Принципиальные схемы Модулі автозапуску бензогенератора та системи АВР, електромонтажні роботи
Хостинг от uCoz