Untitled

 avatar
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