XC8 Saçma bir sıkıntıdan dolayı kod yanlış çalışıyor.

Başlatan ahmetzafer, 10 Ekim 2014, 18:32:33

ahmetzafer

Merhaba,

İki ayrı fonksiyonum var -- > fazSirasi() ve sinir_degerlerin_kontrolu()
fazSirasi() fonksiyonu rst_statu değişkenini '0' ya da '1' olarak değer atıyor.
sinir_degerlerin_kontrolu() fonksiyonu değerleri daha önce belirlenen başka değerler ile karşılaştırma yapıp duruma göre LCD'ye yazdırılacak uyarıyı seçiyor ve Pic'in ilgili bacaklarını değiştiriyor.

Karşılaştığım saçma sıkıntı;
Normalde rst_statu = 0 olması gerekiyor iken 1 oluyordu.
sinir_degerlerin_kontrolu() fonksiyonunda akım kontrollerindeki "if(current_measured_R > akim_max)" koşullarında akim_max değişkenini kullanırsam yanlış çalışıyor. Yani rst_statu = 0 olmalıyken 1 oluyor. akim_max değişkeni geçen koşulları kaldırırsam kod doğru çalışıyor.
rst_statu --> unsigned char
akim_max --> float (current_measured_R değişkeni float işlemlerde kullanıldığı için bu değişkenide float yaptım)

rst_statu başka hiçbir yerde değeri değişmiyor.

    void fazSirasi(void) {
        if (voltage_state == 1) {
            if (fazSirasiState == 1) {
                if (state == 0) { //Birinci sinyalin sifir noktasi bulunuyor.
                    if (ADCResult_int_0 == 0 && ADCResult_past_0 > 0) {
                        if (ADCResult_int_1 > 0) {
                            state = 1;
                        } else {
                            state = 0;
                        }
                    }
                } else if (state == 1) {
                    if (ADCResult_int_1 == 0 && ADCResult_past_1 > 0) {
                        if (ADCResult_int_2 > 0) {
                            state = 2;
                        } else {
                            state = 0;
                        }
                    }
                } else if (state == 2) {
                    if (ADCResult_int_2 == 0 && ADCResult_past_2 > 0) {
                        if (ADCResult_int_0 > 0) {
                            rst_statu = 1;
                            fazSirasiState = 0;
                        } else {
                            //                            systemStop();
                            rst_statu = 0;
                        }
                        state = 0;
                    }
                } else {
                    emniyet_durum_cikisi = 0;
                    systemStop();
                    state = 0;
                }
            }
        }

        ADCResult_past_0 = ADCResult_int_0;
        ADCResult_past_1 = ADCResult_int_1;
        ADCResult_past_2 = ADCResult_int_2;

        //--------------------------------------
        //Test __ Kaldirmayi Unutma
        if (rst_statu_past != rst_statu) {
            if (rst_statu != 1) {
                Serial_LCD_Out(4, 1, "rst = 0");
            } else {
                Serial_LCD_Out(4, 1, "rst = 1");
            }
        }
        //--------------------------------------

        rst_statu_past = rst_statu;
    }


    void sinir_degerlerin_kontrolu(void) {
        if (menu_value == 0) {
            if (vol_0_rms < voltage_min || vol_1_rms < voltage_min || vol_2_rms < voltage_min ||
                    vol_0_rms > voltage_max || vol_1_rms > voltage_max || vol_2_rms > voltage_max) {
                voltage_state = 0; //Gerilim hatasi
            } else {
                voltage_state = 1; //Gerilim normal
            }
            if (temp < isi_ac_value || temp > isi_kapa_value) {
                Isi_ledi = 1;
            } else {
                Isi_ledi = 0;
            }
            if (rst_statu != 1) {
                RST_hatali_ledi = 1;
            } else {
                RST_hatali_ledi = 0;
            }
            //            if (current_measured_R < akim_min || current_measured_R > akim_max ||
            //                    current_measured_S < akim_min || current_measured_S > akim_max ||
            //                    current_measured_T < akim_min || current_measured_T > akim_max) {
            if (current_measured_T > akim_max) {
                    if (demeraj_suresi_sayicisi >= demeraj_suresi) {
                        asiri_akimi_ledi = 1;
                    }
            } else {
                asiri_akimi_ledi = 0;
            }

            //Hata mesaji seciliyor
            //            if (current_measured_R < akim_min || current_measured_R > akim_max ||
            //                    current_measured_S < akim_min || current_measured_S > akim_max ||
            //                    current_measured_T < akim_min || current_measured_T > akim_max) {
            //                if (demeraj_suresi_sayicisi >= demeraj_suresi) {
            //                    error_type = 3; //Asiri Akim
            //                }
            //            } else
            if (vol_0_rms < voltage_min || vol_1_rms < voltage_min || vol_2_rms < voltage_min ||
                    vol_0_rms > voltage_max || vol_1_rms > voltage_max || vol_2_rms > voltage_max) {
                error_type = 4; //Gerilim Hatali
            } else if (temp < isi_ac_value || temp > isi_kapa_value) {
                error_type = 2; //Asiri Sicaklik
            } else if (rst_statu != 1) {
                error_type = 1; //RST Yanlis
            } else {
                error_type = 0;
            }
        }
    }

Gökhan BEKEN

Derleyicilere çok atıp tuttum ama hataların hepsinin benden kaynaklı olduğunu gördüm.

ADCResult değişkenini float yapmışsınız, bu değişken 0.000001 bile olsa 0 dan büyük kabul edilir. Yani if (ADCResult_int_0 > 0) bloğu içine girer.



if (ADCResult_int_0 > 0) {
                            rst_statu = 1;
yazıyor, bu if'e girip girmediğinin garantisini verebilir misiniz?
Debug yaptınız mı?
şöyle denediniz mi:
ADCResult_int_0=0;
if (ADCResult_int_0 > 0) {
                            rst_statu = 1;
ya da şöyle:
if (ADCResult_int_0 > 0) {
                            //rst_statu = 1;
Özel mesaj okumuyorum, lütfen göndermeyin.

ahmetzafer

Meftun bey if() ' e girdiğinin garantisini verebilirim. Dediklerinizi de test ettim olması gerektiği gibi çalışıyor.
Ben de birçok kez derleyicilere suç buldum. Bu kez hatayı bir türlü bulamayadım.
Geriye doğru yaptığım debug kontrollerinde ise sadece akim_max değişkenini kaldırırsam çalıştığını buldum. Ama bir anlam veremedim.

Gökhan BEKEN

O şekilde denediğinizde rst_statu değişkeni yine de 1 oluyor muydu?
Bir de böyle tam anlaşılmıyor, proteus ile çalışabiliyor mu proje, eğer çalışıyorsa yükerseniz biz de bakarız.
En azından diğer kodları da yazarsanız fikir yürütürüz.
Bu arada biliyorsunuz, bir değişkenin içeriğini değiştirmek için değişkenin adını yazmaya gerek yok. Değişkenler ram'de tutulduğu için, herhangi bir pointer ile bütün değişkenler değiştirilebilir. Belki farkında olmadığınız bir yer, o değişkenin adresine başka bir değer yazıyordur.
Özel mesaj okumuyorum, lütfen göndermeyin.

ahmetzafer

Sizin dediğiniz gibi denediğimde değişken 1 olmuyor.
Projeyi proteus'ta çalıştırarak test ediyorum zaten. Çalışmasında problem yok.
Projenin sahibi ben olmadığım için kodların hepsini ve proteus'u paylaşmaya iznim yok ne yazık ki. Bayada uzun zaten.
Kodlarken hiç pointer kullanmadım ama genede daha iyi incelesem iyi olucak.
Yardımlarınız için teşekkürler.

Gökhan BEKEN

ADCResult_int_0 değişkeninin alabileceği değerler neler, neden float?
Virgüllü sayılar alıyorsa, yukarıda bahsettiğim gibi 0.0001 sayısını bile 0 dan büyük kabul eder, şöyle deneyin bir de:
if (((int)ADCResult_int_0) > 0)

bir de ADCResult_int_0 değişkeni başka bir yerde geçiyor mu?
Özel mesaj okumuyorum, lütfen göndermeyin.

ahmetzafer

ADCResult_int_0 değişkeni başka bir yerde float bir sayının çarpım sonucu olduğu için float yapmıştım. başka hiçbir yerde kullanılmıyor.
Kısaca pic'e 3 faz okutuyorum. aralarında 120 derece fark var. ADCResult_int_3 sinyali pozitiften negatife geçerken doğru faz sırası ise ADCResult_int_0 kesinlikle pozitifte ve rst_statu 0 oluyor. Doğru faz_sırası değil ise ADCResult_int_0 negatifte ve rst_statu 1 olacak. pic negatif değerleri okuyamadığı için negatiflik durumunda ADCResult_int_0 her zaman 0 değeri alıyor.

ahmetzafer

Sorunu çözdüm.
Programdaki float işlemler sebebiyle current_measured_R ve akim_max değişkenleri float olarak tanımlıydı.
İşlemleri başka bir float değişkene atayıp bunlarıda unsigned int e tanımladım. işlemlerden sonra sonucu
current_measured_R  = (unsigned int) current_measured_R_float;

şeklinde eşitledim ve karşılaştırmaları bu şekilde yaptım. Program şimdi sorunsuz çalışıyor. Ama buna bir anlam veremedim.

RaMu

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html