Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

termoПродолжаем осваивать периферию, на очереди измерение температуры. Рассмотрим вариант измерения, при помощи датчика температуры DS18b20.

Характеристики датчика: диапазон измерения от -55 до +125°С. Точность измерения ±0,5°С гарантируется в диапазоне от -10 до +85°С. Возможность измерения с разрешением 9, 10, 11 и 12 бит, т.е. с шагом 0,5; 0,25; 0,125; 0,0625°С. Для обмена информацией с AVR микроконтроллером используется 1-Wire протокол. Каждый датчик имеет свой уникальный адрес, поэтому имеется возможность посадить на шину сразу несколько датчиков.

les12-2

Для сборки схемы понадобится жк дисплей, датчик и резистор на 4,7кОм. Теперь перейдем непосредственно к прошивке.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <mega8.h>
#include <delay.h>
// 1 Wire Bus functions
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=2
#endasm
#include <1wire.h>
#include <ds18b20.h>
 
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h> 
 
char lcd_buf[17];
void main(void)
{
 
float temper;  
lcd_init(16);   
w1_init();
ds18b20_init(0,-20,50,DS18B20_12BIT_RES); 
 
while(1)                 
      {
          temper=ds18b20_temperature(0);  
          sprintf(lcd_buf,"t=%.1f\xdfC",temper);    
          lcd_clear();                
          lcd_puts(lcd_buf);        
          delay_ms(1500);              
      }; 
}

Теперь обо всем по порядку:

1
2
3
4
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=2
#endasm

Данный код означает, что датчик подключен к порту В, PB2 ножке

1
2
#include <1wire.h>
#include <ds18b20.h>

Используется протокол 1wire, тип датчика ds18b20

1
2
3
float temper;  
w1_init();
ds18b20_init(0,-20,50,DS18B20_12BIT_RES);

Переменная temper (с плавающей точкой) используется для хранения температуры,
w1_init(); — ищем датчик,
ds18b20_init(0,-20,50,DS18B20_12BIT_RES); — настройка датчика: 0-номер датчика, -20 -нижний предел измерения, 50 — верхний предел измерения,
DS18B20_12BIT_RES используется 12 битный режим(с шагом 0,0625°С). В принципе настройку можно не производить, по умолчанию выставлен 12 битный режим. Показано лишь для того, чтобы вы могли самостоятельно изменить режим измерения, если это понадобится.

1
2
3
4
5
6
          temper=ds18b20_temperature(0);  
 
          sprintf(lcd_buf,"t=%.1f\xdfC",temper);    
          lcd_clear();                
          lcd_puts(lcd_buf);        
          delay_ms(1500);

temper=ds18b20_temperature(0); — читаем значение температуры с датчика
sprintf(lcd_buf,»t=%.1f\xdfC»,temper); преобразовываем к понятному для lcd виду %.1f — вывод числа с плавающей точкой 1 знак после запятой, не забываем в свойствах проекта указать (s)printf features float.
\xdf — вывод на экран значка градуса.

В результате должно получиться нечто похожее
les12-4

Отрицательной температуры поблизости не было :D, поэтому попробовал остудить бутылочкой соуса из холодильника, результат что то не сильно впечатлил.
les12-5

Зато от нагрева рукой, температура довольно быстро повысилась.
les12-3
Проект доступен тут
Проект для DS18s20
Проект для двух датчиков
Проект для DS18b20 на семисегментниках
Проект Алексея(Alyes)для Atmega16 и шести сегментов + бонус видео устройства

259 комментариев: Урок 12. Измерение температуры при помощи AVR. Простой термометр на AVR.

  • Здравствуйте!
    Подскажите, собрал термометр на семисег. индикаторе, но при запуске показывает 00, отсоединяю резистор 4k7 с датчика показывает 09 тут же подсоединяю все отлично работает. При следующем запуске история повторяется. В чем может быть причина?

  • Причина найдена, вся неисправность была во фьюзах.

  • Подскажите пожалуйста , у меня с датчика постоянно снимается показание -9999С , еще подключен АЦП, что делать почему не работает?

  • Здравствуйте! На дисплее выводится -9999,0 °С. Из-за чего такие показания?

  • Разобрался наконец-то, а значит полдня потрачено не зря 🙂 Для датчика выставил бит, а сам на мк к другой ноге прицепился. Как только собрал правильно схему, всё сразу заработало правильно. Спасибо автору за статью.

  • Подскажите пожалуйста почему для нескольких датчиков при поиске их ROM используется переменная-массив на 9 байт, если ROM-код у датчиков 8-байтный? Спасибо.

  • Из кодевижн мануала:
    The pointer p points to an area of RAM where are stored the 8 bytes ROM codes returned by the
    device. After the eighth byte, the function places a ninth status byte which contains a status bit
    returned by some 1 Wire devices (e.g. DS2405). Thus the user must allocate 9 bytes of RAM for each device present on the 1 Wire bus.
    т.е. 9 байт используется для статуса

  • Здравствуйте, подскажите пожалуйста.написал код на часы под семисегментники и хочу их использовать вместе с дс18б20. но боюсь что будут конфликтовать ( тк код написан с прерываниями на 4 индикатора а датчик требует почти секундную задержку) Хочу чтобы часы и температура менялись в показаниях на индикаторе каждые 5-10 секунд. Как проще и наиболее надежнее реализовать это используя стандартную библиотеку для датчика? Мб использовать 2 контроллера(не жалко сделать на двух да да (один обрабатывает температуру и передает на 1 который индуцирует то часы то температуру получая данные))) и передавать между ними данные по UART?( про него пока что еще не читал)или использовать 2 контроллера с прерываниями по ноге?(правда не знаю как данные передавать тогда) либо использовать регистры( для них же прерывания не нужны?)

  • сейчас вроде модно стало подключать ds18b20 через уарт, сам не пробовал, так что подробностей не подскажу

  • Здравствуй дорогой админ.
    Решил сделать термо регулятор
    Данные вывожу на трехразрядный семисегментный индикатор.
    Уперся в проблему, единственный вариант когда данные не искажаются, это когда опрос датчика происходит в прерывании там же где и вывод на семисегменты, поставил я его между тем как тушу последний разряд и перед тем когда зажигаю первый и это с определенной периодичностью, но в таком случае на момент опроса индикатор потушен ориентировочно полсекунды.
    Можно ли с этим бороться?
    В других случаях когда опрос прерывается данные искажаются и на индикатор периодически выводит всякие не определенные символы…
    Это я так решил сэкономить дисплей…

  • посмотрите пост выше. можно подружить мк и 1-wire через уарт. как время появится потестирую и напишу статью

  • Понял, спасибо!
    Ну тогда будет он у меня мерять раз в 10сек и мерцать…
    Зато видно что работает))

  • Почему сэкономить) у светодиодных вещей свои преимущества)Хотя у меня пока тоже безуспешно. Но у людей есть термометры и без запретов прерываний и работают четко)) пока тоже не могу получить «нормальную» индикацию.

  • поставьте какой нибудь сдвиговый регистр он стоит копейки, сможете юзать статическую индикацию и будет у вас все работать нормально

  • Дада,как вы говорили свистелки и перделки 😀 ,но опять проблема- простой 4 разрядный индикатор имеет (8 цифр с точкой )и 4анода-катода.Даже сдвигая в регистр число, ябуду вынужден дрыгать катодами -анодами.(и опять же прерыванием?)и какой выигрыш даст мне регистр?2 регистра?опять же надо будет обновлять инфу чтобы разряды горели..задержки нельзя юзать,значит опять прерывание,получится даже дольше,ибо вынужден буду задвигать данные в регистр ещё,вместо просто присвоения переменной.

  • Все уже давно придумано, возьмите готовую хрень http://avr-start.ru/?p=3788 ей нужно всего 3 провода

  • А можно ли на два ds1820 датчика. Нифига не получается(. Почему то мало схем в интернете на 1820, вот всем приспичило 18b20…

  • Уважаемый Админ ! Очень хочу Вас попросить привести пример программы для считывания ключей ibutton с выводом на Lcd. И подробно разобрать эту программу. Сделайте такой урок, очень хочется.

  • Здравствуйте! Хотелось бы уточнить про функцию вывода температуры temper=ds18b20_temperature(0) !!!! Почему при компиляции проекта в СodeVision AVR, программа указывает ошибку на эту функцию? Ошибка распознается компилятором как неизвестный символ «ds18b20_temperature(0)». Можете ли Вы мне ответить на этот вопрос?

  • не подключена либа

  • Здравствуйте! Я чего-то не понимаю. В Атмеги8 же только 8 кб памяти, а ваш hex файл вешает 13. Прошивается без проблем?

  • прошивается без проблем

  • Здравствуйте! Хотелось бы узнать как сделать беспроводное измерение температуры на DS18B20 и двух радио модулях по UART интерфейсу. Можете ли Вы привести пример кода?

  • Тут особо нечего пояснять, снимаете температуру кидаете байт по уарту, на приемной стороне выводите его куда угодно. Модули можно взять готовые SIM20, они предоставляют «прозрачный» уарт, т.е. никаких дополнительных телодвижений.

  • Подскажите, что делать. Готовый файл hex загружается в протеус и всё работает, но когда хочу скомпилировать код в Atmel Studio , то на строчке, там где библиотека delay.h выскакивает ошибка. Пробовала разные варианты, ничего не помогает

  • util/delay.h

  • util/delay.h тоже не помогает, все равно выскакивает ошибка

  • Добрый день! Прошу прощения что не по теме. Очень нужна Ваша помощь. Нашел программу, не компилируется. Пишет ошибку, подскажите что в ней не так.
    #include
    #include
    #include

    // 1 Wire Bus functions
    #asm
    .equ __w1_port=0x18 ;PORTB
    .equ __w1_bit=0
    #endasm
    #include

    // Alphanumeric LCD Module functions
    #asm
    .equ __lcd_port=0x12 ;PORTD
    #endasm
    #include

    #define DS1990_FAMILY_CODE 1
    unsigned char lcd_buffer[33];
    unsigned char rom_code[8,9];

    void main(void)
    {
    unsigned char a,b,c,devices;

    // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // 1 Wire Bus initialization
    w1_init();

    // LCD module initialization
    lcd_init(16);

    while (1)
    {
    // Place your code here
    devices = w1_search(0xf0,&rom_code[0,0]);

    a=rom_code[0,1];
    b=rom_code[0,2];
    c=rom_code[0,3];

    sprintf(lcd_buffer,»Detected:%X\nCODE: %02X%02X%02X»,devices,c,b,a);
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_puts(lcd_buffer);
    delay_ms(50);
    };
    }

    Ошибка : unsigned char rom_code[8,9]; missing «]»
    Буду очень признателен! Спасибо!

  • unsigned char rom_code[8,9] вы двухмерный массив пытаетесь сделать? тогда он делается не так unsigned char rom_code[8][9]

  • Да, спасибо, Я вчера понял свою ошибку. Я хотел бы попросить Вас сделать урок по DS1990. Очень интересная тема. Да и примеров на codevisionavr на просторах интернета не так много. Устройство контроля допуска или сигнализации к примеру. С построчными описаниями алгоритма, было бы круто. Еще раз спасибо!

  • Добрый день! Информация о температуре хранится в temper=ds18b20_temperature(0);
    в переменной temper. Как можно передать эту информацию на выход в UART микроконтролера чтобы после можно было бы взять ее и отобразить на мониторе компьютора ? Задача такова: посылать постоянно сигнал в UART модуля HC-06 и через bluetooth выводить на монитор компьютера. Прямо посылать сигнал с датчика на UART модуля HC-06 на получается из за буферизации.

  • через printf

  • printf(temper) ? причем тут printf ? Это же для вывода на LCD

  • printf выводит форматированный буфер. Для сведения, printf будет выводить туда, куда вы скажете. В codevision по дефолту он выводит в UART.

  • Спасибо попробую!

  • добрый вечер
    подскажите пожалуйста как часто DS18B20 попадаются бракованными? купил две штуки фирмы DALLAS 18B20, ни один не работает, показывают -9999.0, монтаж проверил, мк настроен на 8 мгц, в пртеусе работает нормально, в чём может быть проблема?

  • то что работает в протеусе — не факт что все правильно. еще была фишка что те датчики par т.е. с паразитным питанием не работали если на них подать питание.

  • ДОБРОЕ УТРО
    СПАСИБО БОЛЬШОЕ !
    ВСЁ ЗАРАБОТАЛО 😛

  • Здравствуйте! Есть 2 или более датчиков которе посылают температуру каждые 500мс на LCD.

    Скажите пожалуйста как можно вывести серийный адрес датчика на LCD. Для того чтобы понемать от которого датчика эта температура .

  • можете посмотреть на функцию w1_search она возвращает ром коды. прям целиком готовый исходник есть в codevision user manual

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика