Arkadaşlar yarı kod yarı algoritma olabilir maksat öğrenmek olduğu için fikirlerinizi yazarmısınız.
Örnek bu menü üzerinden yardımcı olursanız sevinirim.
2x16 LCD veya Herhangi bir LCD için Menü Yapım Algoritma mantığını kavramak.
Değişkenler A,B,C,D,E,F,G
AYARLAR
-SICAKLIK // A Değişkenini Arttır /Azalt
-PARLAKLIK // B Değişkenini Arttır /Azalt
-MESAFA // C Değişkenini Arttır /Azalt
-UZUNLUK // D Değişkenini Arttır /Azalt
a rolesi neye göre çalışsın= sıcaklık, nem, basınç
sıcaklık seçtiysen= alt limit gir üst limit gir.
enter
b rolesi neye göre çalışsın= sıcaklık, nem, basınç
sıcaklık seçtiysen= alt limit gir üst limit gir.
-------------------------------------------------------
1. analog çıkış neye göre çalışsın= sıcaklık, nem, basınç
sıcaklık seçtim
1. analog çıkış ne olsun = +-10v, +-5v, 0-1v, 0-5v, 0-10v, 0-20mA, 0-24mA, 4-20mA
4-20mA seçtin =
4ma kaç derece olsun = -20
20ma kaç derece olsun = +60
bizimkiler böyle çalışıyor
İşaretçiler konusuna hakimsen, menü kodları ile hiç oynamadan, istediğin kadar menü-alt menü oluşturabileceğin algoritma oluşturmana yardımcı olabilirim.
Fakat işaretçiler konusunu az biraz biliyor olmak yetmez. Hakim olman gerek.
Alıntı yapılan: Klein - 25 Ocak 2017, 20:12:31
İşaretçiler konusuna hakimsen, menü kodları ile hiç oynamadan, istediğin kadar menü-alt menü oluşturabileceğin algoritma oluşturmana yardımcı olabilirim.
Fakat işaretçiler konusunu az biraz biliyor olmak yetmez. Hakim olman gerek.
Hocam müsait bir zamanınızda anlatmak isterseniz meraklısı da bulunur. :)
Tek tip veri tipimiz ve tek tip editörümüz olduğunu, alt menülerimiz olmadığını varsayarak. Basit bir algoritmayı hemen tasarlayabiliriz.
Öncelikle bir menünün temel elemanlarına bakalım.
1- Menü başlığı
2- Menüye bağlı değişken.
int tipinde a, b, c, d, e ve f, değişkenlerinin değerlerini menüye girip ayarlamak isteyelim.
O zaman yapımızı oluşturalım.
typedef struct{
char *Header;
int * Var;
}TMenuItem;
Header işaretçisi ekrana basmak istediğimiz menü başlığı.
Var işaretçisi ise değiştirmek istediğimiz değişkenin adresine işaret eder.
Burada doğrudan değer yerine işaretçi kullandık. Çünkü menüde yeni değere onay verdiğimizde sonucun hangi değişkene atılacağını bilmek istiyoruz.
Şimdi menü elemanlarımızın olduğu bir dizi yapalım.
const TMenuItem MainMenu[]= {
{"Sıcaklık", &a"},
{"Nem", &b},
{"Basınc", &c"},
...
...
0
}
Bu menüye istediğiniz kadar item ekleyebilirsiniz.
Sondaki 0. dizinin sonuna geldiğimizi anlamamızı sağlayacak.
void menu(void)
{
TMenuItem *Item = MainMenu;
// aşağı tuşuna basınca
if(Item != MainMenu) Item--// dizi başlangıcı olup olmadığını kontrol et. Değilse azalt
// yukarı yuşuna basınca
if(Item != 0) Item++// dizi sonu olup olmadığını kontrol et. Değilse artır
Yazdır(Item->Header); // Itemimiz her değiştiğinde ekrana yeni Itemin başlığını yazdır.
// enter tuşuna basınca
MenuEdit(Item); // editöre gir. Aktif Itemi parametre olarak geç.
}
Editörümüz
void MenuEdit(TMenuItem *Item)
{
int temp = Item->Var; // Itemimizin değişkeninin değerini geçici değişkene al.
Yazdır(Item->Header); // Item başlığını yazdır.
// aşağı yukarı tuşları ile Temp değişkeninin değerini artır ya da azalt.
// Esc basılmış ise çık return;
// Enter basılmış ise
Item->Var = Temp; // Temp değişkeninin içeriğini, Itemimizin gösterdiği adrese yaz.
}
Tek menü yerine birden fazla menü varsa, O zaman menü fonksiyonumuz hangi menü dizisi üzerinde çalışacağımızı gösterir parametre eklememiz gerekecek.
Yeni bir menü dizisi ekleyelim.
const TMenuItem OrtamMenu[]= {
{"Sıcaklık", &a"},
{"Nem", &b},
{"Basınc", &c"},
...
...
0
}
const TMenuItem ElektrikMenu[]= {
{"Akım", &d"},
{"Gerilim", &e},
{"Direnç", &f"},
...
...
0
}
Menü kodumuzu biraz değiştirip parametrik hale getiriyoruz.
void menu(TMenuItem *Item)
{
// TMenuItem *Item = MainMenu; Artık Item işaretçimiz fonksiyonun parametresi olduğu için buna ihtiyaç yok.
// aşağı tuşuna basınca
if(Item != MainMenu) Item--// dizi başlangıcı olup olmadığını kontrol et. Değilse azalt
// yukarı yuşuna basınca
if(Item != 0) Item++// dizi sonu olup olmadığını kontrol et. Değilse artır
Yazdır(Item->Header); // Itemimiz her değiştiğinde ekrana yeni Itemin başlığını yazdır.
// enter tuşuna basınca
MenuEdit(Item); // editöre gir. Aktif Itemi parametre olarak geç.
}
Çağırırken
Menu(OrtamMenu);
Menu(ElektrikMEnu);
Şimdi menümüzü biraz daha geliştirip mex ve min değer kontrolü ekleyelim.
TMenuItem yapımız ve TMenuItem tipi dizilerimiz aşağıdaki şekilde değişecek
TMenuItem tipimize min ve max üyeleri eklendi.
typedef struct{
char *Header;
int * Var;
int min;
int max;
}TMenuItem;
Menü dizilerimiz ise şu şekilde oldu
const TMenuItem OrtamMenu[]= {
{"Sıcaklık", &a , 10, 100"},
{"Nem", &b, 45, 70},
{"Basınc", &c , 100, 2000"},
...
...
0
}
const TMenuItem ElektrikMenu[]= {
{"Akım", &d, 0, 10},
{"Gerilim", &e, 12, 24},
{"Direnç", &f, 1000, 10000},
...
...
0
}
Editör içerisinde min ve max değerlerin kontrolünü nasıl yapacağınızı bildiğinizi varsayarak o kısmı atlıyorum.
Brada syntax kontrolü yapamıyorum. Ayrıca CCS'te işler nasıl yürür bilmiyorum. Bunların kontrolünü siz yapıp hatalar varsa kendiniz düzeltmelisiniz.
Her şey işaretçiler ve diziler üzerinden yürüdüğü için, bu hataları düzeltmek için işaretçi bilgisine sahip olmanız gerekir.
Menümüzü biraz daha geliştirip 2. dil opsiyonu ekleyelim.
iki dil için iki tane char tipi işaretçiden oluşan bir yapı ile başlayalım.
typedef struct{
char *Str[2];
}TLangStr;
MenuItem yapımız da şu şekilde değişti.
typedef struct{
TLangStr *Header;
int * Var;
int min;
int max;
}TMenuItem;
Menü dizilerimiz ise şu şekilde
const TMenuItem OrtamMenu[]= {
{ {"Sıcaklık", "Temperature"}, &a , 10, 100"},
{ {"Nem", "Humidity"}, &b, 45, 70},
{ {"Basınc", "Pressure"}, &c , 100, 2000"},
...
...
0
}
Menümüze parametre ekleyerek ya da global bir Dil değişkeni tutarak dil seçimini yaptırabiliriz.
Ben menüye parametre ekleyerek yapacağım.
void menu(TMenuItem *Item, int Lang)
{
....
....
Yazdır(Item->Header->Str[Lang]); //Language seçimine bağlı olarak başlığı yazdır.
// enter tuşuna basınca
MenuEdit(Item , Lang); // Editörde de başlığı basacağı için , ona da dil seçimini gösterir parametre eklemelisiniz. Ya da dil seçimini global değişkende tutup oradan alabilirsiniz.
}
@Klein hocam emeğinize sağlık. Kocaman bir ders içeriği çıkmış ortaya. :)
Tekrar fırsat bulduğumda Alt menüler , farklı menü tiplerini entegre etme, Menüde seçilen Item'ler göre fonksiyon çağırma (Callback) gibi konularda yazarım biraz.
@Klein hocam birlik ve beraberliğe ihtiyacımız olan şu günlerde güzel konuya değinmişsiniz teşekkürler. ☺
@electroshock ben meseleyi yanlış anladım galiba
@Klein çok teşekkürler, benzer bir yapı kullanıyorduk, bu daha iyi bundan sonra bu şekilde çalışalım.
devamını bekliyoruz.
@Klein Hocam size teşekkür ediyorum. Benim seviyemin biraz üzerinde bir anlatım olmuş. CCS 'ye uyarlamasını yapmak için işaretçileri sizinde bahsettiğiniz gibi çok iyi bilmem gerekiyor sanırım. Keşke daha basitten başlasaydık:)
Ama anlatımınız ve paylaşımınız takdire şayan gerçekten. forumdaki konuları geziyorum genelde hep sözel anlatımlarla bırakılıyor cevaplar bu kadar detaylı bir kod yazıp paylaşmanız beni çok mutlu etti.
Ben işaretçilere mi çalışsam bilemedim..
@Klein hocam devamını bekliyorum.
Biraz yoğunum. Yoğunluğu atlatır atlatmaz. devam edeceğim.
sabırla bekliyoruz.
işlerinizde Allah kolaylık versin.
sagol teşekkür ederim
Bu menü algoritmasına prosedür işaretçisi eklenemez mi ?
arttırma azaltma gibi bir değer değilse ya da arttırma azaltma işlemi farklı çalışacaksa bu kez farklı bir prosedür çalıştırılabilir mi ?
C'yi basit düzeyde biliyorum sürekli pascal temelim olduğu için anlamakda zorlanmıyorum ama artık inat etmeyip C diline hakim olmam gerekiyor. Bu işaretciler ile böyle bir işlem yapılabilir gibi geliyor.
Örnek ;
{"Sıcaklık", "Temperature"}, [&a,0] , [0,10], [0,100],0"} // Sıcaklık menüsü
[/size]{"Saat", "Time"}, [&saat,&dakika] , [0,23], [0,59],&menu2"} // Saat menüsü
[/size]gibi
[/size]
[/size]
halen bekliyoruz
@Klein hocam :)
Ben bu şekilde yapmıştım. İsteyen state machine konusunu araştırabilir.
Menu tuşu ana fonksiyon ve diğerleri arasında gezinmeyi sağlıyor. Diğer butonlarda değişkenleri artırmayı ve azaltmayı sağlıyor.
while(1)
{
switch(durum)
{
case 0: //Ana program
break;
case 1: // Menu1
lcd.print(degisken1);
break;
case 2: // Menu2
lcd.print(degisken2);
break;
}
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG&BIT0) //Eksiltme tuşu
{
switch(durum)
{
case 0:
break;
case 1:
degisken1--;
break;
case 2:
degisken2--;
break;
P1IFG&=~BIT0; //kesme bayrağı temizlendi.
}
if(P1IFG&BIT1) //Menü tuşu
{
switch(durum)
{
case 0:
durum=1;
break;
case 1:
durum=2;
break;
case 2:
durum=0;
break;
}
P1IFG&=~BIT1; //kesme bayrağı temizlendi.
}
if(P1IFG&BIT2) // Artırma tuşu
{
switch(durum)
{
case 0:
break;
case 1:
degisken1++;
break;
case 2:
degisken2++;
break;
P1IFG&=~BIT2; //kesme bayrağı temizlendi.
}
}
Klein hocam yine döktürmüş. Çok teşekkürler.
@Klein üstad ellerine sağlık. Rica etsem konuya biraz daha açıklık getirebilir miyiz? konu epey eskide kalmış ama hem işaretçileri öğrenmek adına hem bir menü oluşturmak adına bir kaç sorum olacaktı.
Kullandığım derleyici Atollic True Studio;
typedef struct{
char *Header;
int * Var;
int min;
int max;
}TMenuItem;
int a = 0;
int b = 0;
int c = 0;
const TMenuItem OrtamMenu[]= {
{"Sıcaklık", &a , 10, 100},
{"Nem", &b, 45, 70},
{"Basınc", &c , 100, 2000},
{0},
};
bu şekilde typedef tanımlamaları yaptıktan sonra main içerisinde bu itemlere erişmek için tam olarak ne yapmak gerekiyor?
*Edit:
Hatta mümkünse eğer siz tarif edin ben elimden geldiğince yapayım ve konuyu hep birlikte öğrenelim. Alt menülerin olduğu bir menü tasarımını birlikte geliştirelim herkes faydalansın üstad.
Pointerlar konusunda bilgili arkadaşımız illaki vardır forumda. Örnekteki menü algoritmasında yazdır fonksiyonunu nasıl kurabiliriz?