Untitled
unknown
plain_text
5 months ago
15 kB
2
Indexable
#include <stdint.h> #include <targets/AT91SAM7.h> #include "lcd.h" #include <stddef.h> //lcd #define LCD_BACKLIGHT PIOB_SODR_P20 //Podswietlenie wyswietlacza //przyciski obslugi menu #define SW_1 PIOB_SODR_P24 //przycisk SW1 #define SW_2 PIOB_SODR_P25 // przycisk SW2 //joystick obslugi menu #define JOY_UP PIOA_SODR_P9 // zdefiniowanie portu odpowiadajacego za joystick skierowany w gore JOY_UP #define JOY_DOWN PIOA_SODR_P8 // zdefiniowanie portu odpowiadajacego za joystick skierowany w dol JOY_DOWN __attribute__ ((section(".fast"))) void delay(int n){ //procedura opoznienia volatile int i; for(i=3000*n;i>0;i--) { __asm__("nop"); } } //definicja typu menu typedef struct menu_struct menu_t; struct menu_struct { const char * name; menu_t * next; // Nastpny element menu_t * prev; // Poprzeni element menu_t * child; // Dziecko danego wskanika menu_t * parent; // Rodzic danego wskanika void( * menu_function)(void); // Program wykonywany przez element w menu }; //pozycje w menu menu_t menu_1, menu_2, menu_3, sub_menu_1_1, sub_menu_1_2, sub_menu_2_1, sub_menu_2_2, sub_menu_3_1, sub_menu_3_2; //programy w menu void przejdzDoMenu1(); //definicja struktur menu menu_t menu_1 = { "MENU 1", & menu_2, //nastepny element po menu1 NULL, //poprzedni element przed menu 1 & sub_menu_1_1, //dziecko menu1 NULL, //rodzic menu1 NULL //funkcja menu1 }; menu_t sub_menu_1_1 = { "PROGRAM 1", & sub_menu_1_2, //nastepny element sub menu1 NULL, //poprzedni element sub menu1 NULL, //dziecko sub_menu_1_1 & menu_1, //rodzic sub_menu_1_1 NULL //funkcja sub_menu_1_1 }; menu_t sub_menu_1_2 = { "PROGRAM 2", NULL, //nastepny element po sub menu_1_2 & sub_menu_1_1, // poprzedni element przed sub_menu_1_2 NULL, // dziecko sub_menu_1_2 & menu_1, //rodzic menu_1_2 NULL //funckja menu_1_2 }; menu_t menu_2 = { "MENU 2", & menu_3, //nastepny element menu_2 & menu_1, //poprzedni element menu_2 & sub_menu_2_1, //dziecko menu_2 NULL, //rodzic menu_2 NULL //funckja menu_2 } ; menu_t sub_menu_2_1 = { "PROGRAM 1", & sub_menu_2_2, //nastepny element sub_menu_2_1 NULL, //poprzedni element sub_menu_2_1 NULL, //dziecko sub_menu_2_1 & menu_2, //rodzic_sub_menu_2_1 NULL //funkcja_sub_menu_2_1 }; menu_t sub_menu_2_2 = { "PROGRAM 2", NULL, //nastepny element sub_menu_2_2 & sub_menu_2_1, //poprzedni element sub_menu_2_2 NULL, // dziecko sub_menu_2_2 & menu_2, // rodzic sub_menu_2_2 NULL //funkcja sub_menu_2_2 }; menu_t menu_3 = { "MENU 3", NULL, //nastepny element menu_3 & menu_2, //poprzedni element_menu_3 & sub_menu_3_1, //dziecko menu_3 NULL, //rodzic menu_3 NULL //funkcja_menu_3 }; menu_t sub_menu_3_1 = { "PROGRAM 1", & sub_menu_3_2, //nastepny element sub_menu_3_1 NULL , //poprzedni element sub_menu_3_1 NULL, //dziecko sub_menu_3_1 & menu_3, //rodzic sub_menu_3_1 NULL //funkcja sub_menu_3_1 }; menu_t sub_menu_3_2 = { "MENU 1", NULL, //nastepny element sub_menu_3_2 & sub_menu_3_1, //poprzedni element sub_menu_3_2 & sub_menu_1_1, //dziecko sub_menu_3_2 & menu_3, //rodzic sub_menu_3_2 przejdzDoMenu1 // program pozwalajacy na bezposrednie przejscie do elementu menu1 w menu glownym }; //logika menu menu_t * currentPointer = & menu_1; // Aktualny wskanik uint8_t menu_index=0; // Numer aktualnie wybranego elementu na danym poziomie uint8_t menu_poprzedni_index=0; // numer indeksu z ktorego przeszlismy uint8_t lcd_row_pos; // Numer pozycji menu na LCD uint8_t lcd_row_pos_level_1 = 0, lcd_row_pos_level_2 = 0, lcd_row_pos_level_3 = 0; // Numer pozycji menu na LCD dla niszych poziomw //ustawienia globalne int odlegloscElementowMenuOdGoryEkranu= 20; //elementy menu sa odsuniete od gornej krawedzi zeby zrobic miejsce na nazwe menu lub na imie i nazwisko int odlegloscElementowMenuOdSiebie = 20; //elementy menu sa odsuniete od siebie o wybrana odleglosc int odlegloscStrzalkiOdLewejKrawedziEkranu= 90;//ile pikseli bedzie zajmowala strzalka po lewej stronie menu int odlegloscElementowMenuOdLewejKrawedziEkranu = 10;//odleglosc elementu menu od lewej krawedzi to wielkosc strzalki + odleglosc elementu menu od strzalki int kolorTekstu = BLACK;//kolor tekstu dla wszystkich elementow menu int kolorTla = YELLOW; //kolor tla dla wszystkich elementow menu int kolorEkranu = GREEN; //kolor dla tla ekranu int kolorRamkiPrzycisku = YELLOW; // kolor dla ramki pod przyciskiem void rysujRamke(){ LCDSetLine(0, 0, 129, 0, kolorTekstu); LCDSetLine(0, 1, 129, 1, kolorTekstu); LCDSetLine(0, 2, 129, 2, kolorTekstu); LCDSetLine(0, 127, 129, 127, kolorTekstu); LCDSetLine(0, 128, 129, 128, kolorTekstu); LCDSetLine(0, 129, 129, 129, kolorTekstu); LCDSetLine(0, 0, 0, 129, kolorTekstu); LCDSetLine(1, 0, 1, 129, kolorTekstu); LCDSetLine(2, 0, 2, 129, kolorTekstu); LCDSetLine(127, 0, 127, 129, kolorTekstu); LCDSetLine(128, 0, 128, 129, kolorTekstu); LCDSetLine(129, 0, 129, 129, kolorTekstu); } //funkcja czyszczaca indeks wyswietlacza void wyczyscEkran(){ //LCDClearScreen(kolorEkranu);//funkcja biblioteczna czyszczaca ekran rysujProstokat(4,4,100,120,kolorEkranu);//funkcja czyszczaca wszystko oprocz ramki } void rysujProstokat(int x, int y, int h, int w, int cColor){ // loop counter int i; // Row address set (command 0x2B) WriteSpiCommand(PASET); WriteSpiData(x); // Column address set (command 0x2A) WriteSpiCommand(CASET); WriteSpiData(y); WriteSpiData(y + w); // Load data to RAM 12 bits per 1 pixel, writing 2 pixels in one iteration of a loop WriteSpiCommand(RAMWR); for (i = 0; i < ((w * h) / 2); i++) { WriteSpiData((cColor >> 4) & 0xFF); WriteSpiData(((cColor & 0xF) << 4) | ((cColor >> 8) & 0xF)); WriteSpiData(cColor & 0xFF); } } //funkcja wyswietlajaca pozycje menu na danym poziomie void wyswietlPozycjeMenu(){ menu_t * elementMenu = currentPointer; //zmienna na obecnie wybrany element menu //przesuniecie wskaznika do pierwszego elementu menu while(elementMenu->prev !=NULL){//przesuwamy sie w gore listy elementow menu az nie dotrzemy do pierwszego elementu elementMenu = elementMenu->prev; } int indeksRysowanegoElementu = 0; //pierwszy element menu ma 0 indeks while (elementMenu!= NULL) {//rysujemy elementy menu do czasu az istnieja kolejne elementy na liscie menu uint8_t pozycjaXobecnegoElementu = odlegloscElementowMenuOdGoryEkranu + odlegloscElementowMenuOdSiebie * indeksRysowanegoElementu;//obliczenie pozycji X rysowanego elementu na ekranie uint8_t pozycjaYobecnegoElementu = odlegloscElementowMenuOdLewejKrawedziEkranu;//obliczenie pozycji Y rysowanego elementu na ekranie int dlugoscTekstu = LCDPutStrAndReturnSize(elementMenu->name, pozycjaXobecnegoElementu, pozycjaYobecnegoElementu, MEDIUM, kolorTekstu, kolorRamkiPrzycisku);//wyswietlenie elementu menu na ekranie w celu obliczenia jego dlugosci int przesuniecieRamki = -2; rysujProstokat(pozycjaXobecnegoElementu - przesuniecieRamki, pozycjaYobecnegoElementu - przesuniecieRamki,12, dlugoscTekstu, kolorRamkiPrzycisku); LCDPutStr(elementMenu->name, pozycjaXobecnegoElementu, pozycjaYobecnegoElementu, MEDIUM, kolorTekstu, kolorRamkiPrzycisku); //wyswietlenie elementu menu na ekranie elementMenu = elementMenu->next;//przejscie do kolejnego elementu do narysowania indeksRysowanegoElementu++;//zwiekszenie indeksu rysowanego elementu } } void wyswietlStrzalkePrzyElemencieMenu(int x, int y, int color){ LCDSetLine(x, y+4, x+2, y, color); LCDSetLine(x + 4, y + 4, x+2, y, color); } //funkcja liczaca obecny indeks wybranego elementu, potrzebna w przypadku powrotu do elementu menu void obliczObecnyIndex(){ menu_t* obecnyElement = currentPointer; //wskaznik na obecny element while(obecnyElement->prev!=NULL){ //przesuniecie wskaznika do pierwszego elementu obecnego menu obecnyElement = obecnyElement->prev; } int index = 0; //indeks pierwszego elementu menu to 0 while (obecnyElement != currentPointer && obecnyElement!=NULL) { //do czasu az nie dotrzemy do wybranego elementu menu obecnyElement = obecnyElement->next; // przesuwamy sie do kolejnych elementow menu index++;//zwiekszamy zliczany indeks } menu_index = index;//ustawienie menu_index na wyliczony index elementu menu } //funkcja wyswietlajaca wskaznik menu przy obecnie wybranym elemencie menu void wyswietlWskaznikMenuPrzyObecnymIndeksie(){ int staraPozycjaStrzalki = odlegloscElementowMenuOdGoryEkranu + menu_poprzedni_index * odlegloscElementowMenuOdSiebie; //stara pozycja strzalki to pozycja poprzednio wybranego indeksu LCDPutStr(" ", staraPozycjaStrzalki, odlegloscStrzalkiOdLewejKrawedziEkranu, MEDIUM, kolorTekstu, kolorEkranu);//zamalowanie sama strzalka nie dzialalo poprawnie //wyswietlStrzalkePrzyElemencieMenu(staraPozycjaStrzalki, odlegloscStrzalkiOdLewejKrawedziEkranu, kolorEkranu); menu_poprzedni_index = menu_index;//zapisanie obecnego indeksu menu jako nowy poprzednio wybrany indeks int nowaPozycjaStrzalki = odlegloscElementowMenuOdGoryEkranu + menu_index * odlegloscElementowMenuOdSiebie;//nowa pozycja strzalki to obecnie wybrany element menu LCDPutStr("<", nowaPozycjaStrzalki, odlegloscStrzalkiOdLewejKrawedziEkranu, MEDIUM, kolorTekstu, kolorTla);//wyswietlenie strzalki na ekranie //wyswietlStrzalkePrzyElemencieMenu(nowaPozycjaStrzalki, odlegloscStrzalkiOdLewejKrawedziEkranu, kolorTekstu); } //funkcja rysujaca menu glowne void wyswietlMenuGlowne(){ wyczyscEkran(); // wyczyszczenie poprzedniego ekranu przed wyswietleniem LCDPutStr("Debek Anna", 5, 5, SMALL, kolorTekstu, kolorEkranu); // Wyswietlenie imienia i nazwiska na gorze wyswietlacza menu glownego przy uzyciu malej czcionki LCDPutStr("Lab sys wbudowanych", 100, 5, SMALL,kolorTekstu, kolorEkranu);// Wyswietlenie tekstu "Laboratorium systemow wbudowanych" na dole ekranu przy uzyciu malej czcionki wyswietlPozycjeMenu();//wyswietlenie kolejnych pozycji menu obliczObecnyIndex();//przesuniecie menu_index do obecnie wybranego elementu wyswietlWskaznikMenuPrzyObecnymIndeksie();//wyswietlenie wskaznika na ekranie na pozycji wskazanej przez menu_index } //funkcja rysujaca podmenu void wyswietlPodmenu(){ wyczyscEkran(); // wyczyszczenie starego ekranu przed wyswietleniem LCDPutStr(currentPointer->parent->name, 5, 5, MEDIUM, kolorTekstu, kolorTla); // wyswietlenie nazwy podmenu LCDPutStr("lab sys wbudowanych", 100, 5, SMALL,kolorTekstu, kolorEkranu);// Wyswietlenie tekstu "Laboratorium systemow wbudowanych" na dole ekranu przy uzyciu malej czcionki wyswietlPozycjeMenu();//wyswietlenie kolejnych pozycji menu obliczObecnyIndex();//przesuniecie menu_index do obecnie wybranego elementu wyswietlWskaznikMenuPrzyObecnymIndeksie();//wyswietlenie wskaznika na ekranie na pozycji wskazanej przez menu_index } //implementacja programow w menu void przejdzDoMenu1(){ currentPointer = &menu_1; //ustawienie wskaznika elementu menu na menu_1 wyswietlMenuGlowne(); //wyswietlenie menu glownego } //zapamietanie pozycji wskaznika przed wyjsciem z podmenu void zapamietajWskaznikWPodmenu(){ if(currentPointer == &menu_1){ lcd_row_pos_level_1 = menu_index; }else if(currentPointer == &menu_2){ lcd_row_pos_level_2 = menu_index; }else if(currentPointer == &menu_3){ lcd_row_pos_level_3 = menu_index; } } //przywrocenie pozycji wskaznika po wyjsciu z podmenu void przejdzDoPodmenuIPrzywrocWartoscWkaznika(){ uint8_t docelowaPozycja = 0; //przywracamy pozycje z ktorej wyszlismy wczesniej z podmenu do menu glownego if(currentPointer == &menu_1){ docelowaPozycja = lcd_row_pos_level_1; }else if(currentPointer == &menu_2){ docelowaPozycja = lcd_row_pos_level_2; }else if(currentPointer == &menu_3){ docelowaPozycja = lcd_row_pos_level_3; } //przenosimy wskaznik menu do menu podrzednego currentPointer = currentPointer->child; int i=0; while (i<docelowaPozycja && currentPointer->next!=NULL){ currentPointer = currentPointer->next; } } int main(){ //inicjalizacja rejestrow i ustawien wyswietlacza PMC_PCER=PMC_PCER_PIOB | PMC_PCER_PIOA;//wlaczenie urzadzenia we/wy PIOB i PIOA PIOB_OER=LCD_BACKLIGHT;//OUTPUT ENABLE PIOB_PER=LCD_BACKLIGHT | SW_1 | SW_2;//PIOB uruchomienie obslugi przyciskow SW_1, SW_2 oraz podswietlenia wyswietlacza LCD PIOA_PER= JOY_UP | JOY_DOWN;//PIOA uruchomienie obslugi JOY_UP i JOY_DOWN InitLCD(); //inicjalizacja LCD LCDSettings(); //ustawienie LCD wyczyscEkran();//wyczyszczenie ekranu wyswietlacza rysujRamke();//funckja rysujaca obramowanie menu na wyswietlaczu PIOB_SODR|=LCD_BACKLIGHT; //Wlaczenie podswietlenia wyswietlacza LCD wyswietlMenuGlowne(); //na poczatku, po uruchomieniu programu wyswietlane jest menu glowne //obsluga przyciskow, glowna petla programu while(1){ //joystick obsluga //gdy JOY_UP jest wcisniety if ((PIOA_PDSR & JOY_UP)==0){ //obsluga przesuniecia joysticka w gore, do wyboru elementu w menu if(currentPointer->prev!=NULL){//jesli istnieje element powyzej obecnego elementu to przesuwamy do niego obecny indeks menu currentPointer = currentPointer->prev; menu_index--; wyswietlWskaznikMenuPrzyObecnymIndeksie();//wyswietlamy na ekranie wskaznik przy wybranym elemencie menu } delay(200); } //gdy JOY_DOWN jest wcisniety if ((PIOA_PDSR & JOY_DOWN)==0){ //obsluga przesuniecia joysticka w dol do wyboru elementu w menu if(currentPointer->next != NULL){//jesli istnieje element ponizej obecnego elementu to przesuwamy do niego obecny indeks menu currentPointer = currentPointer->next; menu_index++; wyswietlWskaznikMenuPrzyObecnymIndeksie();//wyswietlamy na ekranie wskaznik przy wybranym elemencie menu } delay(200); } //przyciski obsluga //Obsluga przycisku sw1 do wykonywania programow zadeklarowanych w podmenu if ((PIOB_PDSR & SW_1)==0){ //gdy przycisk SW_1 jest wcisniety //obsluga do przejscia do programu w podmenu if(currentPointer->menu_function!=NULL){ currentPointer->menu_function(); // wykonanie funkcji programu w podmenu } delay(200); } //obsluga przycisku sw2, do przechodzenia do podmenu lub powrotu do menu glownego if ((PIOB_PDSR & SW_2)==0){ //gdy przycisk SW_2 jest wcisniety if(currentPointer->parent == NULL && currentPointer->child != NULL ){ //sprawdzenie czy jestesmy w menu glownym oraz czy istnieje podmenu //obsluga przejscia do podmenu //currentPointer = currentPointer->child; //wskaznik na podmenu znajduje sie w polu child obecnego elementu menu przejdzDoPodmenuIPrzywrocWartoscWkaznika(); //funkcja przechodzaca do podmenu i ustawiajaca wskaznik w zapamietanym ostatnio miejscu (lub na pierwszym miejscu jesli to pierwsze wejscie do podmenu) wyswietlPodmenu(); //wyswietlenie na ekranie menu podrzednego }else{ //obsluga powrotu do menu glownego zapamietajWskaznikWPodmenu(); // funkcja zapamietujaca pozycje wskaznika w podmenu currentPointer = currentPointer->parent; //wracamy do elementu menu glownego, ktory jest rodzicem obecnego elementu wyswietlMenuGlowne(); //wyswietlenie na ekranie menu glownego } delay(200); } } return 0; }
Editor is loading...
Leave a Comment