logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA32][C] klawiszologia cztery poziomy menu na LCD

margas4542 05 Paź 2010 22:12 2704 17
REKLAMA
  • #1 8588015
    margas4542
    Poziom 16  
    Witam..mam kłopot z obsługą a właściwie ze zdefiniowaniem obsługi klawiszy w menu na LCD i szczerze mówiąc nie wiem jak to zrobić...w poszczególne sekcje potrafię wejść i wyjść ale w danym poziomie nie umiem zdefiniować obsługi klawiszy i wykonać określonych czynności...sugestie jak to "ugryść' mile widziane a może da się to zrobić prościej niż ja wymyśliłem....
    
    //----- MENU LCD cztery wiersze po 20 znaków 
      unsigned char key;
      for(key=4; key<8; key++)   
      if(!(PIND & _BV(key)))
      {
       switch(key)
       {
       case 4://przełączenie do menu ustawień czasu i daty zegara
        LCD_GoTo(0,0);
        LCD_WriteText("                                         ");//czysczenie LCD
        LCD_GoTo(0,1);
        LCD_WriteText("                                         ");
        while(1)
        {
         LCD_GoTo(0,0);   LCD_WriteText("USTAW CZAS");
         LCD_GoTo(10,1);  LCD_WriteText("18:00");//ustaw czas
         LCD_GoTo(20,0);   LCD_WriteText("USTAW DATE");
         LCD_GoTo(30,1);  LCD_WriteText("10/10.10");//ustaw date
         {
     	  if(!(PIND & _BV(7)))
    	  {
    	   goto exit;
    	   }
    	  }
         }
       break;
       case 5://przełączenie do menu nastaw zegara sterującego
        LCD_GoTo(0,0);
        LCD_WriteText("                                         ");//czyszczenie LCD
        LCD_GoTo(0,1);
        LCD_WriteText("                                         ");
        while(1)
        {
         LCD_GoTo(0,0);   LCD_WriteText("K-1");
         LCD_GoTo(6,0);   LCD_WriteText("01:00");//ustaw czas k-1 wł  poniedziałek-piątk
         LCD_GoTo(13,0);  LCD_WriteText("11:00");//ustaw czas k-1 wył 
         LCD_GoTo(0,1);   LCD_WriteText("K-2");
         LCD_GoTo(6,1);   LCD_WriteText("02:00");//ustaw czas k-2 wł
         LCD_GoTo(13,1);  LCD_WriteText("12:00");//ustaw czas k-2 wył
         LCD_GoTo(20,0);  LCD_WriteText("K-3");
         LCD_GoTo(26,0);  LCD_WriteText("03:00");//ustaw czas k-1 wł sob,niedziela
         LCD_GoTo(33,0);  LCD_WriteText("13:00");//ustaw czas k-1 wył
         LCD_GoTo(20,1);  LCD_WriteText("K-4");
         LCD_GoTo(26,1);  LCD_WriteText("04:00");//ustaw czas k-2 wł
         LCD_GoTo(33,1);  LCD_WriteText("14:00");//ustaw czas k-2 wył
         {
    	  if(!(PIND & _BV(7)))
    	  {
    	   goto exit;
    	  }
    	 }
        }	
       break;
       case 6://przełączenie do menu sterowania kanałami 1-2-3-4 (230V) PORTC piny 8,7,6,5
       //wybór oraz załączenie lub wyłączenie danego kanału
       //dostępne klawisze PIND 6,5,4
        LCD_GoTo(0,0);
        LCD_WriteText("                                         ");//czyszczenie LCD
        LCD_GoTo(0,1);
        LCD_WriteText("                                         ");
        LCD_GoTo(0,0);   LCD_WriteText("OBW-1");
        LCD_GoTo(0,1);   LCD_WriteText("OBW-2");
        LCD_GoTo(20,0);  LCD_WriteText("OBW-3");
    	LCD_GoTo(20,1);  LCD_WriteText("OBW-4");
        while(1)
        {
    	 int set;
    	 char *k="  ";
    	 char k1="wlaczony";
    	 char k2="wylaczony";
    	 if(!(PIND & _BV(4)))
    	 {
    	  set=(set+1);
    	 }
    	 if(!(PIND & _BV(5))
    	 {
          set=(set-1)
    	 }
          if(set=1)
    
    //     LCD_GoTo(11,1);  LCD_WriteText("zalaczony");	//obwód nr1 230V
    //     LCD_GoTo(11,1);  LCD_WriteText("zalaczony");	//obwód nr2 230V
    //     LCD_GoTo(31,0);  LCD_WriteText("zalaczony");	//obwód nr3 230V
    //     LCD_GoTo(31,1);  LCD_WriteText("załączony");	//obwód nr4 230V
           set=0
           if(!(PIND & _BV(7)))//jeżeli naciśnięty to wyjście z petli
    	   {
    	    goto exit;
    	   }
          }
    	  }
        break;
       case 7://podświetlenie LCD
             PORTB ^=_BV(0);	//podświetlenie LCD PORTB pin 1
             _delay_ms(200);
        break;
        {}exit:
        default:
        LCD_GoTo(0,0);
        LCD_WriteText("                                         ");
        LCD_GoTo(0,1);
        LCD_WriteText("                                         ");
    	break;
       }
      }
    
  • REKLAMA
  • #2 8588096
    mieczotronix
    Poziom 16  
    w "if(set=1)" - powinno być " =="
    zamiast goto exit; można napisać "break;"

    a co do menu to przy bardziej rozbudowanych trzeba zrobić na listach

    ja znalazłem na AVRFREAKS fajne menu
    chyba "simplemenu" bodajże się nazywało

    więc będziesz musiał co nieco poćwiczyć wskaźniki do struktur i takietam.
  • #3 8588155
    margas4542
    Poziom 16  
    Witam.....ten kod nie jest kompletny to raczej robocza wersja więc błędy będą bo kombinowałem z kodem ale nie wyszło....goto exit jest po to by wyjść z pętli while
  • REKLAMA
  • #4 8588175
    tadzik85
    Poziom 38  
    W jednym z tematów poruszyłem ten temat. Proponuje dorwać oprogramowanie do butterfly atmela, tak jest ładnie zrobione menu.
  • #6 8588852
    tadzik85
    Poziom 38  
    Poza tym to nie jest 4 poziomowe menu a z 4 opcjami. Takie coś można znacznie prościej zrealizować. Zamknij obsługę każdego menu w odpowiedniej funkcji. Wybór funkcji możesz zrealizować nawet na ifach czy tez switchu, przy tylu opcjach nie wyjdzie ci za wielki kod.
  • #7 8588888
    margas4542
    Poziom 16  
    Ok..jak zwał tak zwał ale faktycznie to bardziej menu z czterema opcjami ale...do avrfreaks nie mam dostępu a po drugie angielski nie jest moją mocną stroną...po trzecie same sugestie że można to zrobić prościej nie przybliżają do poprawy mojego kodu bo ja nie jestem specem od programowania a na tym forum są ludzie którzy takie "coś' piszą pomiędzy dwoma łykami kawy...pytam na tym forum albowiem menu będzie powiązane z zegarem czasu bieżącego PCF 8583 i pamięcią 24C04 po I2C oraz dwukanałowym zegarem sterującym do napisania kodu którego się przymierzam a czuję że w tym przypadku bez pomocy forumowiczów utknę w miejscu.....pozdrawiam
  • #8 8588901
    tadzik85
    Poziom 38  
    Więc może najpierw podaj więcej danych, ilość klawiszy jak podłączone (czy matrycowo). Który przycisk do czego ma służyć.
  • #9 8590370
    margas4542
    Poziom 16  
    Witam..mam pięć klawiszy podłączonych kolejno do PORTD piny 7,6,5,4 oraz jeden PORTA pin 7 który ma służyć zarówno do włączania podświetlenia LCD jak i po wejściu do menu jako znacznik wyjścia z menu komendą goto exit;...pozostałe klawisze w zależności od strony menu 1,2,3,4 mają mieć funkcje;
    wejście do menu klawisz 1;
    ------------------------------------------------------
    menu1-ustawianie czasu i daty zegara
    klawisz 1-ustaw godziny
    klawisz 2-ustaw minuty
    klawisz 3-ustaw miesiąc
    klawisz 4-ustaw dzień
    wyświetlanie sekund nie są mi potrzebne
    rok wyświetlany jako stała na LCD
    -------------------------------------------------------
    menu2-nastawy czasu włącz/wyłącz zegara sterującego
    klawisz 1-ustaw godziny włączenia kanału 1 od poniedziałku do piątku
    klawisz 2-ustaw minuty włączenia kanału 1 od poniedziałku do piątku
    klawisz 3-ustaw godziny wyłączenia kanału 1 dla soboty i niedzieli
    klawisz 4-ustaw godziny wyłączenia kanału 1 dla soboty i niedzieli
    -------------------------------------------------------
    menu3-nastawy czasu włącz/wyłącz zegara sterującego
    klawisz 1-ustaw godziny włączenia kanału 2 od poniedziałku do piątku
    klawisz 2-ustaw minuty włączenia kanału 2 od poniedziałku do piątku
    klawisz 3-ustaw godziny wyłączenia kanału 2 dla soboty i niedzieli
    klawisz 4-ustaw godziny wyłączenia kanału 2 dla soboty i niedzieli
    -------------------------------------------------------
    menu4-ręczne włączanie/wyłączanie czterech obwodów '"sieciowych"
    klawisz 1-włącz lub wyłącz obwód 1
    klawisz 2-włącz lub wyłącz obwód 2
    klawisz 3-włącz lub wyłącz obwód 3
    klawisz 4-włącz lub wyłącz obwód 4
    --------------------------------------------------------
    Co do nastaw zegara sterującego to zakładam zrobienie tablicy do której zostaną wpisane wprowadzone klawiszami dane[godziny][minuty]. Dane z tablicy będą porównywane z aktualnym czasem podawanym z PCF8583P i w przypadku zgodności wykonane załączenie lub wyłączenie danego kanału.
  • REKLAMA
  • #10 8590454
    tadzik85
    Poziom 38  
    W jaki sposób chcesz wybierać menu?

    Obsługę każdego menu zrób w pętli while(klawisz wyjścia)

    start

    pętla główna:

    wybór menu

    if (menu ==1)
    do
    {
    }while(klawisz == wyjscie);
    ....
    elseif(menu==2)
    do
    {
    }while(klawisz == wyjscie);

    koniec pętli
  • #11 8590891
    margas4542
    Poziom 16  
    Oh..trochę niefortunnie napisałem poprzedni post...klawiszami od 1 do 3 wchodzę od razu do konkretnego panelu ustawień..
    klawisz cztery będzie potrzeby już w obsłudze ustawień w danym panelu
    klawisz pięć [wygospodarowany port] podświetlenie LCD i w ustawieniach danego panelu jako wyjście z panelu...
    menu1-ustawianie czasu i daty zegara
    menu2-nastawy czasu włącz/wyłącz zegara sterującego
    menu3-ręczne włączanie/wyłączanie czterech obwodów '"sieciowych"
    zmieniłem nieco menu 2 i na LCD wygląda tak
    K-1 00:00 00:00 //czas 1 załącz czas 2 wyłącz od pon do piątku
    K-1 00:00 00:00 //czas 1 załącz czas 2 wyłącz sobota niedziela
    K-2 00:00 00:00 //czas 1 załącz czas 2 wyłącz od pon do piątku
    K-2 00:00 00:00 //czas 1 załącz czas 2 wyłącz sobota niedziela
  • #12 8591101
    tadzik85
    Poziom 38  
    Więc to co ci zaproponowałem nadaje się doskonale, pozostaje kwestia szczegółów.
  • #13 8592843
    margas4542
    Poziom 16  
    No właśnie w tych szczegółach pies pogrzebany bo listing z pierwszego postu niej więcej tak jest skonstruowany ale jest kilka pomniejszych problemów z przykładową tablicą w której zakładałem zapis danych dotyczących nastawy czasu zegara czasu i daty czyli godziny i minuty plus dzień i miesiąc to cztery dane -> nastaw czasu zegara sterującego zał/wył dla kanał 1 i kanału 2 czyli godziny i minuty razy 8 ->oraz stany wyjść obwodów "sieciowych" to cztery dane.....teraz jak "przepisać" te lokalne dane z pętli podprogramu do programu głównego oby można było wykorzystać dane z tablicy do porównania z czasem zegara...
  • #14 8592973
    tadzik85
    Poziom 38  
    Menu jest twoją pętlą główna. Załączanie urządzeń proponuje zrobić w przerwaniu z zegarka RTC zgłaszanym co czas od sekundy do minuty a w nim porównanie wartości bieżącej z zadaną dla danego kanału. Proponuję byś obsługę klawiszy również zrealizował na przerwaniach. Ułatwi co to trochę główny algorytm.
  • #15 8593030
    margas4542
    Poziom 16  
    Przerwania...to dla mnie nie taka prosta sprawa...właśnie usiłuje najpierw napisać obsługę zegarka a ze względu na fakt że zabawę z Atmęgą zacząłem niedawno moja wiedza o C jest jeszcze uboga...zegar i cała reszta jest częścią napisanego już i działającego programu zarządzającego systemem monitorowania solara oraz akumulatora z automatycznym pomiarem napięć źródeł napięcia [solar lub prostownik] automatycznie ładującym aku oraz prądu ładowania i poboru przez odbiorniki 12V...
  • REKLAMA
  • #16 8593096
    gaskoin
    Poziom 38  
    Przerwania w skrócie można wyjaśnić tak:

    uC costam sobie robi i liczy, dostaje jakieś przerwanie (które wcześniej trzeba uruchomić, skonfigurować), przestaje liczyć i zajmuje się przerwaniem. Po jego skończeniu wraca do momentu w którym przestał liczyć i liczy dalej.

    W kodzie wygląda to tak:

    
    ISR(nazwa_wektora_przerwania){
    //obsluga przerwania
    }
    
    main(){
    konfiguracja_jakiegos_przerwania(); //np od przepelnienia timera
    
    while(1){
    //program
    }
    }
    


    wówczas jak timer się przepełni to procesor przechodzi do wykonania funkcji ISR, po skończeniu jej wykonywania, wraca do whila, do miejsca gdzie skończył.

    Datasheet + manual do avrlibc to dwie najlepsze lektury, ale słabo znasz angielski, a po polsku ciężko znaleźć dobrą literaturę do czegokolwiek.
  • #17 8596175
    margas4542
    Poziom 16  
    Witam...nic z tego nie wyszło rozwaliłem tyko w mak resztę programu....za chiny nie wiem jak obsłużyć tego PCF8583 datashety tylko namierzały mi w głowie a jakiegoś prostego przykładowego kodu w C nie znalazłem....menu jak się sypało tak sypie się dalej...nie radze sobie z tymi przerwaniami wychodzą cuda...

    posiłkując się elektrodą o dadatshetem napisałem coś takiego ale ciągle się pluje o zbyt wiele argumentów w TWI_read TWI_write....słowem już nic z tego nie rozumiem....
    
    //-----define PCF8583 linia A0 połączone z Vcc
    #define zegar 0xA0
    
    int przerwanie=0;
    void INT1_init(void)
    {
     MCUCR = 0x01;     
     GICR = 0x40;   
    }
    ISR(INT1_vect)   
    {
     przerwanie=1;
    } 
    //***** MAIN
    int main()
    {
     DDRA=0xC0;	//znacznik PA6 do wykorzystania
     PORTA=0x80;//pul-up klawisza podświetlenia LCD
     DDRB=0x01;	//podświetlenie LCD (reszta pinów 4 bity,RS,RW,E pod LCD)
     DDRC=0xFC;	//wyjścia sterujące oraz wejścia SCL SDA układu PCF8583 oraz 24C04
     PORTC=0x00;//bez pull-up SCL SDA układu PCF8583 oraz 24C04 rezystory do +5V są
     DDRD=0x00;	//wejścia klawiatura oraz INT1 układu PCF8583
     PORTD=0xF8;//pull-up klawiatura oraz INT1 układu PCF8583
    //----- LCD init
     LCD_Initalize();
     _delay_ms(200);
    //----- ADC init
     ADMUX = _BV(REFS0)|_BV(REFS1)|_BV(ADLAR);
     ADCSRA = _BV(ADEN)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2);
    //----- TWI init
     INT1_init();
     sei();
     while(1)
     {
    //--------------------------zegar 
     TWI_start();
     TWI_write(zegar,0x00); //ustawienie początkowe zegara pcf8583 (zerowanie)
     for(;;)
     {
      if (przerwanie==1)
      {
       volatile unsigned char czas[4]={0,}; //zerowanie wszystkich elementów tablicy
       unsigned char PCF_time=0;
       unsigned char buf2;
       unsigned char buf3;
       unsigned char buf4;
       unsigned char buf5;
    
       PCF_time=TWI_read(zegar,0x04);
       czas[0]=(PCF_time & 0x30) >> 4;	//dziesiatki_godzin         
       czas[1]=PCF_time & 0x0F;			//jednostki godzin
       PCF_time=TWI_read(zegar,0x03);
       czas[2]=PCF_time >> 4;			//dziesatki_minut
       czas[3]=PCF_time & 0x0F;			//jednostki minut
       PCF_time =TWI_read(zegar,0x02); 
       //sekundy są mi zbędne
       buf2= (czas[0]+0x30);
       buf3= (czas[1]+0x30);   
       buf4= (czas[2]+0x30);   
       buf5= (czas[3]+0x30);
       przerwanie=0;
      }
  • #18 8599304
    margas4542
    Poziom 16  
    W związku z brakiem odpowiedzi zamykam post.Dziękuje wszystkim.
REKLAMA