int tus_oku()
{
x = adc_deger[2];
HAL_Delay(15);
if((tus_bayrak == 1) && ( x < 4000))
{
if((x >= tus_arti_alt) && (x <= tus_arti_ust))
{
return 1;
}
else if((x >= tus_eksi_alt) && (x <= tus_eksi_ust))
{
return 2;
}
else if((x >= tus_res_alt) && (x <= tus_res_ust))
{
return 3;
}
else if((x >= tus_mod_alt) && (x <= tus_mod_ust)); // && (tus_bayrak == 1))
{
++mod;
ekran_bayrak = 0;
if(mod == 4) mod = 1;
}
tus_bayrak = 0;
}
if(x >= 4000)
{
tus_bayrak = 1;
}
}
Bu fonksiyonun kendi içerisinde çalışmasında hiç bir sıkıntı yok. Okuduğum analog değerde anormallik olduğunu düşündüm ama okumada sıkıntı bulamadım. Return satırlarının olduğu yerlerde led yaktırarak denedim. Analog okumaya göre ilgili return satırı devreye giriyor.
Ancak tus_oku() fonksiyonunu çağırdığım zaman fonksiyon kararsız değer döndürüyor. Mesela 3 defa dönüşü aldıktan sonra 8 defa dönüş alamıyorum gibi.
Bir de "implict declaration of function" ve " 'if' clause does not guard... " uyarıları alıyorum. Ne yaptımsa bunların kaynağını bulamadım.
Cube ide de ilk defa kompleks bir kod yazıyorum. Cube ideye tam hakim değilim yani.
Fikirleriniz ile beni aydınlatır mısınız.
Fonksiyon adını include satırlarından sonra şu şekilde tanımlayabilir misiniz?
int tus_oku();
Else if'lerin sonuna bir adet de else koyup değişkenlerinizin değerini kontrol edin. Dokunmatik kontrolü yapıyorsanız basılan bölgenin x1,y1,x2,y2 şeklinde kontrolünü yapmanız lazım.
Fonksiyonun en sonunda, belirlediğiniz bir return olmalı. Mesela en başta tus_bayrak = 0, x de 4000'den küçük olsun.
if((tus_bayrak == 1) && ( x < 4000)) kısmına girmedi.
if(x >= 4000) kısmına da girmedi, en sona geldi.
Alıntı yapılan: SB7 - 18 Ocak 2024, 08:15:14Fonksiyon adını include satırlarından sonra şu şekilde tanımlayabilir misiniz?
int tus_oku();
bu satır ekli hocam.
Alıntı yapılan: JKramer - 18 Ocak 2024, 10:22:27Fonksiyonun en sonunda, belirlediğiniz bir return olmalı. Mesela en başta tus_bayrak = 0, x de 4000'den küçük olsun.
if((tus_bayrak == 1) && ( x < 4000)) kısmına girmedi.
if(x >= 4000) kısmına da girmedi, en sona geldi.
Tus_bayrak default değeri 1 hocam. Fonksiyona girince 0 oluyor.
if(x >= 4000)
Özellikle böyle bıraktım ki müdahale yok iken sürekli return 0 dönsün. Sizin dediğiniz gibi deneyeceğim.
Alıntı yapılan: kimlenbu - 18 Ocak 2024, 10:07:56Else if'lerin sonuna bir adet de else koyup değişkenlerinizin değerini kontrol edin. Dokunmatik kontrolü yapıyorsanız basılan bölgenin x1,y1,x2,y2 şeklinde kontrolünü yapmanız lazım.
Tam anlamadım. Biraz açabilir misin
Dokunmatik kontrolü değil hocam direnç gurubu üzerinden 4 adet tuş okuyorum.
Bir de bu uyarılar böyle karışıklıklara neden olur mu? Yoksa dikkate almamalı mıyım?
Fonskiyonun return edemediği durumlar var. Siz en az bir case return yazarak derleyiciyi kandırmış oluyorsunuz yani fonskiyonda logic hata var. Fonskiyon kötü yazılmış diyebiliriz. Fikir vermesi açısından bazı bakış açıları var birini anlatayım fonskiyona girdiğinizde bir otomatik değişken tanımlayıp return değerini bu değişkende tutup fonskiyonun en sonunda return edebilirisiniz
int tus_oku()
{
x = adc_deger[2];
int returnvalue=0;
HAL_Delay(15);
if((tus_bayrak == 1) && ( x < 4000))
{
if((x >= tus_arti_alt) && (x <= tus_arti_ust))
{
returnvalue=1;
}
else if((x >= tus_eksi_alt) && (x <= tus_eksi_ust))
{
returnvalue=2;
}
else if((x >= tus_res_alt) && (x <= tus_res_ust))
{
returnvalue=3;
}
else if((x >= tus_mod_alt) && (x <= tus_mod_ust)); // && (tus_bayrak == 1))
{
++mod;
ekran_bayrak = 0;
if(mod == 4) mod = 1;
}
tus_bayrak = 0;
}
if(x >= 4000)
{
tus_bayrak = 1;
}
return returnvalue;
}
Hemen deniyorum.
Return ifadesinin nasıl kullanılmaması gerektiğini öğrendim.
Teşekkür ederim
@flowchartx hocam.
Gene olmadı.
0 değeri döndüğünde hiç bir case girmediğini unutmayın. 0 değerini hata olarak kabul edebilirsiniz
@flowchartx 0 değeri stabil haldeyken tanımlı. Yani hiç bir tuşa basilmadıgini ifade ediyor ve 0 ın verildiği yer bayrakları temizliyor. Return 0 kullanılmıyor normalde.
Yazılım genel olarak yavaşladı. Sanırım yeni baştan temiz toparlamak lazım.
Örnek veriyorum a.h ve b.h diye iki sayfam var return fonksiyon a.h içinde. b.h içinden fonksiyon çağırıyorum. Bununla alakalı olamaz herhalde.
Bir de analog okumayı DMI ile 3 kanal yapıyorum. Bunların bir tanesi tuşa bağlı. Gene DMI ile iki kanal PWM yapılıyor. I2C ile oled ekran sürüyorum. İşlemci Usb ile bilgisayara veri aktarıyor. STM32F103. Çok mu yükleniyorum acaba?
Alıntı yapılan: flowchartx - 18 Ocak 2024, 21:21:09Fonskiyonun return edemediği durumlar var. Siz en az bir case return yazarak derleyiciyi kandırmış oluyorsunuz yani fonskiyonda logic hata var. Fonskiyon kötü yazılmış diyebiliriz. Fikir vermesi açısından bazı bakış açıları var birini anlatayım fonskiyona girdiğinizde bir otomatik değişken tanımlayıp return değerini bu değişkende tutup fonskiyonun en sonunda return edebilirisiniz
int tus_oku()
{
x = adc_deger[2];
int returnvalue=0;
HAL_Delay(15);
if((tus_bayrak == 1) && ( x < 4000))
{
if((x >= tus_arti_alt) && (x <= tus_arti_ust))
{
returnvalue=1;
}
else if((x >= tus_eksi_alt) && (x <= tus_eksi_ust))
{
returnvalue=2;
}
else if((x >= tus_res_alt) && (x <= tus_res_ust))
{
returnvalue=3;
}
else if((x >= tus_mod_alt) && (x <= tus_mod_ust)); // && (tus_bayrak == 1))
{
++mod;
ekran_bayrak = 0;
if(mod == 4) mod = 1;
}
tus_bayrak = 0;
}
if(x >= 4000)
{
tus_bayrak = 1;
}
return returnvalue;
}
Test ettiğiniz kod bumu?
else if((x >= tus_mod_alt) && (x <= tus_mod_ust)); // && (tus_bayrak == 1))
Buradaki Noktalı virgül ne işe yarıyor?
@JOKERAS o kodları buraya koyarken gözden kaçan bir şey. Siz gösterince büyük bir heyecan ile bilgisayara saldırdım hemen. Ama düzeltmişim. Şu anki halinde bu hata mevcut değil. Hala istediğim gibi çalışmıyor. Bir fonksiyon için bu kadar zaman harcamak çok canımı sıktı.
@papsukal , sizin kodda anlamadığım noktalar var.
Kodunuzun en önemli parametresi adc değerini tuttuğunuz "x" değişkeni.
"tus_bayrak" gereksiz gibi duruyor.Bunun için kodunuzu biraz değiştirdim.
DMI ne oluyor?
unsigned char tus_oku(void) {
x = adc_deger[2];
HAL_delay(15); //Bence buna gerek yok.
if (x < 4000) {
if (x >= tus_arti_alt && x <= tus_arti_ust) {
return 1;
} else if (x >= tus_eksi_alt && x <= tus_eksi_ust) {
return 2;
} else if (x >= tus_res_alt && x <= tus_res_ust) {
return 3;
} else if (x >= tus_mod_alt && x <= tus_mod_ust) {
ekran_bayrak = 0;
if (++mod == 4) {
mod = 1;
}
return 4;
} else {
return 0;//Tuş basılı fakat değerler uyuşmuyor.
}
} else {
return 0; //Tuş basılmamış!
}
}
Bu şekilde bir deneyin bakın ne oluyor durumu görün.
Hocam kodlar iyice çığırından çıktı :) şu an 17 hata görünüyor. Yeni baştan toparlayıp sizin verdiğiniz kodları deneyeyim.
Yaşadığın sorunun kaynağı tus_xxx_alt - üst değişkenleri ile sorguladığın koşullardan birden fazlasının sağlandığı durumlarda oluyor gibi. If-else içinde koşulların biri sağlandığı zaman sonraki sağlanan koşullara bakmıyor çünkü. Bu değişkenlerin değerlerini ve tuş şemanı ekleyebilirsen ona göre yorumlaması daha kolay olur.
Artık kodlar nasıl karıştı ise :) 8 gün olmuş dokunmadım daha.
Öncelikle yeni oluşturduğum .h ve .c dosyalarını properties üzerinden patch yapmam gerekiyormuş. Bunu yapınca tüm uyarılar kayboldu. Sonra kodlarımı bir yerde toplamak düşüncesi oluştu.
Kendi kodlarımı düzenlemek adına kütüphane şeklinde oluşturmaya çalışırken hepsi birbirine girdi. Aslında kodlar aynı ama library patch ayarlarını sanırım karıştırdım hal kütüphanelerini falan da tanımıyor şu anda.
En son yedeğimden yeni baştan oluşturacağım kodları.
Cubeideyi kullanmayı öğrenmeden bu tarz sorunlar ile çok karşılaşacağım kesin. İlk etapta kütüphane oluşturmayı öğrenmem gerek.
Oluşturduğum .c ve .h dosyalarını core klasöründe inc ve src içinde tutarsam sorun yok. Ancak kendi kodlarım derli toplu bir yerde dursun diye "dosyalarım" gibi bir klasör oluşturup içine inc ve src klasörlerini oluşturdum. header ve source dosyalarını buraya yerleştirdim. Ne yaptımsa tanıtamadım. Dosyamın üzerinde anahtar sembolü oluşuyor. Bununla alakalı mıdır bilmiyorum. kendi kodlarımı ayrı bir klasörde .h ve .c olarak toparlamamın bir yöntemi var mı yoksa Core içinde mi olmaları geekiyor?
Adım adım öğreniyorum. Şu anda çok sağlıklı bir şekilde ADC üzerinden tuş okumalarını yapabiliyorum. Yaşadığım problem ise aslında
@JKramer hocamın anlattığına benzer bir durum.
@flowchartx hocam sizin anlatmaya çalıştığınızı sonunda anladım ama biraz uzun sürdü. Tam teşhis koymuşsun.
Bir fonksiyondan Return ile değer istediğimizde eğer ki mantık hatası yapıp fonksiyonun boş değer döndürmesine sebep olursak fonksiyon enterasan bir şekilde kafasına göre bir değeri döndürüyor.
Benim yazdığım kodda tam da bu sebepten (aslında kodlar doğru çalışmasına rağmen) okuduğum adc değerini (dma ile okuduğum için sürekli güncel olanı) döndürüyormuş. Aslında değer gelmemesi gerekirken sürekli güncel değer geldiği için şartlar oluşmamasına rağmen if bloğuna girdiğini düşünüp yanlış yerde hata arıyormuşum.
Fonksiyonun son hali bu şekilde.
int tus_oku()
{
int y;
if(tus_bayrak == 0)
{
if(adc_deger[2] <= 4000)
{
for(int i = 0; i < 10; ++i)
{
x = adc_deger[2];
}
for(int i = 0; i < 10; ++i)
{
x = x + adc_deger[2];
}
tus_bayrak = 1;
x = x/11;
}
}
if((adc_deger[2] >= 4000) && (adc_deger[2] <= 4095))
{
tus_bayrak = 0;
x = 4096;
y = bos;
}
if((x >= tus_mod_alt) &&(x <= tus_mod_ust)){
y = mod;
}
if((x >= tus_arti_alt) && (x <= tus_arti_ust)){
y = arti;
}
if((x >= tus_eksi_alt) && (x <= tus_eksi_ust)){
y = eksi;
}
if((x >= tus_res_alt) && (x <= tus_res_ust)){
y = res;
}
return y;
}
implict declaration uyarılarına henüz tam bir çözüm bulamadım. Properties üzerinden path and symbols altında includes yollarını yeniden apply ediyorum uyarılar kayboluyor, koddaki ilk değişiklikte geri geliyorlar yeniden path apply etmem gerekiyor. Şimdilik bana bir zararları yok. Beraber yaşamaya alışacağız anlaşılan.
Yardım için yorumda bulunan herkese teşekkür ederim.
Yeni önerilieriniz olursa değerlendirmek isterim.
if(adc_deger[2] <= 4000)
{
for(int i = 0; i < 10; ++i)
{
x = adc_deger[2];
}
for(int i = 0; i < 10; ++i)
{
x = x + adc_deger[2];
}
tus_bayrak = 1;
x = x/11;
}
@papsukkal , Yine analamdığım noktalar var.
Şimdi yukarıda iki tane döngü kurmuşsunuz. Birinci for ne işe yarıyor?
Sizin yerinizde olsam İkinci for'da 2 nin katlarına denk gelen bir döngü limiti
koyar bölme yerine Sağa shift yapardım.Bölme Zamandan ve alandan yer.
for(i = 0; i < 16; ++i) {
x = x + adc_deger[2];
}
x = x >> 4;//x 16'ya bölündü.
Bu daha hızlı çalışır.
Ayrıca ....
if()
if()
if()
.
.
.
Zamandan yer, çünkü her if e bakmak zorunda.
if
else if
else if
.
.
Bu şekilde olursa alanı yer.Ama Zamanı if lere göre daha hızlıdır.
Çünkü koşul sağlandığı anda diğer if lerin hükmü kalmaz.
Naçizane önerim budur.
Hocam oradaki for dönüşü ile tuşa ilk bastığım anda analog değer gerçek değerine ulaşana kadar ilk 10 okumayı değerlendirmemek için koydum. Tuş takımı kumandalardaki gibi karbon boyalı tuş.
Kaydırma önerini değerlendireceğim. Benim aklıma gelmedi. Tecrübesizliğime verin :)
Elseleri koyamadığımın farkında değilim. Kod çalışınca heyecandan atlamışım.
C'de implicit uyarısı (bana kalırsa) çok tehlikeli olabilir. Sorunun sebenini bulup değerlendirmekte fayda var. Aklınızda bulunsun
Alıntı yapılan: flowchartx - 04 Şubat 2024, 21:32:05C'de implicit uyarısı (bana kalırsa) çok tehlikeli olabilir. Sorunun sebenini bulup değerlendirmekte fayda var. Aklınızda bulunsun
Nette baktım önerilerin hepsini de denedim ama sonuç alamadım. Kodlar biraz şişip karmaşıklaşınca başımı ağrıtacak. Hissedebiliyorum. Tahminim başka dosyadaki fonksiyonu cağırdığımda oluyor ama emin de değilim. Workspace tabanlı derleyicide daha önce çalışmadım. Böyle böyle uğraşarak STM i öğreniyorum.
Mesela .c ve .h dosyaları oluşturuyorum, bazıları sorunsuz oluyor, aynı şekilde yenisini oluşturuyorum hata veriyor. Neden kabul ediyor neden itiraz ediyor henüz çözemedim.
Bir de size bir soru sorayım. Yazdığım kodun 3 senaryosu var. Birisinde çalışırken diğer ikisi ile hiç bağlantısı (ortak kullanılan birkaç fonksiyon hariç) olmayacak. Kod çalışmaya başlayınca 1. Senaryonun main fonksiyonda while(1) içinde koşacak. 2. senaryoya geçmesi gerektiğinde bu senaryonun main fonksiyonunda while(1) içinde koşacak. Ve 3. için de aynısı olacak. Geçişler taşlardan gelen bilgi ile olacak. Anlaşılırlığı yüksek tutmak için her birini ayrı dosyada tutmak istiyorum.
Bu şekilde oluşturmak mantıklı olur mu ya da nasıl bir algoritma yaparsam daha sağlıklı olur?