TIMER0

Başlatan konusan, 20 Ekim 2017, 14:51:02

konusan

merhaba ustalarım 
CCS derleyicisinde  TIMER0 ve RB4-7 değişiklik kesmesini kullandım.
TIMER0 da
Alıntı Yapsetup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_bit);   
    enable_interrupts(INT_TIMER0)
    enable_interrupts(INT_RB);
    enable_interrupts(GLOBAL);

ayarları ile birlikte 4MHz lik kristal kullandım.Taşma sayısına da 61 dedim

RB4-7 değişiklik kesmesinde ise   menü yaptım .

Devreyi çalıştırdığımda TIMER0 belirlediğim sürede işlem yapmadı. TIMER0 'ın 1 saniyesi  yaklaşık 4 saniyeye denk geldi.

sebebi ne olabilir.

şimdiden teşekkürler



Teğmen

Rb kesmesi ve timer0 kesmesi aynı zamanda mı çalışıyor?
"Girdim ilim meclisine kıldım eyledim talep,   Dediler ilim geride kaldı illa Edep illa Edep" Hz.Yunus Emre K.S.

sadogan

#2
TMR0 yaklaşık 61ms yede kesmeye girer. tasma sayısına 16 demeniz gerekiyor.

Teğmen

@sadogan biraz açar mısın anlattığını?
61 ms de kesmeye girince ne oluyor?
"Girdim ilim meclisine kıldım eyledim talep,   Dediler ilim geride kaldı illa Edep illa Edep" Hz.Yunus Emre K.S.

konusan

@sadogan  hocam,
TMR0 hesabını ben şu şekilde yapmıştım 
Alıntı Yap
Fkomut=(4MHz/4) =1MHz

Kesme Oluşma Süresi= Tkomut *  Bölme Oranı  *(256-TMR0 'a yazılan deger)
                  =0,016384 saniye

1 Kesme               0,016384   saniye
? Kesme                             1 saniye    (doğru orantı)
_____________________________________________________
? Kesme =61,0351  ~   61 kesme   



61 'i bu şekilde belirlemiştim
16 nasıl olacak anlamadım hocam

RB4-7 değişiklik kesmesi aynı anda çalışmıyor  @Teğmen hocam RB4-7 değişiklik kesmesi olduğunda sadece RB7 pini için yazdığım menü işlemleri yapılıyor .Menüden çıktıktan sora TMR0 kaldığı yerden devam ediyor.Bunun için
Alıntı Yap
  #priority RB, TIMER0
komutunu kullandım hocam.

sadogan

Hesap doğru, bende yanlışlık olmuş.
Timer0 rutini paylaşırsan ona bakalım.
Kullandugın mcu nedir ve test ortamın gerçek mcu ilemi yoksa similasyonmu ?

konusan

Alıntı Yap



#int_TIMER0

void timer0_kesmesi() {
if(++sayac == 61)  // timer0 61 kez taştıysa
{                 // 61 x 16.3 ms = 1 sn süre geçmiştir
   sayac = 0;


  led1--;
  saniye =led1 %60;
  dakika =led1 /60;
  lcd_gotoxy(1,1);
  if(x ==1)
   printf(lcd_putc," 1.cihaz   %02d:%02d   ",dakika,saniye);


      if(led1==0)
      {
      led1=0;   
      output_low(pin_c0);
      lcd_gotoxy(1,1);
      printf(lcd_putc,"                 ");
      delay_ms(10);
      z=0,x=0;
      }
     
     
     
    led2--;
  saniye_2 =led2 %60;
  dakika_2 =led2 /60;
  lcd_gotoxy(2,2);
  if (y == 2)
   printf(lcd_putc,"2.cihaz   %02d:%02d   ",dakika_2,saniye_2);
   
     

   if(led2 == 0) // 60 saniye
      {     
      led2=0;
      output_low(pin_c1);
      lcd_gotoxy(1,2);
      printf(lcd_putc,"                 ");
      delay_ms(10);
       zz=0, y=0;
      }
     
     
   
}
}





16F887 kullanıyorum @sadogan hocam

Acaba RB4 kesmesindeki menüden kaynaklanıyor olabilir mi TMR0  daki kayma? RB4-7 kesmesinde baya bi delay_ms  kullanmıştım.

sadogan

#7
printf ,lcd_putc gibi fonksiyonları interrupt içinde kulandığınızda derleyici interrupt ları kapatıyor.
interrupt içinde böyle uzun uzun program parçaları kullanmak hele delay_ms gibi fonkiyonlar kulanmak doğru deyil,stack sorunlarına yol açar.
interrupt  runtine girdiginizde bir flag setleyip çıkın. Ana programda bu flag'a bakarak işlemlerinizi yapın.
RB4 -7 interrupt rutinde delay_ms printf gibi her yerde kulanılan foksiyonlar varsa, dediğim gibi bu foksiyonlar icra edilirlen ccs interrupt ları kapatıyor.


Teğmen

@sadogan konuyu bende takip ediyprum.Flag set etme olayını anlatır mısın
"Girdim ilim meclisine kıldım eyledim talep,   Dediler ilim geride kaldı illa Edep illa Edep" Hz.Yunus Emre K.S.

konusan

@sadogan hocam örnek kod verebilir misiniz? Anlayamadım tam demek istediğinizi

RB4-7 de menü yaparken menüye girmek,onaylamak   onay yapmak için belirlenen  saniye boyunca tuşa basılı olması gerekiyor. bunun için başka nasıl bir yol bulabilirim?

delay_ms kullanmak yerine for döngüsüyle mi saydırmam gerekir acaba ? 

sadogan

#10
int1 HesapYap_LcdYeYaz = 0;

#int_TIMER0
void timer0_kesmesi() {
						if(++sayac == 61)  // timer0 61 kez taştıysa
						{                 // 61 x 16.3 ms = 1 sn süre geçmiştir
							sayac = 0;
							HesapYap_LcdYeYaz = 1;	
						}			
}


void main ()
{
	while(true)
	{
		if(HesapYap_LcdYeYaz)
		{
			HesapYap_LcdYeYaz = 0;
			// Timr0 ın belerledigi süre sonunda yapılacak işler.
		}
	}
}

volkanunal

Alıntı yapılan: sadogan - 24 Ekim 2017, 14:43:39
int1 HesapYap_LcdYeYaz = 0;

#int_TIMER0
void timer0_kesmesi() {
						if(++sayac == 61)  // timer0 61 kez taştıysa
						{                 // 61 x 16.3 ms = 1 sn süre geçmiştir
							sayac = 0;
							HesapYap_LcdYeYaz = 1;	
						}			
}


void main ()
{
	while(true)
	{
		if(HesapYap_LcdYeYaz)
		{
			HesapYap_LcdYeYaz = 0;
			// Timr0 ın belerledigi süre sonunda yapılacak işler.
		}
	}
}


if(++sayac == 61) kısmını if(++sayac >=61) olarak yapmak daha iyi olmaz mı hocam?
Primum nil nocere

sadogan

#12
Alıntı yapılan: volkanunal - 24 Ekim 2017, 15:37:07
if(++sayac == 61) kısmını if(++sayac >=61) olarak yapmak daha iyi olmaz mı hocam?
Evet,tedbirli olmak iyi dir.
Ama ben  if(++sayac >60) genellikle böyle kulanıyorum.

konusan

@volkanunal  ,  @sadogan  Çok teşekkür ederim anladım hocam. delay_ms için nasıl bir yol izlemek gerekir?
Programlarda genel olarak delay_ms kullanmak yerine saydırma işlemi yaparak (basic de dec ,inc gibi işlemlerle )kullanın diyorlar.Onu nasıl yaparız hem norma main içinde hem de interrupt da

Örnek kod verebilir misiniz?

mehmet

Timer içinde belirli değişkenleri
set edin. Ana döngüde bu değişkenleri
kontrol edin. Hangisi hangi iş için ise
onu kullanıp resetleyin.
Yada bir sayaç olsun timer içinde.
Bu sayacın belli değerlerinde belli
işler yapılsın. Sayacın resetlenmesi de
ya interrupt içinde ya da uygun başka
bir yerde yapılır.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr