Další jednoduché zapojení určené pro náš kroužek mládeže, tentokrát jednoduchého teploměru s ATmega8 a čidlem teploty DS18B20. Najdete zde kompletní popis programu a zapojení včetně plošného spoje.
Pro správnou funkci teploměru je zapotřebí naprogramovat pojistky mikroprocesoru (fuses).
Pojistkami nastavíte, aby mikroprocesor použil jako hodinový signál interní 8 MHz oscilátor, jinak by běžěl na standardní frekvenci 1 MHz a nefungovalo by správně zobrazování teploty. Naše doporučené hodnoty pojistek jsou: hfuse=D9, lfuse=04
.
Schéma
Plošný spoj
Zdrojové soubory
Schéma: eagle, PDF Plošný spoj: eagle, PDF 1:1
Projekt na GitLabu digitalni-teplomer-s-atmega8.git
Aktuální zdrojový kód naleznete na našem GitLabu, kde také naleznete přeložený zdojový kód do formátu HEX.
Deska byla vyrobena metodou nažehlením tonneru.
Seznam součástek:
Označení | Hodnota | Datasheet | Odkaz do obchodu |
---|---|---|---|
R1 - R8 | 330 Ω | ||
R9 | 10 kΩ | ||
R10 | 4.7 kΩ | ||
C1, C2 | 100 µF | ||
C3 | 100 nF | ||
IC1 | 7805 (TO220) | LM7805.pdf | tme.eu |
IC2 | ATmega8A-PU | ATmega8a.pdf | tme.eu |
IC3 | DS18B20 | DS18B20.pdf | tme.eu |
D1 | LED displej | CA56-12SRWA.pdf | tme.eu |
D2 | zenerova dioda 5V6 | BZX55C5V6.pdf | tme.eu |
Fotky
Zdrojový kód
Jen hlavní soubor digitalni_teplomer.c
, pokud si chcete projekt zkompilovat sami, stáhněte si celý projekt se všemi soubory.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ds18b20_1.h"
#include "macros.h"
//Definice pozic segmentů na pinech portu
#define _s_A PD2
#define _s_B PD0
#define _s_C PD6
#define _s_D PD4
#define _s_E PD3
#define _s_F PD1
#define _s_G PD7
#define _s_dot PD5
const unsigned char segs[] = //Definice číslic na 7segmentové displeji
{
_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F), //0
_BV(_s_B) | _BV(_s_C), //1
_BV(_s_A) | _BV(_s_B) | _BV(_s_D) | _BV(_s_E) | _BV(_s_G), //2
_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_G), //3
_BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G), //4
_BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_F) | _BV(_s_G), //5
_BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //6
_BV(_s_A) | _BV(_s_B) | _BV(_s_C), //7
_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //8
_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G), //9
_BV(_s_G) //mínus
};
const unsigned char err[] = //Chyba
{
0, //mezera
_BV(_s_A) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //E
_BV(_s_E) | _BV(_s_G), //r
_BV(_s_E) | _BV(_s_G) //r
};
volatile int temp; //Proměnná pro teplotu
//V tomto přerušení se zobrazuje na despleji
ISR(TIMER1_COMPA_vect)
{
static int temp_1=0;
static unsigned char disp=0;
unsigned char dec;
disp++;
if(disp>3) disp=0; //cyklicky 0 - 4 (sedmisegmentovka)
PORTD=0xff; //vypnout segmenty
PORTC=0b00100000>>disp; //přepnout na danou sedmisegmentovku
if (temp==0x5fff) //pokud je chyba čidla
{
PORTD=(~err[disp]); //vypsání znaku chyby
}
else //pokud není chyba čidla
{
switch(disp)
{
case 0://1.cifra - znam�nko
if (temp>>15) //pokud je nejvyšší bit 1 (záporné číslo)
{
temp_1=temp*(-1); //převedení záporné teploty na kladnou
PORTD=(~segs[10]); //zobrazení mínus
}
else temp_1=temp/16; //převedení kladné teploty
break;
case 1://2.cifra - desítky
dec = temp_1 / 10;
if(dec>0) PORTD=(~segs[dec]);//zobrazit desítky
break;
case 2://3.cifra - jednotky
PORTD=(~segs[temp_1 % 10]) & ~_BV(_s_dot); //zobrazit jednotky a desetinnou tečku
break;
case 3://4.cifra - desetiny
PORTD = (~segs[((temp % 16)*625)/1000]); //zobrazit desetiny
break;
}//switch(disp)
}//else (temp==0x5fff)
}//ISR(TIMER1_COMPA_vect)
int main(void)
{
DDRD = 0xFF; //výstupy - segmenty
DDRC = 0x3F; //výstupy - displeje
setb(TCCR1B,0);
setb(TCCR1B,1); //start čítače 1 s předděličkou 64
setb(TCCR1B,3); //CTC mode
OCR1AH=0x01; //porovnávací registry
OCR1AL=0x39; //0x0139 = 313 = 8 000 000 / 64 / (100 * 4) (=> 100 Hz)
setb(TIMSK,4); //povolení přerušení od šasovače 1
setb(SREG,7); //globální povolení přerušení
while(1)
{
temp=gettemp();//přečtení teploty z čidla
}
}