1 pic ile 2 (veya daha fazla programı) birbirinden bağımsız çalıştırmak

Başlatan asim1, 18 Mart 2011, 17:16:44

asim1

Mesela, düzenli tarama yapan 3 pin, ledleri yürüyen şekilde taratırken, diğer portta buton kontrollu birbaşka bağımsız program çalıştırmak istersem ne yapmalıyım.? Karşılaştığım sorun anlaşılıyor herhalde, led yakabilmeme rağmen, mesela buton kontrolü için komutu her satırın arasına mı koymalıyım, bunun pratik çözümü olmalı diye tahmin ediyorum, ilgilenenlere şimdiden teşekkür ederim.
Not: çok fazla konu başlığı olduğundan hepsini inceleyemedim, yönlendirme varsa işimi halledebilir.

fahri-

pic de birbirinden bağımsız 2 program çalıştıramazsınız. ama 2-3-4 ayrı fonksiyon halinde 2-3-4 iş yaptırabilirsiniz. taramalı şekilde veya rtos kullanarak.

serdararikan

aynı anda olmaz ama multitasking ile birden fazla programı çalıştırmak mümkündür.

asim1

Arkadaşlar teşekkür ederim, ancak bahsettiğiniz rtos ve multishaking kelimelerini pic ile ilgili olarak ilk defa duydum. Anlaşılan meseleyi baya iyi biliyorsunuz, yormak istemem ama , herhalde Fahri(kıdemli) arkadaşın bahsettiği ayrı fonksiyon halinde 2-3-4 ayrı iş yaptırmak benim yapmak istediğim ilk şeylere yetebilir. Bu arada Microcode Studio kullanıyorum.
Mesela Led çıkışı olarak 3'lü tarama düzenli devam ederken aynı pic 'in diğer pin leri ile farklı yanıp sönmeler yapmak nasıl olur örnek verebilirmisiniz.

Klein

Sanırım sorun  aynı anda , aynı periyotta işterebilirmiyim şeklinde anlaşılmış.
Programınıhiçbir yerde bekletmezsen yaparsın. Böyle çalışmanın en büyük dezavantajı , bolca ram alanı kullanması. Hiçbir rutinn içinde belemediğin için , tekrar rutine girdiğinde  bayraklar , sayıcılar gibi değerlerin kaybolmaması gerekir. bu yüzden değişkenleri statik olarak veya global değişkenler olarak tanımlamalısın.
Birkaç örnek kodla açıklayayım:

Bu bir keypad kodu.  Bu koddaki read_key() rutini  ana döngüde sürekli çağırılır. Herhangi bir tuşa basılınca elimizde tuş basıldı bilgisi ve tuş bilgisi olur.  key_time_irq() rutini ise 1 milisaniyede veya iteğe göre daha uzun sürede çağırılır. Bu rutin debounce sayıcısı , tuştekrarlama vs.. işler için zamanlama yapar.  Dikkat edersen , program hiçbir yerde bekleme yapmaz.
#define  nopress 0
#define  press 1
#define key_esc 1
#define key_dn 2
#define key_ent 3
#define key_up 4
#define key_shift 5
#define KEY_DEBOUNCE_CONST 50
#define KEY_ECHO_CONST 50
#define KEY_HOLD_CONST 1000


unsigned char keypress=nopress;
unsigned char keystate;
unsigned int keydebounce=0;
unsigned char keytime=0;
unsigned char keyprescaler=50;
unsigned char keypresscounter=0;
unsigned char keysingleflag=0;
unsigned int key_hold_counter=0;
unsigned char key_hold_flag=0;

void read_key(void){
unsigned char portval;
   portval= p0&0xF0;
   if((portval != 0xF0 )&& (key_hold_counter)) key_hold_counter--;
	if(( portval != 0xF0) && keystate){
		keystate=0;	
		keysingleflag=0;
		keytime=keyprescaler;
		keypresscounter++;
		if(keypresscounter>=2){ 
			if(keyprescaler>5)keyprescaler -=5;  
			keypresscounter=0;
		}
		keydebounce=0;
		menu_return_time=0;
		switch((portval)){
			case 0xD0 : key=key_dn;keysingleflag=1;keypress=press;break;
			case 0xB0 : key=key_up;keysingleflag=1;keypress=press;break;
			case 0xE0 : key=key_esc;keypress=press;break;
			case 0x70 : key=key_ent;keypress=press;break;
         default: key=0xFF;
		}
	} 
	if( (portval == 0xF0) && (keydebounce==KEY_DEBOUNCE_CONST)){
			 keystate=1;
			 keyprescaler = KEY_ECHO_CONST;
          key_hold_counter = KEY_HOLD_CONST;
			 keypresscounter=0;
          key_hold_flag=0;
	}
   if (!key_hold_counter && !key_hold_flag) {
     key_hold_flag=1;
     keypress=press;
   }
	if(keytime == 0) keystate=1;

}

void key_time_irq(void){ // 1ms de bir çağırılır
static unsigned char i=0;
      if(keydebounce<KEY_DEBOUNCE_CONST) keydebounce++;
      if(++i>=10){	           
        if(keytime>0) keytime -=keysingleflag;
        i=0;
      }
      

}


aşağıda ise  ana menü kodu var.  Bu kodaa if(keypress) şeklinde başlayan bölüme dikkat et. Burada tuştakımının işini bitirmesini  beklemeden nasıl programın herhangi bir yerinde tuşu okuyabileceğini görürsün.


void main_menu(void){
static unsigned int menu_index=0;  
    if(page_change){
      page_change=0;
		printstr(row1,0,mainmenu_header[0]+sys_langindex);
    }
	if(page_update){
		page_update=0;
		printstr(row2,0,mainmenu_titles[menu_index]+sys_langindex);
	}

	if(keypress){
		keypress=nopress;
		page_update=1;
			switch(key){
				case key_dn : if(menu_index<mainmenu_length-1) menu_index++;break;
				case key_up : if(menu_index) menu_index--;break;
				case key_esc: page_index=homepage_index; menu_index=0;break;
				case key_ent: 
                     upmenu_index=page_index;
					      switch(menu_index){
						      case 0: page_index = sysmenu_index ; break;
						      case 1: page_index = global_setmenu_index ; break;
						      case 2: page_index = pumpmenu_index ; break;
						      case 3: page_index = servicemenu_index ; break;
					      }
					      break;
			}
	}
}


Yukarıdaki tuş takımını baz alarak bir rnek yapalım:

Örneğin enter tuğuna basınca  10 saniye beklesin ve bir roleyi  çektirsin , 2 saniye sonra da roleyitekrar bıraksın. 
Bu iş şöyle yapılabilir.
    if(key=enter) {
           delay(10sn);
           role_ac();
           delay(2sn);
           role_bırak();
    }


ama bu kod rolenin açılmasını veya kapanmasını beklerken program orada durur. bu istenmeyen bir durum.
biz bu odu şöyle düzenlersek:
unsigned char sec_update=0;

void main(void){
while(1){
          if(keypress = press){
                  if(key=enter)  işlem_kodu=1;

          }

           switch(işlem_kodu){
                  case 1:  role_işlemi();break;  
            }
}
}

void zaman_güncellemeleri(void){  
//time interrupt içerisinden veya sabit zamanlı örn: 1 milisaniyede bir çağırılır. 
// saniye garicinde başka sabit zamanlar kullanıyorsan onları da buraya ekleyebilirsin. 
static unsigned int sec_time;
        if(++sec_time==1000) sec_update=1;
}

void role_işlemi(void){ 
static unsigned char program_sayıcı=0;
static unsigned char time_temp=0;
             if(sec_update){
                 sec_update=0;
                 switch(program_sayıcı){
                      case 0:  if(++time_temp==10) program_sayıcı++;break;
                      case 1:  role_ac;  time_temp=0;program_sayıcı++; break;
                      case 2:  if(++time_temp==2) role_kapat;program_sayıcı=0; işlem kodu=0;
                      default: işlem_kodu=0; program_sayıcı=0; 
                }
            }

}

burada şunu yaptık :
Programı adım adım ilerlettik. Programda bir tuşabasılınca onun yapması gereken işlemleri peşpeşe dizip her işlemi beklemek yerine , programın her parçasının bağımsız olmasını sağladık.

asim1

Hemen gelen cevaplar beni sevindirdi ama, kodlar benim anlayacağımdan baya öte, örnekleri inceledim, ama çalışmasını sağlayamadım, simdi benim kullanabildiğim yegane programlama ortamım "microcode studio". belli belirgin kodları alt alta yazınca yak/söndür olayları gerçekleşiyor, hepsi bu. "c" falan bilmem, biraz qbasic tecrübem vardı. bu örneklerdeki parantezler falan uzatmalı yazılım beni aştı,
örneklerin daha net microcodestudio ortamında çalışır halde olanı mümkünmüdür acaba? 16f84 için.