Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

CCS C alıştırma Turlarım

Başlatan Mucit23, 10 Şubat 2012, 15:29:51

Mucit23

#150
Arkadaşlar Merhaba

18F452 ile uğraşıyorum. Kesme olarak şuanda timer0 ve timer1 kesmeleri aktif ve çalışıyorlar. Bunların yanı sıra birde RB0  kesmesi lazım fakat bir türlü çalıştıramadım.

Yaptığım ayarlamalar bu şekilde,

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_ext);
   enable_interrupts(INT_timer0);
   ext_int_edge(H_TO_L);


timer1 kesmesini ise program içerisinde açıp kapıyorum. Bundada sıkıntı yok. Fakat ne yaptıysam RB0 kesmesini çalıştıramadım. RB0 da buton bağlı ve pin pull-up yapılmış durumda butona bastığımda pin 0 olacak. Ayarladada kesmenin bu anda oluşacağını belirttim. (ext_int_edge(H_TO_L);)

Kesme alt programınıda bu şekilde yaptım

#int_ext
void external_int(){

output_high(pin_b7);
}


Sorun diğer kesmelerdemi anlamak için RB0 kesmesi dışında bütün kesmeleri kapattım. Ama nafile. Butona bastığımda kesme oluşmuyor.

Sorun ne olabilir. RB0 kesmesinin başka gizemli ayarlarımı var?

mesaj birleştirme:: 27 Temmuz 2013, 21:08:27

Kesme fonksiyonu içerisine girdim sorun kesme fonksiyonu ismindenmiş. Fakat giriş işlemi tek seferlik oldu.  Kesme flagı temizlenmiyor olsa gerekki kesmeye girdimmi birdaha giremiyorum. Öylece kalıyor.. :-X

böyle yaptım kesme fonksiyonunu
#int_ext
void EXT_isr(){
output_toggle(pin_d7);
clear_interrupt(int_ext1);
}

halilgalic

"Mucit23" hocam b0 kesmesinde aynı sorunu bende yaşadım çözümü
#USE FAST_IO (b)
buldum.

Mucit23

@Halil

Port giriş çıkış yönlendirmelerini program başında zaten yapmışım. Bunun dışında bir problem olmalı

ogy

Sorun giriş çıkış tanımlamaları yada fonksiyon ismi değil...clear interrupt bile kullanmanıza gerek yok.Dikkat edilmesi gereken şu..
CCS C' de kesme içerisinde doğrudan işlem yapmaktan kaçının.Bir değişken atayın ve başlangıçta sıfır olsun..Kesme oluştuğunda 1 olsun..Main fonksiyonunda değişken 1 ise işlemi yaptırıp değişkeni sıfırlayın.Kesme sıkıntısız çalışacaktır.Örnek bir program yazdım.Kontrol ettim çalışıyor.
//******************************************************************************
//Program Adı             :RB0 Kesme uygulaması
//Program Amacı           :Butonla RB0 kesmesi yapılır.
//Açıklama                :Kesme geldiğinde portb.3 terslenir.
//                        :       
//                        :
//Programı Yazan          :Osman Görkem YOĞURTÇU
//Tarih                   :11.03.2012
//******************************************************************************

#include <16f628a.h> // İşlemci tanımlama dosyası çağırılıyor.
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOMCLR // Sigorta ayarları
#use delay(clock=20000000)  // Gecikme komutlarında kullanılcak frekans belirlenir.
#use fast_io(b) // giiş çıkış işlemleri manuel olarak yapılacak
int kesme=0;
     
#int_ext    // RB0/Int Dış Kesmesi (EXTERNAL)

//__________________________DIŞ KESME FONKSİYONU______________________________

void ext_kesmesi ()   // Dış kesme fonksiyonu
{
   while(input(pin_b0==0)) // Buton kilitleme
   {}
   kesme=1; // kesme oluştuğunun işaretçisi
}

//__________________________Main Fonksiyonu______________________________

void main ()   // Main Fonksiyonu
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0b00000001); // portb.0 giriş diğerleri çıkış

   
   enable_interrupts(INT_EXT);        // INT_EXT kesmesini aktif yapar.
   enable_interrupts(GLOBAL);         // Aktif edilen kesmelere izin ver.
   ext_int_edge(H_TO_L);              // Kesme düşen kenarda gerçekleşir.
   
       for(;;)                        // Sonsuz döngü       
         {
            if(kesme==1) // kesme oluştu ise 
               {
                  output_toggle(pin_b3); // RB3 ü tersle
                  kesme=0;               // yeni kesme oluşması için sıfırlanır.
               }
         }
}

Mucit23

Birşey Sorayım,

Kesme alt programında şarta bağlı olarak aşağıdaki kodlar çalışıyor.

       saat=zaman/60;
       dak=zaman%60;


Bu kodları aynı zamanda yine şarta bağlı olarak main programındada çalıştırmak istediğimde programı derlerken ccs bana aşağıdaki uyarıyı veriyor.


yükle resim

Buna benzer bir hatayı aynı fonksiyonu şarta bağlı olarak hem main döngüsünde hemde kesme içerisinde çalıştırmak istediğimde de alıyorum..

fatih6761

Hocam burada bir hata gözükmüyor. Uyarı vermesi normal. 16-bitlik bir değişkenle bölme işlemi yapıyorsunuz. Kullandığınız mikrodenetleyici çekirdeği 8-bitlik ise 16bit için ALU emülasyonu yapılacak. Yani yazılım birkaç aşamada bölmeyi gerçekleştirecek. Bu esnada kesme gelirse bölme işlemi yarıda kalabilir. Muhtemelen bunu engellemek için böle işlemi esnasında kesmeler kapatılıyor. Assembly çıktısını incelerseniz durumu anlarsınız.

haydarpasamikro

while(input(pin_b0==0)) // Buton kilitleme
   {}

Kesme içerisinde şartlı sonsuz bekleme yapılması ne kadar uygun olur. Ana programda yürütülmesi gereken başka şeyler varsa hep beklemede yada kaçtı.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

Tagli

#157
Uyarı vermesindeki asıl sebep şu: Bölme işlemi bir çeşit fonksiyon olarak gerçekleniyor. Benzer bir uyarıyı örneğin bir a() fonksiyonunu hem ana programda hem de kesmede çağırınca da verir. Zaten yine aynı sebepten dolayı yanlış hatırlamıyorsam CCS C, kesme kodu içinde delay kullanmaya izin vermiyordu. Bir fonksiyon çağrılırken, içinde kullanılan tüm değişkenler için derleyicinin kendi oluşturduğu bir yığında (stack) yer açılması gerekir. Anladığım kadarıyla mikrodenetleyiciler için yazılmış derleyiciler fazla karmaşık değil, veya kaynaklar az olduğu için derinlemesine girmek istemiyorlar ve aynı fonksiyon için iki farklı yığın alanı açamıyorlar. Yani kod bir tane, ve bunun iç değişkenlerinin adresleri de derleme anında belirlenmiş, dinamik bir yer ayırma söz konusu değil. Şimdi bu a() fonksiyonunu ana program işlerken, bu sırada bir kesme gelirse o da aynı a() fonksiyonunu çalıştıracak ve aynı değişkenlere erişmeye çalışacaklar. Kesmede çalışan a(), ana programdaki a()'nın durumunu bozacak, kan gövdeyi götürecek... Bu sebeple ana programdaki a() çalışmadan önce kesmeleri kapatıyor, derleyici de bunun uyarısını veriyor.

Zaten yukarıda bahsettiğim sebep yüzünden, düşük seviyeli işlemcilerin derleyicileri recursion'a (fonksiyonların kendi kendilerini çağırması) genelde izin vermezler. Bilgisayardaki C derleyicilerinde (veya daha gelişmiş işlemcilerin, atıyorum STM32 gibi) böyle bir kısıtlama yoktur, fonksiyonun her çağrılışında sanki farklı bir fonksiyonmuş gibi ayrı bir yığın oluşturulur.

Bu arada, XC8 yukarıdaki sorunu, arka planda iki fonksiyon oluşturarak çözüyor. Yani bir a() fonksiyonu hem ana programda hem de kesme içinde çağrılmışsa, bunlar gizlice a_1() ve a_2() gibi iki fonksiyon oluyor. Elbette bu durumda program hafızasında kapladıkları yer de artıyor. Bu özellik istenirse kapatılabiliyor. Belki kızacaksınız bana ama söylemeden geçemeyeceğim: "Yine CCS C, yine bir eksiklik..."

Ekleme: Az önce imla denetimi için Google'da "recursion" diye arattım da, benimle çok tatlı bir şekilde dalga geçti. Siz de bir deneyin.
Gökçe Tağlıoğlu

sadogan

Alıntı yapılan: Tagli - 30 Temmuz 2013, 20:04:50
Ekleme: Az önce imla denetimi için Google'da "recursion" diye arattım da, benimle çok tatlı bir şekilde dalga geçti. Siz de bir deneyin.
İlginç. Neden böyle ?

Erol YILMAZ


Mucit23

#160
@fatih6761ve @Tagli açıklamalarınız için teşekkür ederim

Ccs ile ilgili birşey daha sorayım.  Ccs bünyesinde random sayı üretme fonsiyonu yokmudur? Aralık vereyim random sayı versin.

kantirici

Alıntı yapılan: Tagli - 30 Temmuz 2013, 20:04:50

Zaten yukarıda bahsettiğim sebep yüzünden, düşük seviyeli işlemcilerin derleyicileri recursion'a (fonksiyonların kendi kendilerini çağırması) genelde izin vermezler. Bilgisayardaki C derleyicilerinde (veya daha gelişmiş işlemcilerin, atıyorum STM32 gibi) böyle bir kısıtlama yoktur, fonksiyonun her çağrılışında sanki farklı bir fonksiyonmuş gibi ayrı bir yığın oluşturulur.


Hocam aynı sorunu dün yaşadım XC8'de fonk. içinden aynı fonk. çağıramadım, benden fonk. kopyasını çağırdım.

Tagli

Alıntı yapılan: Mucit23 - 31 Temmuz 2013, 00:39:42
@fatih6761ve @Tagli açıklamalarınız için teşekkür ederim

Ccs ile ilgili birşey daha sorayım.  Ccs bünyesinde random sayı üretme fonsiyonu yokmudur? Aralık vereyim random sayı versin.
srand() ve rand() fonksiyonları ile yapılabiliyor olması gerekir ama srand()'ın çalışabilmesi için her seferinde farklı bir sayı ile beslemnesi gerekir ki bu zor bir iş. Bilgisayarda bunun için takvim ve saat kullanılır. PIC'te bunun yapılabilmesi için ya harici bir takvim entegresi olacak (DS1307 gibi), ya da program çalışırken rasgele bir zamanda birisi bir butona basarak o anki timer değerini alıp srand ile kullanacak. Aklıma gelen bir diğer yöntem, boşta floating pin varsa bunların değerini okumak ama ne kadar başarılı olacağı tartışılır. İşin özü, her çalışmada aynı seri gelmesi bir sorun yaratmayacaksa srand herhangi bir sayı ile ayarlanabilir, ama her seferinde farklı bir rasgele seri gerekiyorsa srand()'ın benzer bir şekilde farklı bir değerle beslenmesi gerekiyor.
Gökçe Tağlıoğlu

Mucit23

Hocam sistemde saat benzeri bir yapı yok fakat sürekli çalışan 8 ve 16 bitlik timerler var.
Fonksiyona mesela 8 bitlik timerin değerini gondersem nasıl olur ?

Tagli

Olur olmasına ama şöyle bir sorun var: O kısmın koddaki yeri belli, muhtemelen başlangıç ayarlarının içinde olacak. Yani PIC enerji alınca oraya hep aynı sürede ulaşacak, bu sebeple timer da hep aynı olacak. Bu durumda sabit sayı vermekten bir farkı kalmıyor. Dışarıdan rasgele bir müdahele olması lazım. Mesela PIC çalıştıktan sonra kullanıcı bir butona basacak, timer değeri o zaman okunarak srand()'a verilecek. Veya dediğim gibi, floating pinlere bakılabilir ama pek güvenilir değil bence. Sisteme bağlı sensörler varsa bunlar da kullanılabilir. CCS C'nin forumlarında birisi örnek olarak, PIC'e seri porttan gelen ilk byte ile timer'ın kaydedilmesini önermiş.
Gökçe Tağlıoğlu