Продолжаем осваивать периферию, на очереди измерение температуры. Рассмотрим вариант измерения, при помощи датчика температуры DS18b20.
Характеристики датчика: диапазон измерения от -55 до +125°С. Точность измерения ±0,5°С гарантируется в диапазоне от -10 до +85°С. Возможность измерения с разрешением 9, 10, 11 и 12 бит, т.е. с шагом 0,5; 0,25; 0,125; 0,0625°С. Для обмена информацией с AVR микроконтроллером используется 1-Wire протокол. Каждый датчик имеет свой уникальный адрес, поэтому имеется возможность посадить на шину сразу несколько датчиков.
Для сборки схемы понадобится жк дисплей, датчик и резистор на 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 — вывод на экран значка градуса.
В результате должно получиться нечто похожее
Отрицательной температуры поблизости не было :D, поэтому попробовал остудить бутылочкой соуса из холодильника, результат что то не сильно впечатлил.
Зато от нагрева рукой, температура довольно быстро повысилась.
Проект доступен тут
Проект для DS18s20
Проект для двух датчиков
Проект для DS18b20 на семисегментниках
Проект Алексея(Alyes)для Atmega16 и шести сегментов + бонус видео устройства
Здравствуйте! На семисигментниках собрал термометр с отображением до десятых долей градуса.В протеусе все ОК.В железе при вкл на индикаторе отображается ересь-как будто два итображения чисел вместе накладываются Железо вроде ОК ( с программой на два знака(целые значения температуры) все норм работает!Программу тоже пошагово проверял все нормально. Может кто подскажет в чем дело-писал пропеты и посложнее и все получалось , а тут споткнулся…
это нормально 🙂 попробуйте реже опрашивать для начала.
Здравствуйте Уважаемый Admin! Подскажите пожалуйста как в Codevisionavr 2.05 сделать проект с двумя и более температурными датчиками DS18B20? В конце Вашей статьи есть Проект Алексея(Alyes), выполненный в CVAVR 2.05, но заставить работать его с двумя датчиками никак не могу добиться. Подскажите пожалуйста куда какие стоки нужно добавить?
Спасибо.
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
#include
#include
// 1 Wire Bus interface functions
#include
// DS1820 Temperature Sensor functions
#include
void main(void)
{
// Declare your local variables here
float temper;
unsigned int x;
// 1 Wire Bus initialization
// 1 Wire Data port: PORTD
// 1 Wire Data bit: 7
// Note: 1 Wire port settings must be specified in the
// Project|Configure|C Compiler|Libraries|1 Wire IDE menu.
w1_init();
ds18b20_init(0,-20,50,DS18B20_12BIT_RES);
// Global enable interrupts
#asm(«sei»)
while (1)
{
temper=ds18b20_temperature(0);
if (temper>1000)
{
temper=4096.0-temper;
minus=1;
}
x=temper*10;
nom4=x%10;//разборка целого числа на отдельный сегмент…
x=x/10;
nom3=x%10;
nom2=x/10;
nom5=10;
nom6=11;
if(minus==0)
{
nom1=12;
}
else
{
nom1=13;
}
}
}
посмотрите про статическую и динамическую индикацию, тут легкого пути нет.
#include
#include
// 1 Wire Bus functions
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=0
#endasm
#include
//#include
#define MAX_devices 8
unsigned char rom_code[MAX_devices][9];
// Declare your global variables here
unsigned char a,b,c;
eeprom unsigned char key[5][3]={ {0x00,0x00,0x00},
{0x00,0x00,0x00},
{0x00,0x00,0x00},
{0x00,0x00,0x00},
{0x00,0x00,0x00}};
eeprom int count_keys=0; // список ключей
int i,j,devices;
bit security=0; // 1-режим охраны, 0-снято с охраны;
//eeprom int address[4][6];
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if (security==1)
{
PORTC.2=1;
PORTC.4=0;
}
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
if (security==1)
{
PORTC.2=1;
PORTC.4=0;
}
}
void programming(void) // программирование ключей
{
if (count_keys==4) count_keys=0;
devices=w1_search(0xf0,&rom_code[0,0]);
if (devices!=0)
{
for (j=1;j<=10;j++)
{
key[count_keys][0]=rom_code[0,3];
key[count_keys][1]=rom_code[0,2];
key[count_keys][2]=rom_code[0,1];
}
count_keys=count_keys+1;
delay_ms(1000);
for (j=1;j<=count_keys;j++)
{
PORTC.5=0;
delay_ms(700);
PORTC.5=1;
delay_ms(700);
}
PORTC.5=0;
delay_ms(1000);
}
}
void main(void)
{
// Declare your local variables here
// 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=Out Func4=Out Func3=In Func2=Out Func1=In Func0=In
// State6=T State5=0 State4=0 State3=T State2=0 State1=T State0=P
PORTC=0x01;
DDRC=0x34;
// 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;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
GICR|=0xC0;
MCUCR=0x00;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Determine the number of DS1820 devices
// connected to the 1 Wire bus
// Global enable interrupts
#asm("sei")
PORTC.4=1; // Инвертированный выход реле
while (1)
{
if (PINC.0==1) // если не включен режим программирования
{
programming(); // функция программирования ключей
for (j=1;j<=10;j++)
{
PORTC.5=!PORTC.5;
delay_ms(50);
}
}
else
{
devices=w1_search(0xf0,&rom_code[0,0]);
if (devices!=0)
{
for (j=1;j<=6;j++)
{
a=rom_code[0,3];
b=rom_code[0,2];
c=rom_code[0,1];
}
for (i=1;i<=count_keys;i++)
{
if ((key[i-1][0]==a)&(key[i-1][1]==b)&(key[i-1][2]==c))
{
PORTC.5=!PORTC.5;
security=!security;
PORTC.2=0; /// Выход сигналиции на звук
PORTC.4=1; /// Выход сигналиции на свет
}
} // for (i=1;i<=count_keys;i++)
}; //if (devices!=0)
delay_ms(300);
}; //else
} // while
}
выдает следующие ошибки:
Error: D:\Архив\уроки codevision avr\разное иредкое\ibutton\CVA\1-wire.c(56): missing ']'
Error: D:\Архив\уроки codevision avr\разное иредкое\ibutton\CVA\1-wire.c(62): missing ']'
Error: D:\Архив\уроки codevision avr\разное иредкое\ibutton\CVA\1-wire.c(187): missing ']'
Error: D:\Архив\уроки codevision avr\разное иредкое\ibutton\CVA\1-wire.c(193): missing ']'
Уважаемый помоги!!! в чем тут дело?
Спасибо!!! Разобрался 😛 😛 😛 😛
Я понял ошибку ! 🙂
Здравствуйте. Подскажите пожалуйста, возможно ли одновременное использование датчиков ds18b20 и dht11? Если да, то их нужно садить на разные порты или на один?
Заранее благодарен.
насколько я помню у них разные тайминги, поэтому подозреваю, что будут конфликтовать.