Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

mplab xc8 de hatalı derleme

Başlatan apsis, 13 Mart 2014, 21:10:50

apsis

Merhaba,
Aşağıdaki programı h-tech c derleyicisini seçerek derlediğimde istenilen biçimde çalışıyor. Ancak xc8 ile derlediğimde program 1 kere çalışıyor yani çalışması gereken şekli; butona bastığımda led yancak bastıpımda sönecek ama xc8de derlediğim zaman ilk başta butına bastığımda çalışıyor bastığımda sönüyor ve bir daha çalışmıyor. reset butonuna bastığımda reset yapmıyor da. Kod:
#include <xc.h>


void main(void)
{
   
   
    TRISB=0X01;
    PORTB=0X00;

    INTF=0;
    INTEDG=1;
    INTE=1;
    GIE=1;
    while(1);
   
}

static void interrupt
kesme(void)
{
    char i;
    if(INTF)
    {
        GIE=0;
        i++;
       
                if(i==1)
                    RB1=1;
                 if(i==2)
                {
                    RB1=0;
                    i=0;
                }

        INTF=0;
        GIE=1;

    }
}
"Makineye Beyin" MEKATRONİK

subram

http://www.elektronark.org  Türkiyede Elektronik Kültürünü Değiştirmeye Geliyoruz

apsis

"Makineye Beyin" MEKATRONİK

Tagli

Programda config ayarları yok. Sorun bundan kaynaklanıyor olabilir.

Normalde kesme kodu içinde GIE ile oynanmaz. GIE kesme girişinde donanım tarafından otomatik olarak sıfırlanır ve kesme fonksiyonu çıkışında da RETFIE komutu ile dönüldüğünden otomatik olarak 1 olur.

Fonksiyon başındaki tanımlamada i'nin değeri belirsiz. Ayrıca i'yi statik olarak tanımlaman gerekir. Sorun büyük ihtimalle bundan kaynaklanıyor. Senin yazdığın şekliyle fonksiyona her girişte i rastgele bir değer alıyor muhtemelen. Doğrusu şöyle olmalı: static char i = 0;

Ayrıca, "button bouncing" (zıplama?) de sorun yaratıyor olabilir.

Alıntı Yapreset butonuna bastığımda reset yapmıyor da.
Bunu nereden biliyorsun? Reset ardından register değerleri belirsiz olur. Bir ihtimalle yukarıda bahsettiğim rasgele i, ilk enerji verildiğinde 0 olup resetin ardından bir önceki değerine geliyor olabilir. Zaten 0'dan farklı olduğu her durumda sorun çıkaracaktır. Kesin bir şey söylemek zor çünkü olay belirsiz zaten.
PIC'in resetlendiğinden şöyle emin olabilirsin: while(1) yazmadan önce ana programda LED'i 1 saniye yakıp söndür.
Gökçe Tağlıoğlu

Gökhan BEKEN

@Tagli hocama katılıyorum.
Ek olarak, böyle durumlarda debug yapmanızı tavsiye ediyorum.
Özel mesaj okumuyorum, lütfen göndermeyin.

apsis

@tagli hocam sizin dediğiniz gibi oldu değişkeni static olarak tanımladım düzeldi. değişkeni neden static olarak tanımladık? ve program önceki haliyle h-tech picc p.65pl1 de derlediğimde çalışıyor bunu da anlamadım!
"Makineye Beyin" MEKATRONİK

Gökhan BEKEN

Statik tanımlamazsanız şöyle olur :
kesme fonksiyona ilk girdiğinde i değişkeni 1 artırır. Sonraki girişinde değişken statik olmadığı için daha önceki artırdığın değişkenin 1 olması gerekirken 0 olur. Çünkü bir fonksiyon içindeki değişkenler statik tanımlanmazsa 0(sıfır) olarak yeni değer alır.

Çözüm olarak ya değişkeni fonksiyon içinde değil de bütün fonksiyonların dışında tanımlayın(böyle yaparsan global olur ve bütün fonksiyonlardan erişebilirsiniz ve verdiğiniz değerler kalıcı olur)
Diğer yöntem olarakta kesme içinde statik olarak tanımlayın.

Tercih size ait.

Alıntı yapılan: Tagli - 14 Mart 2014, 06:47:30
Ayrıca, "button bouncing" (zıplama?) de sorun yaratıyor olabilir.
Bu konuyu da es geçmeyin. Mutlaka düzeltin.
Özel mesaj okumuyorum, lütfen göndermeyin.

Tagli

Alıntı yapılan: meftun - 14 Mart 2014, 16:08:30
Çünkü bir fonksiyon içindeki değişkenler statik tanımlanmazsa 0(sıfır) olarak yeni değer alır.
Bu yanlış aslında. Fonksiyon içinde tanımlanan statik olmayan normal değişkenler (aslında otomatik değişken olarak bilinirler) derleyicinin oluşturduğu yazılımsal yığında (stack) saklanır. Yığın, programı çalışması sırasında sürekli değişir, ancak buradan yer açılırken eski değişkenler silinmez aslında, sadece yığın işaretçisi (pointer) kaydırılır. Bu durumda, yeni değerler eski değerlerin üzerine yazılır. Global değişkenlerin aksine, yığın içinde bulunan bu değişkenlerin ömürleri fonksiyonun çalıştığı süreyle kısıtlıdır ve bunların rastgele değerler aldıkları kabul edilir. Yani "değer verilmezse 0'dır" diyemeyiz. Çünkü bu fonksiyonda mesela char i'yi tutan bellek bölgesi, başka zamanda çalışan bir başka fonksiyonda belki de bir int x'in küçük byte'ını tutuyordur ve onun son değerini almış olabilir.

Hi-Tech'de programın çalışması tamamen tesadüf. Bu biraz da programda başka fonksiyon olmaması ile ilgili. Demek ki Hi-Tech derleyicisi kesme fonksiyonu her çalıştığında yığın üzerinde i'ye hep aynı alanı vermiş. Bir başka fonksiyon da kesme olmadığı zaman o alanı işgal etmediği için i değişmeden kalabilmiş. Dilin standart kuralları içinde kalmak şartıyla derleyicilerin çalışma şekilleri birbirinden farklı olabilir.

Düşük bir ihtimalle, Hi-Tech derleyicisi fonksiyon girişinde yığın içindeki başlangıç değeri atanmamış otomatik değişkenleri sıfırlıyor olabilir ancak bu, C dilinin standartında olan bir şey değil. XC8 yapmıyordur, kurallara aykırı bir durum yok.
Gökçe Tağlıoğlu

apsis

Anladım teşekkürler yardımlarınız için :)
Alıntı YapAyrıca, "button bouncing" (zıplama?) de sorun yaratıyor olabilir.
bu nedir? buton arkı mı?
"Makineye Beyin" MEKATRONİK

Kazım

#9
@tagli ve @meftun hocam bende hitech c kullanıyorum.Statik değişkenini ben hiç kullnamadım.son projemde analog joystik,gps,rftransc.,timerlar,rcservolar,lcd ler var.Hiç sorunsuz çalişışıyor.ama bu mezqj beni korkuttu doğrusu.program kararsız hale gelebilirmi diye.bütün kütüphanelerin ,interruptların içindeki değeri değişmemes gereken i gibi değişkenlerin õnüne statik yazıp değiştermem mi lazım.bende isis ve devamında pickit3 ile debug yapıyorum.dedigim gibi htech le yazdığım programımı. Sorunnsuz calısması benide kararsız durumda getirdi. . Bazı kütüphanelerde .h dosyası içindekilerîn statik olduğunu gördüm .c dosyalarında rastlamadım.neyse bu statik olayını anlayamıdım oldukça önemli.

Birde anaprogram.c dosyamda main fonksyonumun icicndekiler de statik mi olacak.



Tabletten yazmak çok zor.imla hatalari icin kusura bakmayin.zaten 20 dakiksda yazdim.yazana kadarda olayı anladım ya neyse.


Tagli

Hayır. Statik değişkenler zaten çok sık kullanılan şeyler değil. Sadece fonksiyonun içinde geçerli olduğu halde, fonksiyon sonlandıktan sonra da değerini kaybetmeyip fonksiyonun bir sonraki çağrılışında eski değeri ile devam etmesi gereken değişkenler için kullanılır.

Hatta çoğu zaman, fonksiyon içinde statik değişken tanımlamak aklıma gelmez, aynı amaçla dışarıda global değişken tanımlarım. Yanlış aslında.

Unutulmaması gereken şey, fonksiyonların içindeki değişkeneler (statik olmayanlar) fonksiyona her girişte rastgele değer alır, tabi eğer başlangıç değerleri verilmemişse. Bu çoğu zaman bir sorun yaratmaz. Ama apsis'in verdiği örnekte sorun yaratıyor çünkü i değişkeninin kesmeden çıkıldıktan sonra da değerini koruması gerekiyor.

apsis,
Alıntı Yapbu nedir? buton arkı mı?
Evet, o şekilde ifade etmek aklıma gelmedi.
Gökçe Tağlıoğlu

Kazım

#11
sağolun hocam. Ne zaman sıkışsam meftun hocamla siz hemen yardımcı oluyorsunuz.

Mesela for döngüsünde gerek yok.olay orada başlayıp bitiyor.Ama fonksiyon içinde i++ veya i-- vb gibi sonrasında fonksyon ndan geri dönülürse kullanılmalı.foksiyon içinde statik tanmlamak veya global olarak i,z vb. her fonksiyon icin farklı isim vermek lazim.bu durumda fonksyon icinde statik olmali  bence.

Tagli

Genelleme yapmak yanlış olur. Olay tamamen değişkenin ne amaçla kullanıldığına bağlı.
Gökçe Tağlıoğlu

apsis

#13
peki şu program neden çalışmıyor xc8 de? işlemci 16f877a config ayarları vs hepsi tamam ama aynı kodu h-tech çalışırıyor xc8 çalıştırmıyor.(Not: bu örnekler Fırat DEVECİ'nin kitabından alıntıdır)
void main(void)
{
    ADCON1=0x07;
    TRISA=0x10;
   
    TRISB=0x00;
    PORTA=0x00;
    PORTB=0x00;
    TMR0=-5;
    T0SE=0;
    T0CS=1;
    PSA=1;
    PS2=0;
    PS1=0;
    PS0=0;
    TMR0IF=0;
    TMR0IE=1;
    GIE=1;
    for(;; );

}
static void interrupt
say(void)
{
    static char i;

    if(TMR0IF)
    {

        GIE=0;
        i++;
      
        if(i==16)
            i=0;
        PORTB=i;
        TMR0=-5;
        TMR0IF=0;
        GIE=1;

    }
}
"Makineye Beyin" MEKATRONİK

mehmet

/* 
 * File:   newmain.c
 * Author: mehmet
 *
 * Created on 16 Mart 2014 Pazar, 11:53
 */

#include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 20000000     //defining crystal frequenct to 20 MHz

// PIC16F877A Configuration Bit Settings

#include <xc.h>

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)


void interrupt ISR (void)
{
    static char i;

    if(TMR0IE && TMR0IF)
    {
        //GIE=0;
        i++;

        if(i==16) i=0;

        PORTB=i;
        TMR0=-5;
        //GIE=1;

    }
    TMR0IF=0;
}


void main(void)
{
    ADCON1=0x07;
    TRISA=0x10;

    TRISB=0x00;
    PORTA=0x00;
    PORTB=0x00;
    
    TMR0=-5;

/* T0SE=0;
    T0CS=1;
    PSA=1;
    PS2=0;
    PS1=0;
    PS0=0;
    TMR0IF=0;
    TMR0IE=1;

    GIE=1;*/


    INTCON         = 0b10100000;
    OPTION_REG = 0b00000111;

    for(;;);

}


Hex dosyası:
:060000000A128A11122809
:10000800FE00030EF1000408F2000A08F300831250
:1000180003137F08F4000A128A111A280A128A1197
:100028001528F50183010A128A1135288B1A0B1D30
:1000380029280130F0007008F5077508103A0319EF
:10004800F50175088600FB3081000B117408FF006C
:1000580073088A0072088400710E8300FE0E7E0EFB
:1000680009000730831603139F00103085008601AE
:100078008312031385018601FB308100A0308B00B9
:0A0088000730831603138100482897
:02400E007AFF37
:00000001FF
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"