Skocz do zawartości

Funkcja do obsługi klawiszy


Krawi92

Pomocna odpowiedź

Chciałem pobawić się dziś napisaniem funkcji do obsługi klawiszy, jednak chciałem sobie trochę skomplikować życie. Wykorzystałem typ strukturalny, stworzyłem tablice tych struktur i zacząłem pisać. 

W pliku .h deklaracja typu, wystawienie na zewnątrz zmiennych i funkcji.

typedef struct {
	volatile uint8_t *KPIN;
	uint8_t key_mask;
	uint8_t keylock;
	void (*kfun)(void);
}TBUTTON;

extern TBUTTON button[5];

void key_init(void);
void key_left (void);
void key_right (void);
void key_up (void);
void key_down (void);
void key_ok (void);
void key_press ( TBUTTON *btn[], uint8_t nr);

w pliku .c tworze zmienną tablicą, która ma przechowywać ustawienia kazdego przycisku, w inicjalizacji ustawiam pullupy i definiuje wartości zmiennych w strukturze.

TBUTTON button[5];

void key_init(void){
	PORTD |= (CUR_UP|CUR_DOWN|CUR_RIGHT|CUR_LEFT|KEY_OK);
	button[left].kfun = key_left;
	button[left].KPIN = &PIND;
	button[left].key_mask = CUR_LEFT;
	button[right].kfun = key_right;
	button[right].KPIN = &PIND;
	button[right].key_mask = CUR_RIGHT;
	button[up].kfun = key_up;
	button[up].KPIN = &PIND;
	button[up].key_mask = CUR_UP;
	button[down].kfun = key_down;
	button[down].KPIN = &PIND;
	button[down].key_mask = CUR_DOWN;
	button[ok].kfun = key_ok;
	button[ok].KPIN = &PIND;
	button[ok].key_mask = KEY_OK;
}

void key_left (void){
	snake_tab[0].direction=left;
}
void key_right (void){
	snake_tab[0].direction=right;
}
void key_up (void){
	snake_tab[0].direction=up;
}
void key_down (void){
	snake_tab[0].direction=down;
}
void key_ok (void){
	restart = 1;
}
void key_press ( TBUTTON * btn[], uint8_t nr){
	register uint8_t keypress = (*btn[nr]->KPIN & btn[nr]->key_mask);
	if (!btn[nr]->keylock && !keypress){
		btn[nr]->keylock = 1;
		if(btn[nr]->kfun)btn[nr]->kfun();
	}else if (btn[nr]->keylock && keypress)btn[nr]->keylock=0;
}

gdy w pliku main.c wywołuje funkcje

key_press(&button,right);

dostaje warring : ../main.c:45:14: warning: passing argument 1 of 'key_press' from incompatible pointer type [-Wincompatible-pointer-types]

../SNAKE/snake.h:79:6: note: expected 'TBUTTON ** {aka struct <anonymous> **}' but argument is of type 'TBUTTON (*)[5] {aka struct <anonymous> (*)[5]}'

Dodam tez, ze wykorzystuje tu typ wyliczeniowy 

enum {left,right,up,down,ok};		

Oczywiście obsługa nie działa, a ja nie wiem co tu jest niekompatybilne... Pomoże ktoś, gdzie robię błąd ? 

Link do komentarza
Share on other sites

8 minut temu, Krawi92 napisał:

Coś przekombinowałem z tą tablicą, bo gdy tworzę pojedynczą zmienną i przekazuję do niej tylko adres jest OK. 

To usun nawiasy kwadratowe...jak przekazujesz tablice to ma ich nie byc...to Ty masz wiedziec ile jest elementow tej tablicy zeby nie wyjsc poza jej obszar, dlatego czesto podaje sie wskaznik (nazwe tablicy) na jej pierwszy element i ilosc elementow tej tablicy..

int tab[5]
  
  funkcja(&tab, 5)
  
  void funkcja(int * tablica, byte x)
  for (int i=0; i < x; i++)
  tablica[i] = 10;
  
 

 

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

Coś mi się ciężko myśli 😄 Za długo już nad tym siedzę. Przerobiłem funkcje, zamiast tablicy zrobiłem 5 zmiennych i jest OK.

TBUTTON button1,button2,button3,button4,button5;

void key_init(void){
	PORTD |= (CUR_UP|CUR_DOWN|CUR_RIGHT|CUR_LEFT|KEY_OK);

	button1.kfun = key_left;
	button1.KPIN = &PIND;
	button1.key_mask = CUR_LEFT;
	button2.kfun = key_right;
	button2.KPIN = &PIND;
	button2.key_mask = CUR_RIGHT;
	button3.kfun = key_up;
	button3.KPIN = &PIND;
	button3.key_mask = CUR_UP;
	button4.kfun = key_down;
	button4.KPIN = &PIND;
	button4.key_mask = CUR_DOWN;
	button5.kfun = key_ok;
	button5.KPIN = &PIND;
	button5.key_mask = KEY_OK;
}

void key_press ( TBUTTON * btn){

	register uint8_t keypress = (*btn->KPIN & btn->key_mask);
	if (!btn->keylock && !keypress){
		btn->keylock = 1;
		if(btn->kfun)btn->kfun();
	}else if (btn->keylock && keypress)btn->keylock=0;
}

i w main.c odwołuje się

 

 

while(1){
		key_press(&button1);
		key_press(&button2);
		key_press(&button3);
		key_press(&button4);
		key_press(&button5);
		if(!timer1){
			if(snakes(0)->draw_snake_fun)snakes(0)->draw_snake_fun(snakes(0));

			
			timer1=snakes(0)->speed;
		}
	}
}

 

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

A wystarczylo wywalic nawias kwadratowy i upchac wszystko w for..😉 nie to zebym byl jakis znawca bo nie jestem, ale tablice to bardzo fajna rzecz i warto z nich korzystac w takich przypadkach chociazby jak u Ciebie, no ale nie jest to tez obowiazkowe...na pojedynczych zmiennych tez moze byc😉

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

(edytowany)

Ok, udało mi się w końcu to zrobić używając tablicy 😛

Tylko teraz nie rozumiem pewnej rzeczy. 

void key_press ( TBUTTON * btn, uint8_t nr){

	register uint8_t keypress = (*btn[nr].KPIN & btn[nr].key_mask);
	if (!btn[nr].keylock && !keypress){
		btn[nr].keylock = 1;
		if(btn[nr].kfun)btn[nr].kfun();
	}else if (btn[nr].keylock && keypress)btn[nr].keylock=0;
}

Argumentem funkcji jest wskaźnik na tablice. Jeżeli odwołujemy się przez wskaźnik uzywamy ->. Kiedy uzyłem strzałki dostałem error 

 error: invalid type argument of '->' (have 'TBUTTON {aka struct <anonymous>}') chociaż, gdy użyłem strzałki pola struktury się pokazały. Dopiero gdy użyłem kropki to wszystko się dobrze skompilowało.

Edytowano przez Krawi92
Link do komentarza
Share on other sites

A tak wogole jesli nie robisz jakiejs biblioteki czy czegos tam to ten wskaznik na tablice struktur wcale nie jest Ci potrzebny skoro ta tablica jest globalna...(ja wiem ze Ty o tym wiesz😉, tak tylko przypominam, bo czasem czlowiek sie rozpedzi i troszke przedobrzy..)

Link do komentarza
Share on other sites

Nie nie..wogole wywalasz wskaznikowy czy tablicowy argument z funkcji..ewentualnie podajesz tylko indeks dla tablicy, a w funkcji piszesz normalnie wszystko po kropce

  key_press(left)
  key_press(right)
  key_press(ok)


void key_press (uint8_t nr)
  stru[nr].cos;
  

Lub robisz petle for i za jednym wywolaniem funkcji sprawdzasz cala tablice struktur (zmiany stanow etc, wiadomo)

  • Pomogłeś! 1
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!

Gość
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.