emilo9 Napisano Grudzień 29, 2012 Udostępnij Napisano Grudzień 29, 2012 Witam. Mój problem jest następujący. Pomiar napięcia rozpoczynam przyciskiem i chcę go zakończyć tym samym przyciskiem. Najpierw sprawdzam czy wciśnięty jest przycisk i wykonuje się pomiar w trybie pomiaru ciągłego. Zakończenie pomiaru jest obsługiwane przerwaniem. Teraz problem jest taki że sprawdzenie ponownego wciśnięcia przycisku działa tylko w funkcji obsługującej przerwanie, a nie działa w pętli głównej programu, nawet wtedy gdy próbowałem ustawiać flagę w przerwaniu i sprawdzać w pętli głównej czy wciśnięty jest przycisk. Teraz: 1. Jeśli sprawdzam stan przycisku w funkcji obsługującej przerwanie pojawiają się opóźnienia, które są niemile widziane. 2. Nie wiem jak powrócić na początek pętli głównej po sprawdzeniu czy przycisk został wciśnięty drugi raz. Z góry dziękuję za pomoc. Oto kod: volatile float adc; //zmienna do obliczenia napięcia volatile char flaga; ISR(ADC_vect) { adc=((ADC*VREF)/1024)*DZIELNIK; //spr_2_przycisk(); if(!(PINB & 0x01)) { //sprawdzenie _delay_ms(100); while(!(PINB & 0x01)){} //stanu ADCSRA=(0<<ADEN); LCD_CLEAR; // przycisku _delay_ms(10); LCD_LOCATE(0,0); //przy zakończeniu pomiaru lcd_puts("Koniec pomiaru"); } } void main(void) { char wynik[]=" "; lcd_init(); // Funkcja inicjalizuje wyświetlacz /* Włącza wyświetlanie */ LCD_DISPLAY(LCDDISPLAY); menu_tekst(); LCD_CLEAR; LCD_LOCATE(0,0); /* Funkcja lcd_puts wysyła do wyświetlacza ciąg znaków */ lcd_puts("Wcisnij przycisk"); _delay_ms(500); DDRB = 0x00; PORTB = 0x07; while(1) { //sprawdzenie stanu przycisku if(!(PINB & 0x01)) { _delay_ms(100); while(!(PINB & 0x01 )){} //po wciśnięciu i puszczeniu początek pomiaru adc_wl(); //inicjalizacja przetwornika sei(); // globalna obsługa przerwań for(;;) { sprintf(wynik,"U=%1.2f [V]",adc); //konwersja wyniku LCD_LOCATE(4,1); lcd_puts(wynik); //wyświetlenie wyniku pomiaru _delay_ms(200); } } _delay_ms(100); if(!(PINB & 0x02)) { _delay_ms(100); while(!(PINB & 0x02)){} LCD_CLEAR; LCD_LOCATE(0,0); lcd_puts("Wybrales 2 "); _delay_ms(200); } if(!(PINB & 0x04)) { _delay_ms(100); while(!(PINB & 0x04)){} LCD_CLEAR; LCD_LOCATE(0,0); lcd_puts("Wybrales 3 "); _delay_ms(200); } } } Link do komentarza Share on other sites More sharing options...
Marooned Grudzień 29, 2012 Udostępnij Grudzień 29, 2012 Nie odpowiem na główny problem, ale rzucają mi się w oczy dwie rzeczy: - inicjujesz niektóre rzeczy w pętli zamiast raz (ADC i sei()) - po co? - kod w obsłudze przerwania jest wolny - używasz delay oraz wolnego dzielenia podczas, gdy dzielnikiem jest potęga dwójki, więc mógłbyś "dzielnik" przesunąć o 10 bitów (jeśli to typ całkowity) lub chociaż podzielić go raz przed pętlą główną (jeśli się nie zmienia, a na to wygląda) Link do komentarza Share on other sites More sharing options...
perlon Styczeń 5, 2013 Udostępnij Styczeń 5, 2013 Na moje po inicjacji pomiaru wpadasz w pętlę nieskończoną która w kółko wyswietla wynik pomiaru pomimo 'że pomiar jest już zakończony przez przerwanie. Skan stanu przycisku jest sprawdzany w przerwaniu bo przerwania "wskakują" w tę pętlę ale program nigdy nie dojdzie do końca pętli głównej. Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »