/*** =================================================================== ** Název souboru : 2013_5_15_ClappingSwitch_7_UART_4_zakmity ** Procesor : AtMega8 ** Frekvence CPU : 8 MHz ** Popis : Program vypocet plovouciho prumeru z hodnot ADC a provereni doby trvani prekroceni tresholdu ** Autor : Bílý, Mecerod ** Poslední změna : 16.5.2013 00:18 ** =================================================================== */ //#define F_CPU 8000000UL #include // definiční soubor mikrokontroléru #include // knihovna obsluhy přeručení //#include // knihovna zpoždění #include // matematická knihovna #include #include #include "uart.h" #define LED1_ON PORTB |= 0b00100000 // definice zapnutí LED1 #define LED1_OFF PORTB &=~0b00100000 // definice vypnutí LED1 #define LED2_ON PORTB |= 0b01000000 // definice zapnutí LED2 #define LED2_OFF PORTB &=~0b01000000 // definice vypnutí LED2 #define LED3_ON PORTB |= 0b10000000 // definice zapnutí LED3 #define LED3_OFF PORTB &=~0b10000000 // definice vypnutí LED3 volatile float cislo = 65000.555; volatile char buffer[30]; volatile uint16_t stav_ADC = 0; // proměná pro stav ADC volatile uint8_t priznak_ADC = 0; // proměná pro příznak dokončení ADC volatile float treshold = 0.25; // proměná pro příznak dokončení ADC volatile float prumer = 1000; // proměná pro hodnotu průměru bool status = false; volatile float priznak_TIMER_off = 0; volatile uint8_t priznak_TIMER_on = 0; volatile uint8_t priznak_preteceni = 0; volatile uint16_t end_time = 0; int InitADC(void) { /********************************************************************************************************* Inicializace ADC **********************************************************************************************************/ DDRC &=~ 0b00000001; // nastavení vstupního pinu pro ADC0 ADMUX |= (0< ADC0 ADCSRA |= (1< 1) // osetreni proti opakovanemu spinani { if (prumer > treshold) // byl prekrocen treshold => priznak_TIMER_off = 0; a priznak_TIMER_on = 0; { priznak_TIMER_on++; priznak_TIMER_off=0; } else { priznak_TIMER_off++; // nebyl prekrocen treshold => priznak_TIMER_on=0; priznak_TIMER_on=0; } if (priznak_TIMER_on == 1 ) // zacatek mereni { TCNT1 = 0; } if (priznak_TIMER_off == 1 ) // prumer poklesl po treshold => end_time = TCNT1; { priznak_preteceni = 0; end_time = TCNT1; TCNT1 = 0; CompareTime(end_time); } if (priznak_TIMER_off == 9000000) // osetreni prekroceni rozsahu promeně pri dlouhodobe necinnosti { priznak_TIMER_off = 2; } } return ( end_time ); } void CompareTime(int end_time) { /********************************************************************************************************* Funkce pro porovnání doby trvani tlesknuti end_time ------- pocet cyklu casovace pro vymezeni doby trvani tlesknuti status ------- promenna pro indikaci aktualniho stavu LED(zapnuto/vypnuto) **********************************************************************************************************/ if ((end_time > 1000) && (end_time < 30000) ) // 8 : 240 ms { if (status == false) // osetreni postupneho vypinani a a zapinani { LED3_ON; status = true; } else { LED3_OFF; status = false; } } } int main(void) { /********************************************************************************************************* Hlavni funkce Slouzi pro vypis plovouciho prumeru a promennych indikujicich aktualni stav na UART **********************************************************************************************************/ DDRB |= 0b11100000; // nastavení výstupních pinů pro LED1, 2, 3 DDRD &=~ 0b00100000; // nastavení vstupního pinu pro tlačítko S1 DDRC &=~ 0b00000010; // nastavení vstupního pinu pro tlačítko S2 uart_init(9600); InitADC(); InitTimer1(); sei(); while(1) { CountADC(); Treshold( prumer ); cislo = TCNT1; sprintf(buffer,"%f;%.4f;", cislo, prumer); uart_puts(buffer); sprintf(buffer,"%u;%.2f", priznak_TIMER_on, priznak_TIMER_off); uart_puts(buffer); sprintf(buffer,";%u;%u", end_time, priznak_preteceni); uart_puts(buffer); uart_puts("\n"); } } ISR( TIMER1_OVF_vect ) { /********************************************************************************************************* Obsluha přerušení pro osetreni proti opakovanemu **********************************************************************************************************/ priznak_preteceni++; } ISR( ADC_vect ) { /********************************************************************************************************* Obsluha přerušení při dokončení převodu ADC **********************************************************************************************************/ stav_ADC = ADCW; //načtení obsahu registrového páru ADCH:L priznak_ADC = 1; //nastavení příznaku dokončení převodu }