Aynı anda 2 fonksiyon çalıştırmak mümkün mü?

Başlatan samedkutuk, 03 Haziran 2020, 19:05:09

samedkutuk

öncelikle umarım herkesin sağlığı ve işleri yolundadır.

Şuan denemek ve projemin alt yapısını oluşturmak ve biraz da Xc8 in dosya fonksiyon sistemini öğrenmek için bir örnek çalışma yaptım .
yapmak istediğim şu;

Ana Main.c Dosyam içerisine alt 2 adet fonksiyon çağırdım.1
1-) run_led() fonksiyonum butona basıldığı sürece 3 ledi sürekli sıralı olarak yakıp söndüren bir fonksiyondur.
#define _XTAL_FREQ 8000000UL // to perform delay
#include <xc.h> // to perform header
#define BTN PORTBbits.RB0 // PORT B zero leg is connected to BTN
#define led1 PORTBbits.RB1 // PORT B first leg is connected to led1
#define led2 PORTBbits.RB2 // PORT B second leg is connected to led2
#define led3 PORTBbits.RB3// PORT B third leg is connected to led3
char led_state = 1; // define led state initial value as 1


void run_led() {
TRISBbits.TRISB1 = 0; //make led1 output
TRISBbits.TRISB2 = 0; //make led2 output
TRISBbits.TRISB3 = 0; //make led3 output

TRISBbits.TRISB0 = 1; // make BTN input

while(1){
 if(BTN == 0){ // If button is pressed
 __delay_ms(100); // Wait for contact debouncing 100ms
if(BTN == 0) // If is button is still pressed
 led_state++; // incease the led state if button is still pressed(count)

 if(led_state == 5) led_state = 1; // if led state =5 turn to 1 again for count
 switch(led_state){
 case 1: // if led state=1
 led1=1; led2=0; led3=0; break; // led1 open
 case 2: // if led state=2
 led1=0; led2=1; led3=0; break; // led2 open
 case 3: // if led state=3
 led1=0; led2=0; led3=1; break; // led3 open
 case 4: // if led state=4
 led1=0; led2=1; led3=0; break; // led2 open
 case 5: led1=1; led2=0; led3=0; break; // led1  
 default: // any time
 led1=1; led2=1; led3=1; break; // led1 open in other conditions
 }
 }
 }
}

2-) Seven() Fonksiyonum butona basıldığı sürece 7-segment displayde 0-dan 9 a kadar rakamları yazdıran bir fonksiyondur.

#define _XTAL_FREQ 8000000UL // to perform delay 
#include <xc.h>   // to perform header 
char disp_counter = 0;    // define disp_counter initial value as 0  
#define BTN PORTBbits.RB0 // PORT B zero leg is connected to BTN

void seven(){   
 TRISBbits.TRISB0 = 1;    // make BTN input 
 TRISD = 0; // Make PortD output
     
 while(1){ 
    if(BTN == 0){     // If button is pressed 
    __delay_ms(500); // Wait for contact debouncing 500ms 
    if(BTN == 0)   // If button is still pressed 
    disp_counter++; // incease the disp_counter if button is still pressed(count) 
                   
                if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count 
                switch(disp_counter){ 
                    
                    case 0:  // if disp_counter=0 
                        PORTD=0b00111111; break; // Show 0 on display
                    case 1: // if disp_counter=1
                        PORTD=0b00000110; break; // Show 1 on display
                    case 2: // if disp_counter=2
                        PORTD=0b01011011; break; // Show 2 on display
                    case 3: // if disp_counter=3
                        PORTD=0b01001111; break; // Show 3 on display
                    case 4: // if disp_counter=4
                        PORTD=0b01100110; break; // Show 4 on display
                    case 5: // if disp_counter=5
                        PORTD=0b01101101; break; // Show 5 on display
                    case 6: // if disp_counter=6
                        PORTD=0b01111101; break; // Show 6 on display
                    case 7: // if disp_counter=7
                        PORTD=0b00000111; break; // Show 7 on display
                    case 8: // if disp_counter=8
                        PORTD=0b01111111; break; // Show 8 on display
                    case 9: // if disp_counter=9
                        PORTD=0b01101111; break; // Show 9 on display
                    default:  // any time
                        PORTD=0b00111111;break; // Show 0 on display
    }  
    } 
     if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
    }
    } 
}

Ana Min kodum;
/*
 * File:   newmain.c
 * Author: samed
 *
 * Created on 03 Haziran 2020 Çar?amba, 18:01
 */
#include <xc.h>

//#include <xc.h>
void run_led(void);
void seven(void);
void main(void) {
    
TRISBbits.TRISB1 = 0; //make led1 output
TRISBbits.TRISB2 = 0; //make led2 output
TRISBbits.TRISB3 = 0; //make led3 output
TRISBbits.TRISB0 = 1; // make BTN input
 TRISD = 0;    
while(1){   
    
     run_led();
     seven();
     
    
}
}


istediğim  Ana butona bastığımda hem ledler yanıp sönsün hemde displayde rakamlar sıralı olarak değişsin
yani kısacası 2 adet fonksiyonu aynı anda çalıştırmak istiyorum. ama şuan ilk öne hangisini yazdıysam hep o çalışıyor
sorunu çözemedim

Fonksiyonlarımı aynı zamanda iç içe de mi tanımlamam gerekiyor acaba
yada farklı bir yöntemi mi vardır

bilenler lütfen yardımcı olabilir mi ?



samedkutuk

serkan

#1
 if(BTN == 0) ları silip

while(BTN ==0) denermisin.

Tek butonla aynı anda sadece birisi çalışır ondan dolayı olabilir.

samedkutuk

samedkutuk

Endorfin35+

Benim bildigim iki cozum olabilir.

1. Dedigin gibi tek fonksiyon olacak.
2. kesme kullanarak fonksuyonun birini kesme icinde calistiracaksin.
"İşi bilen yapar, az bilen akıl verir, bilmeyen eleştirir, yapamayan çamur atar."

samedkutuk

Alıntı yapılan: serkan - 03 Haziran 2020, 19:43:15if(BTN == 0) ları silip

while(BTN ==0) denermisin.

Yok hocam malesef bir değişiklik olmadı
samedkutuk

samedkutuk

Alıntı yapılan: Endorfin35+ - 03 Haziran 2020, 19:48:46Benim bildigim iki cozum olabilir.

1. Dedigin gibi tek fonksiyon olacak.
2. kesme kullanarak fonksuyonun birini kesme icinde calistiracaksin.

ama tek fonksiyonda bile aynı anda olmuyor hocam
samedkutuk

Endorfin35+

Uzman degilim.

Tavsiye niteliginde, delay kullanma.

En basitinden bir adet sayac adinda long degisken kullan. Sayaci her fonksiyon dungusunde 1 arttir. İslem hizina gore degisecektir ancak soyle bir yapi olusur sayac atiyorum 3000 oldugunda senin istedigin delay kadar sure gecmis olur. Bunuda if ile kontrol edersin. Hatta fonksiyon dongusune sadece tek bir delay ekle 1ms lik. Sayac degerin yaklasik ms deger verir.

Boylece fonksiyonlar bir birini beklemeden islemleri yapar. Fonksiyonlar demek yanlis aslinda sonucta tek bir fonksiyon haline gelecek.
"İşi bilen yapar, az bilen akıl verir, bilmeyen eleştirir, yapamayan çamur atar."

samedkutuk

hocam bir yöntem görmüştüm iç içe dosyalama gibi yapıyorlar o şekilde ortak kullanılıyor gibi yapıyorlar.
ama onu da bulamadım.
acaba XC8 ait bir kullanım mı diye sormak istedim
samedkutuk

Tagli

Fonksiyonlarının ikisinin de kendi sonsuz döngüleri var, bu da hiçbir zaman sonlanmayacakları anlamına gelir. Normalde bu şekilde iki fonksiyonu aynı anda çalıştıramazsın. Bu ancak RTOS kullanarak mümkün olabilir. Yapmaya çalıştığın şey RTOS kullanmadan da yapılabilir, ama bu durumda programını iki ayrı fonksiyon olarak yazamazsın.
Gökçe Tağlıoğlu

samedkutuk

Alıntı yapılan: Tagli - 03 Haziran 2020, 22:44:18Fonksiyonlarının ikisinin de kendi sonsuz döngüleri var, bu da hiçbir zaman sonlanmayacakları anlamına gelir. Normalde bu şekilde iki fonksiyonu aynı anda çalıştıramazsın. Bu ancak RTOS kullanarak mümkün olabilir. Yapmaya çalıştığın şey RTOS kullanmadan da yapılabilir, ama bu durumda programını iki ayrı fonksiyon olarak yazamazsın.

Peki nasıl yapabilirim hocam?
samedkutuk

samedkutuk

samedkutuk

ilyas KAYA

Aynı anda çalışması için çift çekirdek bir işlemci gerekir. Ancak timer kesmesi kullanıp zamanlama işlerini timer kesmesi ile yaparak döngüyü hizlandirirsiniz. Başka türlü tek çekirdek işlemci ile mümkün değil.

RaMu

Fonksiyonları sürekli girip çıkılacak şekilde yazacaksın,
sanki herşeyi if ile yazıyormuşsun gibi düşün.
butona basıldımı, led yanma zamanı doldu mu ... gibi.
Bu mantıkla dene çözüm bulamazsan yardımcı olurum.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

serkan

#13
Fonksiyonlardaki while (1) leri kaldırıp denenebilir.


void run_led() {
while (BTN == 0){
    __delay_ms(100);
    disp_counter++; // incease the disp_counter if button is still pressed(count)        
                if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count 
                switch(disp_counter){ 
                    
                    case 0:  // if disp_counter=0 
                        PORTD=0b00111111; break; // Show 0 on display
                    case 1: // if disp_counter=1
                        PORTD=0b00000110; break; // Show 1 on display
                    case 2: // if disp_counter=2
                        PORTD=0b01011011; break; // Show 2 on display
                    case 3: // if disp_counter=3
                        PORTD=0b01001111; break; // Show 3 on display
                    case 4: // if disp_counter=4
                        PORTD=0b01100110; break; // Show 4 on display
                    case 5: // if disp_counter=5
                        PORTD=0b01101101; //break; // Show 5 on display
                    led1=1; led2=0; led3=0; break;// led1 open
                    case 6: // if disp_counter=6
                        PORTD=0b01111101; //break; // Show 6 on display
                    led1=0; led2=1; led3=0; break; // led2 open
                    case 7: // if disp_counter=7
                        PORTD=0b00000111; //break; // Show 7 on display
                    led1=0; led2=0; led3=1; break; // led3 open
                    case 8: // if disp_counter=8
                        PORTD=0b01111111; //break; // Show 8 on display
                    led1=0; led2=1; led3=0; break; // led2 open
                    case 9: // if disp_counter=9
                        PORTD=0b01101111; //break; // Show 9 on display
                    led1=1; led2=0; led3=0; break; // led1  
                    default:  // any time
                        PORTD=0b00111111;//break; // Show 0 on display
                    led1=1; led2=1; led3=1; break; // led1 open in other conditions
                }                
        if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
      }
  }
 }


void main(void) {
nRBPU =0;            //PORTB.0 pullup direnci acik
TRISB=  0b00000001;  //PORTB.0 giris
TRISD = 0b00000000;  
PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; //portlari temizle.

while(1){  
    
    run_led();  
  
    }
}


yada

void run_led() {
while (BTN == 0){
    __delay_ms(100); // Wait  
  
 led_state++; // incease the led state if button is still pressed(count)

 if(led_state == 5) led_state = 1; // if led state =5 turn to 1 again for count
 switch(led_state){
 case 1: // if led state=1
 led1=1; led2=0; led3=0; break; // led1 open
 case 2: // if led state=2
 led1=0; led2=1; led3=0; break; // led2 open
 case 3: // if led state=3
 led1=0; led2=0; led3=1; break; // led3 open
 case 4: // if led state=4
 led1=0; led2=1; led3=0; break; // led2 open
 case 5: led1=1; led2=0; led3=0; break; // led1  
 default: // any time
 led1=1; led2=1; led3=1; break; // led1 open in other conditions
 }

    disp_counter++; // incease the disp_counter if button is still pressed(count) 
                  
                if(disp_counter == 10) disp_counter = 0; // if disp_counter =10 turn to 0 again for count 
                switch(disp_counter){ 
                    
                    case 0:  // if disp_counter=0 
                        PORTD=0b00111111; break; // Show 0 on display
                    case 1: // if disp_counter=1
                        PORTD=0b00000110; break; // Show 1 on display
                    case 2: // if disp_counter=2
                        PORTD=0b01011011; break; // Show 2 on display
                    case 3: // if disp_counter=3
                        PORTD=0b01001111; break; // Show 3 on display
                    case 4: // if disp_counter=4
                        PORTD=0b01100110; break; // Show 4 on display
                    case 5: // if disp_counter=5
                        PORTD=0b01101101; break; // Show 5 on display
                    case 6: // if disp_counter=6
                        PORTD=0b01111101; break; // Show 6 on display
                    case 7: // if disp_counter=7
                        PORTD=0b00000111; break; // Show 7 on display
                    case 8: // if disp_counter=8
                        PORTD=0b01111111; break; // Show 8 on display
                    case 9: // if disp_counter=9
                        PORTD=0b01101111; break; // Show 9 on display
                    default:  // any time
                        PORTD=0b00111111;break; // Show 0 on display
    }  
    
    if(BTN == 1){PORTD=0b00111111; // If button is not pressed Show 0 on display
    }
  }
 }


void main(void) {
nRBPU =0;            //PORTB.0 pullup direnci acik
TRISB=  0b00000001;  //PORTB.0 giris
TRISD = 0b00000000;  
PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; //portlari temizle.

while(1){  
    
    run_led();  
  
    }
}