Skocz do zawartości

Problem z wyjściem z pętli nieskończonej


Krawi92

Pomocna odpowiedź

Witajcie, studiuje wszystkie części poradnika o wskaźnikach i strukturach p. Kardasia, gdzie efektem ubocznym ma być gra snake. Gra działa, sterowanie, ekrany startowe i końcowe również. Jednak zaczynam się samemu bawić, przerabiając ich wygląd itp. Jedną z opcji, którą chciałem to, aby ekran nie znikał po czasie zadanym w _delay_ms jak jest orginalnie w poradniku, tylko, aby reagował na naciśnięcie klawisza, wtedy gra ma się rozpocząć. I tu pojawił się problem. Miałem troszkę przerwy od programowania i sporo rzeczy wyleciało z głowy i ciężko mi się czasem myśli  Oto jak kombinuje to rozwiązać.

void display_init( uint8_t usr_cnt ) {
        lcd_locate(0,0);
        lcd_str("****************");
        lcd_locate(1,0);
        lcd_str("*     SNAKE    *");
        lcd_locate(2,0);
        lcd_str("*  PRESS  KEY  *");
        lcd_locate(3,0);
        lcd_str("****************");
        while(1){
                IR_EVENT();
                if(command == 1)break;
               
        }
        lcd_cls();
}

Wrzucam pętle nieskończoną, aby zatrzymać ekran, w środku pętli wywołuje zdarzenie, które bada, czy nadleciała jakaś ramka. W ifie sprawdzam czy kod się zgadza, jeśli tak to program ma wyjść z pętli, a jednak tego nie robi. Kombinowałem na kilka innych sposobów, ale nie potrafie znaleźć rozwiązania wyjścia z pętli.
Ktoś podpowie, co robię nie tak ?

Gdy zamiast pętli jest zwykły delay, to po zakończeniu oczekiwania gra się uruchamia. 

Link do komentarza
Share on other sites

Return nie dziala??...no to zamiast jedynki daj jakas zmienna ktora bedzie w warunku while..

bool zmienna = 0;

while(zmienna == 0){
    IR_EVENT();
    if(command == 1) {
    zmienna = 1;
    }
}

Chociaz w twoim przypadku lepszy jest break, bo konczy while i wszystko dalej sie wykonac ma, z return to nie wykonala by sie ta funkcja po while i bys wyskoczyl z tej glownej funkcji...hmm, dziwne ze nie dziala ani jedno ani drugie🤔 a jestes pewny ze guzik dziala i "command" zostaje zmienione??

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Nie, to nie działa. Muszę się zastanowić jak działa dokładnie ta biblioteka do IR, bo gdy na tym ekranie wyświetlam zmienną command to mam cały czas 0. Jakby nie odbierał ramek, choć TSOP działa. 

Link do komentarza
Share on other sites

13 minut temu, Krawi92 napisał:

  bo gdy na tym ekranie wyświetlam zmienną command to mam cały czas 0. 

A no wlasnie, czyli returny brejki i inne wynalazki zapewne dzialaja, a problem to ze nie wykrywasz wcisniecia guzika...nie korzystam z IR wiec i nic nie doradze..

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

(edytowany)

Na razie przetestuje, jak to działa jak microswitcha podłącze i na nim zrobie warunek. Pewnie zadziała normalnie.

No i na sztywno jak microswitch podłączę to OK, działa. 

Edytowano przez Krawi92
Link do komentarza
Share on other sites

Przerwania masz włączone? Callback pod obsługę IR podpięty? IR też musisz mieć "pewny" w sensie czy wgl przylatuje command == 1

Edytowano przez _LM_
Link do komentarza
Share on other sites

Zrobie obiad i opiszę jak działa ta biblioteka tj. ile z niej kumam. Bo normalnie IR działa, jak gra uruchomi się to sterowanie jest, a przy ekranie początkowym nie mam. Zaraz wkleję trochę więcej kodu. Wczoraj dopiero łyknąłem trochę o callbackach i jeszcze nie bardzo wiem jak sobie radzić. 

Link do komentarza
Share on other sites

To może zacznijmy co to ten IR_EVENT

void IR_EVENT(void) {

	if( Ir_key_press_flag ) {

		Ir_key_press_flag=0;

		// wywo³anie w³asnej funkcji obs³ugi u¿ytkownika jeœli
		// uprzednio zosta³a ona zarejestrowana

		if(ir_event_callback) (*ir_event_callback)(address, command, key_time);


		address=0xff;
		command=0xff;

	}
}

No więc musimy napisać i zarejestrować własną funkcje do obsługi IR.

Więc w pliku main mam taką oto funkcję:

void snake_ir_keys(uint8_t adr,uint8_t cmd,uint8_t key_time){
	if (command == snakes(0)->keys[left]) snakes(0)->direction = left;
	else if (command == snakes(0)->keys[right]) snakes(0)->direction = right;
	else if (command == snakes(0)->keys[up]) snakes(0)->direction = up;
	else if(command == snakes(0)->keys[down]) snakes(0)->direction = down;
	//else if (command == KEY_OK) restart = 1;
}

Stała KEY_OK ma wartość 1. Ogólnie powinienem mieć 6 klawiszy, niestety mam zlutowany pilot RC5 tylko na 5. Pierwotnie command == 1 miał restartować grę, gdy wyświetli się ekran końcowy, gdy przegramy. Wtedy wciskamy restart, włącza nam się główny ekran i rusza gra. Zakomentowałem tą linie, bo pomyślałem ze może to robić jakiś konflikt, jeśli będzie sie zmieniała ta zmienna restart w nieodpowiednim momencie, jednak to nic nie daje.

register_ir_event_callback(snake_ir_keys);

w main zarejestrowałem funkcję.

do ekranów początkowych i końcowych również mam callbacki, taka możliwość, aby móc samemu tworzyć jakiś własny ekran.

register_start_screen_callback(display_init);
register_end_screen_callback(ekran_koncowy);

funkcje display_init i ekran_koncowy znajdują się w osobnym pliku ekrany.c

I w tym właśnie pliku próbuje użyć podczerwieni, a mi się to nie udaję. 

Pętla nieskończona w pliku main w sumie składa się tylko z tego:

while(1){
		IR_EVENT();
		if(!timer1){
			if(snakes(0)->draw_snake_fun)snakes(0)->draw_snake_fun(snakes(0));

			timer1=70;
		}

Wywołujemy zdarzenie IR_EVENT, które bada czy nie nadleciała jakaś ramka, w timerze wywołujemy poprzez wskaźnik funkcje do rysowania węża.

Link do komentarza
Share on other sites

Może byś odpowiedział na zadane pytania, zdaje się że to jest kluczowe. Co ci po dziesiątkach linii kodu jak z prostej pętli nie można wyjść? 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Callback mam włączony, przerwania też, podczas gry, kiedy wąż jest rysowany sterowanie działa, komendy przylatują. Po zakończeniu gry gdy przegram, command == 1 resetuje grę od początku. Więc takto działa ok, problem tylko ze nie przylatują żadne ramki gdy jestem w ekranie początkowym 

Link do komentarza
Share on other sites

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lcd.h"
#include "SNAKE/snake.h"
#include "IR_UNI/ir_config.h"
#include "uart.h"
#include "ekrany.h"

void snake_ir_keys(uint8_t adr,uint8_t cmd,uint8_t key_time);

volatile uint16_t timer1;
int main (){
	PORTD |= (1<<PD7);
	register_ir_event_callback(snake_ir_keys);
	check_and_load_defaults();
	USART_Init(__UBRR);
	ir_init();
	lcd_init();
	register_start_screen_callback(display_init);
	register_end_screen_callback(ekran_koncowy);
	snake_init(1);
	// konfiguracja timera//
	TCCR0 |= (1 << WGM01); // tryb ctc
	TCCR0 |= (1<< CS00)|(1<<CS02); // prescaler 1024
	OCR0 = 78;
	TIMSK |= (1 << OCIE0);



	sei();

 

Link do komentarza
Share on other sites

Tak jak myślałem 😉 zobacz w której linii jest Snake init a w której globalne zezwolenie na przerwania. Bo zakładam ze w "poczęciu" węża program wisi? 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

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ę »
×
×
  • 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.