Untitled
unknown
plain_text
a year ago
16 kB
5
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 drawBorder(){
LCDSetLine(1, 1, 129, 1, kolorTekstu);
LCDSetLine(1, 2, 129, 2, kolorTekstu);
LCDSetLine(1, 3, 129, 3, kolorTekstu);
LCDSetLine(1, 129, 129, 129, kolorTekstu);
LCDSetLine(1, 128, 129, 128, kolorTekstu);
LCDSetLine(1, 127, 129, 127, kolorTekstu);
LCDSetLine(1, 1, 1, 129, kolorTekstu);
LCDSetLine(2, 1, 2, 129, kolorTekstu);
LCDSetLine(3, 1, 3, 129, kolorTekstu);
LCDSetLine(129, 1, 129, 129, kolorTekstu);
LCDSetLine(128, 1, 128, 129, kolorTekstu);
LCDSetLine(127, 1, 127, 129, kolorTekstu);
}
//funkcja czyszczaca indeks wyswietlacza
void wyczyscEkran(){
LCDClearScreen(kolorEkranu);//funkcja biblioteczna czyszczaca ekran
drawBorder();//funckja biblioteczna rysujaca obramowanie menu na wyswietlaczu
}
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
rysujProstokat(staraPozycjaStrzalki-2, odlegloscStrzalkiOdLewejKrawedziEkranu-10,14, 10, kolorEkranu);
//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
rysujProstokat(nowaPozycjaStrzalki-1, odlegloscStrzalkiOdLewejKrawedziEkranu,12, 10, kolorTekstu);
//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
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