Skocz do zawartości

[C] Problem z obsługą przycisku w przerwaniu.


emilo9

Pomocna odpowiedź

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

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

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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.