//================================= // Voltmetr s logickym vystupem a nastavenim hysterezniho pasma //================================= // verze: 4.4.2015 // POPIS: //========== // Pomoci trimru na PB3 (ADC3) se nastavi napeti, pri kterem se ma logicky vystup prepnout do "1" // Pomoci trimru na PB4 (ADC2) se nastavi napeti, pri kterem se ma logicky vystup prepnout do "0" // Napeti na PB4 musi byt nizsi, nez napeti na PB3. // Rozdil mezi temito dvema napetimi je hystereze, ktera zarucuje, ze pri prechodovem stavu nebude vystup zakmitavat // PB2 (ADC1) je hlavni merici vstup. // Hlavni logicky vystup je na PB0 // Druhy logicky vystup na PB1 je pomocny a signalizuje stav, kdy je merene napeti v hystereznim pasmu // Kvuli stabilite se vsechna napeti meri 20x a provadi se prumerovani // Vyznam jednotlivych vyvodu procesoru ATtiny13A: // PB0 = pin 5 = OUT - hlavni logicky vystup // PB1 = pin 6 = OUT - signalizace hysterezniho pasma // PB2 = pin 7 = ANALOG IN - hlavni merici vstup // PB3 = pin 2 = ANALOG IN - nastaveni napeti pro "H" // PB4 = pin 3 = ANALOG IN - nastaveni napeti pro "L" // PB5 = pin 1 = IN - nevyuzito (RESET) // VCC = pin 8 = napajeni +5V // GND = pin 4 = napajeni GND //=================================================================================================== #define F_CPU 9600000 // nastaveni vnitrni frekvence procesoru na 9.6 MHz #include // cteni analogove hodnoty z nastaveneho A/D prevodniku byte adc_read (byte kanal) { ADMUX = 0b00100000 | kanal; // zakladni nastaveni A/D prevodniku - ADLAR na "1" (=nejvyssich 8 bitu je pohromade) a nastaveni prislusneho vstupu // Start bit se nastavi do "1" ADCSRA |= 0b01000000; // cekani na ukonceni prevodu (bit ADSC v registru ADSRA padne do "0") while (ADCSRA & 0b01000000); return ADCH; // V ADCH je 8 nejvyssich bitu z namerene hodnoty (2 nejnizsi bity jsou v ADCL, ale tady nejsou vyuzity) } int main (void) { byte i = 0 ; // pocitadlo smycek pri prumerovani unsigned int prum_prom = 0 ; // pomocna promenna pro soucty pri prumerovani unsigned int uroven_H = 0 ; // nastavena hodnota trimrem H unsigned int uroven_L = 0 ; // nastavena hodnota trimrem L unsigned int napeti = 0 ; // napeti na hlavnim mericim vstupu DDRB = 0b00000011; // nastaveni smeru signalu na portu B ("1" = vystup ; "0" = vstup) - PB1=LED hysterezni pasmo; PB0=hlavni vystup ADCSRA = 0b10000111; // ADC enable bit na "1" a nastaveni delice frekvence pro ADC na 1:128 (=75kHz) while (1) // nekonecna hlavni smycka { prum_prom = 0; // prumerovani namereneho napeti na trimru L for (i=0; i<20 ; i++) { prum_prom += adc_read(2); } uroven_L = prum_prom / 20; prum_prom = 0; // prumerovani namereneho napeti na trimru H for (i=0; i<20 ; i++) { prum_prom += adc_read(3); } uroven_H = prum_prom / 20; prum_prom = 0; // prumerovani namereneho napeti na hlavnim mericim vstupu for (i=0; i<20 ; i++) { prum_prom += adc_read(1); } napeti = prum_prom / 20; // blok vzajemnych testu namerenych a nastavenych hodnot if (napeti > uroven_H) // merene napeti je vetsi, nez uroven nastavena trimrem H { PORTB &= 0b11111101; // hysterezni LED na PB1 zhasne ... PORTB |= 0b00000001; // ... a hlavni vystup na PB0 se nastavi do "1" } if (napeti < uroven_L) // merene napeti je mensi, nez uroven nastavena trimrem L { PORTB &= 0b11111100; // hysterezni LED na PB1 zhasne a hlavni vystup na PB0 se nastavi do "0" } if ((napeti > uroven_L) && (napeti < uroven_H)) // merene napeti je uvnitr hysterezniho pasma { PORTB |= 0b00000010; // hlavni vystup na PB0 se nemeni, ale hysterezni LED na PB1 se rozsviti } } // konec hlavni smycky }