diff --git a/articles/2012/digitalni-teplomer-s-atmega8.md b/articles/2012/digitalni-teplomer-s-atmega8.md index 81488a698416f8081bbb6ad9e2cfb75be127b71c..414f978a1e2ae1955bed8bcb0078599d2d18f461 100644 --- a/articles/2012/digitalni-teplomer-s-atmega8.md +++ b/articles/2012/digitalni-teplomer-s-atmega8.md @@ -59,6 +59,118 @@ Deska byla vyrobena [metodou naĹľehlenĂm tonneru](/clanek/2008/vyroba-plosnych-  # ZdrojovĂ˝ kĂłd -``` +Jen hlavnĂ soubor `digitalni_teplomer.c`, pokud si chcete projekt zkompilovat sami, stáhnÄ›te si [celĂ˝ projekt](https://git.ok1kvk.cz/krouzek/digitalni-teplomer-s-atmega8/repository/archive.zip?ref=master) 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 + } +} +```