Haberler:

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

Ana Menü

timer1 için yardım

Başlatan ranadilara, 09 Nisan 2008, 21:29:26

ranadilara

merhaba
16f877'nin timer1'ini kullanarak herhangi bir pinin 1den 0a düştüğü andaki zamanı bulmak ve bu zamanın uzunluğuna ya da kısalığına göre led yaktırmak istiyorum programı aşağıdaki şekilde yaptım ancak ne proteusta ne de gerçekte çalıştırabildim kodda ne gibi bir hata var yardımcı olabilirseniz  çok sevinirim şimdiden teşekkürler

#include <16F877.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)


int i=0;


#int_timer1
void timer1_kesme()
{
i++;
}

void main()
{

set_tris_b(0x01);

loop:


if(pin_b0==1)
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0);
enable_interrupts(INT_timer1);
enable_interrupts(GLOBAL);
}


if(i>=10)
{
disable_interrupts(INT_timer1);
i=0;
output_high(pin_c1);



}


goto loop;
}

Ziya

Alıntı Yapif(pin_b0==1)
if(input(pin_b0))
Alıntı Yaploop: ... goto loop:
while(1){...}
for( ; ; ){...}
do{...}while(1);
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

ete

Normal yazım format hatasının dışında bana kalırsa TMR1 kesmesini de çalıştırmaman gerek. Yapılacak iş;
- TMR1=0 (yada TMR1L=0 ve TMR1H=0) demek gerek ancak timer1'i aktif etmemek gerek.
- PortB.0=1  olduğu anda Timer1'i aktif edip saymaya başlamasını sağlamak gerek. (T1CON.0=1)
- Daha sonra PORTB.0=0 olduğu anı kollayıp bu anı yakalayınca TMR1 aktivasyonunu kaldırmak ve daha sonrada değerini okuyup bir değişkene vermek gerekir. (T1CON=0 ve SAYAC.Byte0=TMR1L ve Sayac.Byte1=TMR1H)

Şayet Kesmeyi açarsanız , kesme TMR1 in 65535 değerini aşması halinde oluşacaktırki bu sizin aramadığınız bir şey dir.

Timer1, in aktivasyonu, T1CON.0 bitinin 1 yapılması ile olur. AYnı biti 0 yapıncada TMR1 saymayı durdurur.

Ayrıca TMR1 Sayacı 16 bitlik bir sayaç olmasına rağmen değerini 2 ayrı 8 bitlik parçalar halinde okuyabiliyoruz. TMR1L ve TMRH olarak bu bilgiler alınabilmektedir. Belki bu işlem CCS de farklıdır. Araştırmak gerek.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

ranadilara

Alıntı YapAlıntı:
if(pin_b0==1)

if(input(pin_b0))
Alıntı:
loop: ... goto loop:
while(1){...}
for( ; ; ){...}
do{...}while(1);

bunu yaptım ancak yine de çalıştıramadım:(



Alıntı Yap- TMR1=0 (yada TMR1L=0 ve TMR1H=0) demek gerek ancak timer1'i aktif etmemek gerek.
- PortB.0=1 olduğu anda Timer1'i aktif edip saymaya başlamasını sağlamak gerek. (T1CON.0=1)
- Daha sonra PORTB.0=0 olduğu anı kollayıp bu anı yakalayınca TMR1 aktivasyonunu kaldırmak ve daha sonrada değerini okuyup bir değişkene vermek gerekir. (T1CON=0 ve SAYAC.Byte0=TMR1L ve Sayac.Byte1=TMR1H)

Şayet Kesmeyi açarsanız , kesme TMR1 in 65535 değerini aşması halinde oluşacaktırki bu sizin aramadığınız bir şey dir.

Timer1, in aktivasyonu, T1CON.0 bitinin 1 yapılması ile olur. AYnı biti 0 yapıncada TMR1 saymayı durdurur.

aslında yapmak istediğim anlattığın şekilde,ancak burada süreyi uzun tutmam gerekiyor bir pinin değişimi 3 4 snde bir olacaksa timer1 zaten defalarca taşacak ve bu taşmaları da saymam lazım ccsde yeni olduğum için fonksiyonlarına pek hakim değilim proteusta süreler zaten problemli ancak devreyi gerçeklediğimde de bir netice alamadım acaba başka ne hatam var teşekkürler...

aliveli

sorunu biraz daha açıklayabilirmisin?
hangi zamandan, herhangi bir pinin 1den 0a düştüğü ana kadar geçen zamanı bulmak istiyorsun?
Yani  timer ne zaman saymaya başlayacak ne zaman duracak?

ayrıca herhangi bir pinin 1den 0a düştüğü anı bulmak için if(pin_b0==1) yerine
if(!input(pin_b0)) kullanmalısın

iyonosfer

Aşağıdaki kodu inceleyebilirsiniz, kolay gelsin
#include <16F877.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)

int i=0;
boolean timer_kur;

#int_timer1
void timer1_kesme()
{
  i++;
}

void main()
{

set_tris_b(0x01);
set_tris_c(0x00);
timer_kur = 0;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(GLOBAL);

while(1) {

	if(input(pin_b0))   //pin b0 yüksek olduysa
	{
		if(!timer_kur) {   // timer1 kesmesi 1 kereliğine açılıyor ve timer 0 lanıyor
		set_timer1(0);      // böyle yapılmazsa, ana döngüde pin_b0 1 olduğu sürece buraya girilir
		timer_kur = 1;		// ve timer1 hicbir zaman taşmaz ve kesme oluşmaz
		i = 0;
		enable_interrupts(INT_timer1);
		output_low(pin_c1)  // kapatalım ki ikinci led hep yanık kamasın
		}
		
	}

	if(i>=10)    // timer 10 kez yada daha fazla taşmışsa
	{
		disable_interrupts(INT_timer1);  
		i=0;
		timer_kur = 0;           // birdahakei sefer kurulum için değişkeni sıfırla
		output_high(pin_c1);
	}
  }
}


başka türlüde yazılabilir ama senin tam oalrak ne ypamak istediğin belli olmalı.
Blog Sayfam: www.teknobakis.com

ranadilara

benim yapmak istediğim tam olarak şu b0 pininin 1 olduğu süreyi bulmak istiyorum ve bu süre uzunsa bir ledi yaktırmak istiyorum, bunu da timer1 kullanarak yapmak istiyorum. Ancak mesela süre 5snden uzunsa bir ledi yaktırmak istiorum yani süre uzun olduğu için timer1 10 defa filan taşıp tekrar saymaya başlıycak, sürenin kontrolünü de timer1in taşma sayısıyla yapmak istedim, yani kesme programında her seferinde i yi 1 artırarak eğer i 10dan büyük olmuşsa timer1 5snden fazla  saymıştır demektir ve ledin yanması gerekir. tam olarak yapmak istediğim bu teşekkürler...

ranadilara

Alıntı Yap

#include <16F877.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)

int i=0;
boolean timer_kur;

#int_timer1
void timer1_kesme()
{
 i++;
}

void main()
{

set_tris_b(0x01);
timer_kur = 0;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(GLOBAL);

while(1) {

  if(!input(pin_b0))   //pin b0 0 olduysa
  {
     if(!timer_kur) {   // timer1 kesmesi 1 kereliğine açılıyor ve timer 0 lanıyor
     set_timer1(0);      // böyle yapılmazsa, ana döngüde pin_b0 1 olduğu sürece buraya girilir
     timer_kur = 1;      // ve timer1 hicbir zaman taşmaz ve kesme oluşmaz
     i = 0;
     enable_interrupts(INT_timer1);
     }
  }

  if(i>=10)    // timer 10 kez yada daha fazla taşmışsa
  {
     disable_interrupts(INT_timer1);
     i=0;
     timer_kur = 0;           // birdahakei sefer kurulum için değişkeni sıfırla
     output_high(pin_c1);
  }
 }
}

bu kodu proteusta çalıştırdım gerçekte de deneyeceğim çok teşekkürler yardım eden bütün arkadaşlara...

iyonosfer

yukaıdaki kodu biraz daha düzenledim onu bir dene istersen. pin b0 1 olduğunda saymaya başlar, 5.2 sn sonra c1 deki led yanar, tekrar pib b0 1 olduğunda led soner ve 5.2 sn sonra tekrar yanar.
kolay gelsin
Edit: Düzenlediğim kodu kullan
Blog Sayfam: www.teknobakis.com

aliveli

#include <16F877.H> 
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP 
#use delay (clock=4000000) 

int i=0; 
#int_timer1 
void timer1_kesme() 
{ i++; } 

void main() 
{ 
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); 
set_timer1(0); 
enable_interrupts(INT_timer1); 
enable_interrupts(GLOBAL); 

while(1) { 

   if(input(pin_b0))   
   { set_timer1(0);    
      i = 0; 
      output_low(pin_c1)  
     } 
       
     if(!input(pin_b0) && i>=10){   
     disable_interrupts(INT_timer1);  
     output_high(pin_c1);        } 
              } 
}

ranadilara

merhaba  
timerlarla ilgili bir projem var.Yukardaki sorunu hallettim fakat şimdi de 5 saniye içinde bo pinindeki 1den 0a düşüş sayısını hesaplamak ve belirli bir değerden büyükse bir LED yaktırmak istiyorum.Aşağıdaki kodu yazdım ancak program if(i<=10) döngüsünden çıkmıyor.Herhalde hep i=0 olarak algılıyor.Bu sorunu halletmek için ne yapabilirim?
teşekkürler

#include <16F877.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)
#int_timer1

int sayi1=0;
int i=0;

void timer1_kesme()
{
i++;
}


void main()
{

set_tris_b(0x01);

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(GLOBAL);
enable_interrupts(INT_timer1);
set_timer1(0);

while(1)

{
if(i<=10)
{

if(input(pin_b0))

{delay_ms(15);

if(!(input(pin_b0)))
{sayi1++;}
}

}

if(i>=10)
{
disable_interrupts(INT_timer1);
i=0;
set_timer1(0);}

if(sayi1>=3)
{output_high(pin_c1);}



}

}