Skocz do zawartości

Tworzenie prostego menu na lcd


Krawi92

Pomocna odpowiedź

18 minut temu, Krawi92 napisał:

a ktos odniesie sie do mojego wpisu odbiegajacego od tematu ?

🙂 jak chcesz pozbyć się tego switch case(który nie jest obciachem!) przeanalizuj przykład podany przez elvisa to jest właśnie wykorzystanie tablic i wskaźników i postaram się dokładniej opisać co zaszło:

tutaj @Elvis powołał nowy typ danych (coś jak char, int) który jest wskaźnikiem (adresem) na funkcję która nie pobiera parametrów i nie zwraca wartości

typedef void (*menu_func)(void);

następnie:

typedef struct {
    const char *text;
    menu_func func;
}menu_t;

@Elvis zrobił kolejny typ danych który zawiera wskaźnik(adres) tekstu który ma być wyświetlony oraz użył wcześniejszego menu_func któremu nadał nazwę func. Cały nowy typ ma nazwę menu_t 

teraz:

static const menu_t menu1[] = {
    { "RTC event(?)", RTC_Event },
    { "Ustaw date", display_menu2 },
    { "Ustaw czas", display_menu },
    { "Zapisz zmiany", zapisano_czas },
};

na typie menu_t zbudował tablicę nazw("RTC event","ustaw datę" itd) i funkcji które będą powiązane z tymi nazwami.

Niestety nie pokazał jak z tego skorzystać 😉 no ale zróbmy to:

musisz mieć jakiś licznik który będzie zliczał od pozycji zerowej do max twojej tablicy 

uint8_t idx_tab = 0;

dla uproszczenia sami wyliczymy maksymalny rozmiar (da się to zrobić automatycznie ale to nie na teraz) 

#define MAXMENU 4

no i program główny - jak z tego skorzystać (pseudo kod)

if(btn == LOW){
	if(++idx_tab < MAXMENU)
	lcd_str(menu1[idx_tab].text); // tu wyświetlasz przypisany tekst
		if(menu1[idx_tab].func){; // tu sprawdzasz czy pod func jest coś przypisane, 
			func[idx_tab];		  //jeśli tak to wykonaj tę akcję
		}
	else idx_tab = 0;
}

Żeby dokładniej to wyjaśnić potrzebowałbym nieco więcej czasu. Ale na szczęście są osoby które to już przepracowały 

 

 

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 ma co się tych wskaźników wystraszać, nie potrzebujemy ich zbyt wiele - na pewno mniej niż w przypadku list. Wystarczy znać i trochę rozumieć jak działają napisy w C, czyli printf("Hello World!\n"). Wskaźniki do funkcji są nieco trudniejsze, ale wystarczy je traktować jak wywołanie samej funkcji, bez wnikania w szczegóły.

A jak chodzi o materiały dydaktyczne, to polecałbym bardziej profesjonalne źródła.

Link do komentarza
Share on other sites

Właśnie w pierwszej książkę Kardasia wskaźniki są wytłumaczone w czw teoretycznej tak prosto. Jak wygląda zapis, kiedy gwiazdka kiedy nie. Przykład kodu na przykładach 2 zmiennych i prostych operacjach wsk+3 i *wsk+1 np: i jaka wartość jest zmiennej a i b. I to jest proste, ale później w kodzie są gotowe przykłady już w funkcjach itp gdzie już tak nie wszystko do końca jest jasne, a im dalej tym trudniej. I ciężko mi potem analizować jakiś kod nie rozumiejąc do końca wszystkiego. Dlatego zastanawiam się gdzie mógłbym tak dobrze doczytać o posługiwaniu się wskaźnikami. 

Link do komentarza
Share on other sites

Więc zamiast tego spróbuj je przećwiczyć. Powiedzmy że masz za zadanie zrobić pięć funkcji które nie pobierają ani nie zwracają żadnej wartości. Zbuduj tablicę wskaźników na te funkcje. Jak byś to zrobił?

Link do komentarza
Share on other sites

Ja uczyłem się C tak dawno, że raczej ciężko będzie mi polecić cokolwiek poza klasycznym "Język ANSI C" https://helion.pl/ksiazki/jezyk-ansi-c-programowanie-wydanie-ii-brian-w-kernighan-dennis-m-ritchie,jansiv.htm#format/d Jak chodzi o podlinkowany wcześniej materiał to widziałem kilka prezentacji tej firmy i było w nich mnóstwo nieścisłości i błędów. Dlatego zachęcam do sięgania po bardziej wiarygodne źródła.

Akurat wskaźniki są raczej prostym tematem, jeśli coś wydaje się niejasne, może warto założyć temat na forum, na pewno wielu uczestników będzie mogło pomóc.

Link do komentarza
Share on other sites

1 minutę temu, Krawi92 napisał:

jutro Ci odpowiem bo chyba pamiętam jak się deklarowało wskaźnik na funkcje void 🤔🙃

Nie żebym nie pokazywał 😉 faktem jest że w C te deklaracje są mocno popierniczone delikatnie mówiąc. Nie dziwię się że sprawiają tyle trudności. 

Link do komentarza
Share on other sites

Znalazłem chwilę, na napisanie odrobiny kodu, mogę więc opisać nieco dokładniej o co chodziło z tym bardzo prostym menu. Od razu wyjaśnienie - to nie jest mega ambitne, uniwersalne, niezawodne, itd., itp. rozwiązanie. To tylko przykład jak można prosto rozwiązać problem, a później w miarę potrzeby dodawać potrzebne opcje.

Na początek przyda się jakaś platforma testowa. Potrzebne będzie wyświetlacz, jakieś przyciski i pewnie mikrokontroler. Wybrałem Arduino tym bardziej, że w szufladzie czekała całkiem ciekawa płytka MKR IoT Carrier Board i ciągle brakowało czasu żeby ją podłączyć:

2021-12-27-120017_2558x1398_scrot.thumb.png.4b3e8e0a8dfcbbe6e82b8a8e980c28fa.png

Na początek warto spróbować wyświetlić samo menu. Do tego napisałem bardzo prostą funkcję:

void draw_menu(const menu_t *menu, int menu_size)
{
    int i;

    mkr_iot.display.fillScreen(ST77XX_BLACK);
    mkr_iot.display.setTextSize(2);
    mkr_iot.display.setTextColor(ST77XX_YELLOW);

    for (i = 0; i < menu_size; i++) {
        mkr_iot.display.setCursor(32, 60 + i * 24);
        mkr_iot.display.println(menu[i].text);
    }
}

Kodu chyba nie trzeba wyjaśniać. Funkcja otrzymuje dwa parametry, pierwszy to tablica z pozycjami menu, drugi to liczba pozycji do wyświetlenia. Po uruchomieniu efekt jest następujący:

PXL_20211227_105353161.thumb.jpg.68cba412829407ec3297ebcb3a8e29e9.jpg

Na wszelki wypadek jeszcze cały kod:

#include <Arduino_MKRIoTCarrier.h>

MKRIoTCarrier mkr_iot;

typedef void (*menu_func)(void);

typedef struct {
    const char *text;
    menu_func func;
}menu_t;

void draw_menu(const menu_t *menu, int menu_size)
{
    int i;

    mkr_iot.display.fillScreen(ST77XX_BLACK);
    mkr_iot.display.setTextSize(2);
    mkr_iot.display.setTextColor(ST77XX_YELLOW);

    for (i = 0; i < menu_size; i++) {
        mkr_iot.display.setCursor(32, 60 + i * 24);
        mkr_iot.display.println(menu[i].text);
    }
}

static void RTC_Event(void)
{
}

static void display_menu2(void)
{
}

static void display_menu(void)
{
}

static void zapisano_czas(void)
{
}

static const menu_t menu1[] = {
    { "RTC event(?)", RTC_Event },
    { "Ustaw date", display_menu2 },
    { "Ustaw czas", display_menu },
    { "Zapisz zmiany", zapisano_czas },
};

void setup()
{
    mkr_iot.begin();
    draw_menu(menu1, 4);
}

void loop()
{
}

 

  • 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!

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.